Completed
Push — master ( 7e98cf...023f04 )
by Roy
02:08
created

stripe.js ➔ ... ➔ wc_stripe_form.validateCheckout   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 23
rs 9.0856
c 0
b 0
f 0

1 Function

Rating   Name   Duplication   Size   Complexity  
A stripe.js ➔ ... ➔ $.ajax.success 0 9 3
1
/* global wc_stripe_params */
2
3
jQuery( function( $ ) {
4
	'use strict';
5
6
	var stripe = Stripe( wc_stripe_params.key );
7
8
	if ( 'yes' === wc_stripe_params.use_elements ) {
9
		var stripe_elements_options = wc_stripe_params.elements_options.length ? wc_stripe_params.elements_options : {},
10
			elements = stripe.elements( stripe_elements_options ),
11
			stripe_card,
12
			stripe_exp,
13
			stripe_cvc;
14
	}
15
16
	/**
17
	 * Object to handle Stripe elements payment form.
18
	 */
19
	var wc_stripe_form = {
20
		/**
21
		 * Get WC AJAX endpoint URL.
22
		 *
23
		 * @param  {String} endpoint Endpoint.
24
		 * @return {String}
25
		 */
26
		getAjaxURL: function( endpoint ) {
27
			return wc_stripe_params.ajaxurl
28
				.toString()
29
				.replace( '%%endpoint%%', 'wc_stripe_' + endpoint );
30
		},
31
32
		unmountElements: function() {
33
			if ( 'yes' === wc_stripe_params.inline_cc_form ) {
34
				stripe_card.unmount( '#stripe-card-element' );
35
			} else {
36
				stripe_card.unmount( '#stripe-card-element' );
37
				stripe_exp.unmount( '#stripe-exp-element' );
38
				stripe_cvc.unmount( '#stripe-cvc-element' );
39
			}
40
		},
41
42
		mountElements: function() {
43
			if ( ! $( '#stripe-card-element' ).length ) {
44
				return;
45
			}
46
			if ( 'yes' === wc_stripe_params.inline_cc_form ) {
47
				stripe_card.mount( '#stripe-card-element' );
48
			} else {
49
				stripe_card.mount( '#stripe-card-element' );
50
				stripe_exp.mount( '#stripe-exp-element' );
51
				stripe_cvc.mount( '#stripe-cvc-element' );
52
			}
53
		},
54
55
		createElements: function() {
56
			var elementStyles = {
57
				base: {
58
					iconColor: '#666EE8',
59
					color: '#31325F',
60
					fontSize: '15px',
61
					'::placeholder': {
62
				  		color: '#CFD7E0',
63
					}
64
				}
65
			};
66
67
			var elementClasses = {
68
				focus: 'focused',
69
				empty: 'empty',
70
				invalid: 'invalid',
71
			};
72
73
			elementStyles  = wc_stripe_params.elements_styling ? wc_stripe_params.elements_styling : elementStyles;
74
			elementClasses = wc_stripe_params.elements_classes ? wc_stripe_params.elements_classes : elementClasses;
75
76
			if ( 'yes' === wc_stripe_params.inline_cc_form ) {
77
				stripe_card = elements.create( 'card', { style: elementStyles, hidePostalCode: true } );
0 ignored issues
show
Bug introduced by
The variable elements does not seem to be initialized in case "yes" === wc_stripe_params.use_elements on line 8 is false. Are you sure this can never be the case?
Loading history...
78
79
				stripe_card.addEventListener( 'change', function( event ) {
80
					wc_stripe_form.onCCFormChange();
81
82
					if ( event.error ) {
83
						$( document.body ).trigger( 'stripeError', event );
84
					}
85
				} );
86
			} else {
87
				stripe_card = elements.create( 'cardNumber', { style: elementStyles, classes: elementClasses } );
0 ignored issues
show
Bug introduced by
The variable elements does not seem to be initialized in case "yes" === wc_stripe_params.use_elements on line 8 is false. Are you sure this can never be the case?
Loading history...
88
				stripe_exp  = elements.create( 'cardExpiry', { style: elementStyles, classes: elementClasses } );
89
				stripe_cvc  = elements.create( 'cardCvc', { style: elementStyles, classes: elementClasses } );
90
91
				stripe_card.addEventListener( 'change', function( event ) {
92
					wc_stripe_form.onCCFormChange();
93
94
					if ( event.error ) {
95
						$( document.body ).trigger( 'stripeError', event );
96
					}
97
				} );
98
99
				stripe_exp.addEventListener( 'change', function( event ) {
100
					wc_stripe_form.onCCFormChange();
101
102
					if ( event.error ) {
103
						$( document.body ).trigger( 'stripeError', event );
104
					}
105
				} );
106
107
				stripe_cvc.addEventListener( 'change', function( event ) {
108
					wc_stripe_form.onCCFormChange();
109
110
					if ( event.error ) {
111
						$( document.body ).trigger( 'stripeError', event );
112
					}
113
				} );
114
			}
115
116
			/**
117
			 * Only in checkout page we need to delay the mounting of the
118
			 * card as some AJAX process needs to happen before we do.
119
			 */
120
			if ( 'yes' === wc_stripe_params.is_checkout ) {
121
				$( document.body ).on( 'updated_checkout', function() {
122
					// Don't mount elements a second time.
123
					if ( stripe_card ) {
124
						wc_stripe_form.unmountElements();
125
					}
126
127
					wc_stripe_form.mountElements();
128
				} );
129
			} else if ( $( 'form#add_payment_method' ).length || $( 'form#order_review' ).length ) {
130
				wc_stripe_form.mountElements();
131
			}
132
		},
133
134
		/**
135
		 * Initialize event handlers and UI state.
136
		 */
137
		init: function() {
138
			// Initialize tokenization script if on change payment method page and pay for order page.
139
			if ( 'yes' === wc_stripe_params.is_change_payment_page || 'yes' === wc_stripe_params.is_pay_for_order_page ) {
140
				$( document.body ).trigger( 'wc-credit-card-form-init' );
141
			}
142
143
			// Stripe Checkout.
144
			this.stripe_checkout_submit = false;
145
146
			// checkout page
147
			if ( $( 'form.woocommerce-checkout' ).length ) {
148
				this.form = $( 'form.woocommerce-checkout' );
149
			}
150
151
			$( 'form.woocommerce-checkout' )
152
				.on(
153
					'checkout_place_order_stripe checkout_place_order_stripe_bancontact checkout_place_order_stripe_sofort checkout_place_order_stripe_giropay checkout_place_order_stripe_ideal checkout_place_order_stripe_alipay checkout_place_order_stripe_sepa checkout_place_order_stripe_bitcoin',
154
					this.onSubmit
155
				);
156
157
			// pay order page
158
			if ( $( 'form#order_review' ).length ) {
159
				this.form = $( 'form#order_review' );
160
			}
161
162
			$( 'form#order_review, form#add_payment_method' )
163
				.on(
164
					'submit',
165
					this.onSubmit
166
				);
167
168
			// add payment method page
169
			if ( $( 'form#add_payment_method' ).length ) {
170
				this.form = $( 'form#add_payment_method' );
171
			}
172
173
			$( 'form.woocommerce-checkout' )
174
				.on(
175
					'change',
176
					this.reset
177
				);
178
179
			$( document )
180
				.on(
181
					'stripeError',
182
					this.onError
183
				)
184
				.on(
185
					'checkout_error',
186
					this.reset
187
				);
188
189
			if ( 'yes' === wc_stripe_params.use_elements ) {
190
				wc_stripe_form.createElements();
191
			}
192
		},
193
194
		// Check to see if Stripe in general is being used for checkout.
195
		isStripeChosen: function() {
196
			return $( '#payment_method_stripe, #payment_method_stripe_bancontact, #payment_method_stripe_sofort, #payment_method_stripe_giropay, #payment_method_stripe_ideal, #payment_method_stripe_alipay, #payment_method_stripe_sepa, #payment_method_stripe_bitcoin' ).is( ':checked' ) || ( $( '#payment_method_stripe' ).is( ':checked' ) && 'new' === $( 'input[name="wc-stripe-payment-token"]:checked' ).val() ) || ( $( '#payment_method_stripe_sepa' ).is( ':checked' ) && 'new' === $( 'input[name="wc-stripe-payment-token"]:checked' ).val() );
197
		},
198
199
		// Currently only support saved cards via credit cards and SEPA. No other payment method.
200
		isStripeSaveCardChosen: function() {
201
			return ( $( '#payment_method_stripe' ).is( ':checked' ) && ( $( 'input[name="wc-stripe-payment-token"]' ).is( ':checked' ) && 'new' !== $( 'input[name="wc-stripe-payment-token"]:checked' ).val() ) ) ||
202
				( $( '#payment_method_stripe_sepa' ).is( ':checked' ) && ( $( 'input[name="wc-stripe_sepa-payment-token"]' ).is( ':checked' ) && 'new' !== $( 'input[name="wc-stripe_sepa-payment-token"]:checked' ).val() ) );
203
		},
204
205
		// Stripe credit card used.
206
		isStripeCardChosen: function() {
207
			return $( '#payment_method_stripe' ).is( ':checked' );
208
		},
209
210
		isBancontactChosen: function() {
211
			return $( '#payment_method_stripe_bancontact' ).is( ':checked' );
212
		},
213
214
		isGiropayChosen: function() {
215
			return $( '#payment_method_stripe_giropay' ).is( ':checked' );
216
		},
217
218
		isIdealChosen: function() {
219
			return $( '#payment_method_stripe_ideal' ).is( ':checked' );
220
		},
221
222
		isSofortChosen: function() {
223
			return $( '#payment_method_stripe_sofort' ).is( ':checked' );
224
		},
225
226
		isAlipayChosen: function() {
227
			return $( '#payment_method_stripe_alipay' ).is( ':checked' );
228
		},
229
230
		isSepaChosen: function() {
231
			return $( '#payment_method_stripe_sepa' ).is( ':checked' );
232
		},
233
234
		isBitcoinChosen: function() {
235
			return $( '#payment_method_stripe_bitcoin' ).is( ':checked' );
236
		},
237
238
		isP24Chosen: function() {
239
			return $( '#payment_method_stripe_p24' ).is( ':checked' );
240
		},
241
242
		hasSource: function() {
243
			return 0 < $( 'input.stripe-source' ).length;
244
		},
245
246
		// Legacy
247
		hasToken: function() {
248
			return 0 < $( 'input.stripe_token' ).length;
249
		},
250
251
		isMobile: function() {
252
			if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) {
0 ignored issues
show
Bug introduced by
The variable navigator seems to be never declared. If this is a global, consider adding a /** global: navigator */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
253
				return true;
254
			}
255
256
			return false;
257
		},
258
259
		isStripeModalNeeded: function( e ) {
0 ignored issues
show
Unused Code introduced by
The parameter e is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
260
			var token = wc_stripe_form.form.find( 'input.stripe_token' ),
261
				$required_inputs;
0 ignored issues
show
Unused Code introduced by
The variable $required_inputs seems to be never used. Consider removing it.
Loading history...
262
263
			// If this is a stripe submission (after modal) and token exists, allow submit.
264
			if ( wc_stripe_form.stripe_submit && token ) {
265
				return false;
266
			}
267
268
			// Don't affect submission if modal is not needed.
269
			if ( ! wc_stripe_form.isStripeChosen() ) {
270
				return false;
271
			}
272
273
			return true;
274
		},
275
276
		block: function() {
277
			if ( ! wc_stripe_form.isMobile() ) {
278
				wc_stripe_form.form.block({
279
					message: null,
280
					overlayCSS: {
281
						background: '#fff',
282
						opacity: 0.6
283
					}
284
				});
285
			}
286
		},
287
288
		unblock: function() {
289
			wc_stripe_form.form.unblock();
290
		},
291
292
		getSelectedPaymentElement: function() {
293
			return $( '.payment_methods input[name="payment_method"]:checked' );
294
		},
295
296
		// Stripe Checkout.
297
		openModal: function() {
298
			// Capture submittal and open stripecheckout
299
			var $form = wc_stripe_form.form,
300
				$data = $( '#stripe-payment-data' );
301
302
			wc_stripe_form.reset();
303
304
			var token_action = function( res ) {
305
				$form.find( 'input.stripe_source' ).remove();
306
307
				/* Since source was introduced in 4.0. We need to
308
				 * convert the token into a source.
309
				 */
310
				if ( 'token' === res.object ) {
311
					stripe.createSource( {
312
						type: 'card',
313
						token: res.id,
314
					} ).then( wc_stripe_form.sourceResponse );
315
				} else if ( 'source' === res.object ) {
316
					var response = { source: res };
317
					wc_stripe_form.sourceResponse( response );
318
				}
319
			};
320
321
			StripeCheckout.open({
0 ignored issues
show
Bug introduced by
The variable StripeCheckout seems to be never declared. If this is a global, consider adding a /** global: StripeCheckout */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
322
				key               : wc_stripe_params.key,
323
				billingAddress    : 'yes' === wc_stripe_params.stripe_checkout_require_billing_address,
324
				amount            : $data.data( 'amount' ),
325
				name              : $data.data( 'name' ),
326
				description       : $data.data( 'description' ),
327
				currency          : $data.data( 'currency' ),
328
				image             : $data.data( 'image' ),
329
				bitcoin           : $data.data( 'bitcoin' ),
330
				locale            : $data.data( 'locale' ),
331
				email             : $( '#billing_email' ).val() || $data.data( 'email' ),
332
				panelLabel        : $data.data( 'panel-label' ),
333
				allowRememberMe   : $data.data( 'allow-remember-me' ),
334
				token             : token_action,
335
				closed            : wc_stripe_form.onClose()
336
			});
337
		},
338
339
		// Stripe Checkout.
340
		resetModal: function() {
341
			wc_stripe_form.reset();
342
			wc_stripe_form.stripe_checkout_submit = false;
343
		},
344
345
		// Stripe Checkout.
346
		onClose: function() {
347
			wc_stripe_form.unblock();
348
		},
349
350
		getOwnerDetails: function() {
351
			var first_name = $( '#billing_first_name' ).length ? $( '#billing_first_name' ).val() : wc_stripe_params.billing_first_name,
352
				last_name  = $( '#billing_last_name' ).length ? $( '#billing_last_name' ).val() : wc_stripe_params.billing_last_name,
353
				extra_details = { owner: { name: '', address: {}, email: '', phone: '' } };
354
355
			extra_details.owner.name = first_name;
356
357
			if ( first_name && last_name ) {
358
				extra_details.owner.name = first_name + ' ' + last_name;
359
			}
360
361
			extra_details.owner.email = $( '#billing_email' ).val();
362
			extra_details.owner.phone = $( '#billing_phone' ).val();
363
364
			/* Stripe does not like empty string values so
365
			 * we need to remove the parameter if we're not
366
			 * passing any value.
367
			 */
368
			if ( typeof extra_details.owner.phone !== 'undefined' && 0 >= extra_details.owner.phone.length ) {
369
				delete extra_details.owner.phone;
370
			}
371
372
			if ( typeof extra_details.owner.email !== 'undefined' && 0 >= extra_details.owner.email.length ) {
373
				delete extra_details.owner.email;
374
			}
375
376
			if ( typeof extra_details.owner.name !== 'undefined' && 0 >= extra_details.owner.name.length ) {
377
				delete extra_details.owner.name;
378
			}
379
380
			if ( $( '#billing_address_1' ).length > 0 ) {
381
				extra_details.owner.address.line1       = $( '#billing_address_1' ).val();
382
				extra_details.owner.address.line2       = $( '#billing_address_2' ).val();
383
				extra_details.owner.address.state       = $( '#billing_state' ).val();
384
				extra_details.owner.address.city        = $( '#billing_city' ).val();
385
				extra_details.owner.address.postal_code = $( '#billing_postcode' ).val();
386
				extra_details.owner.address.country     = $( '#billing_country' ).val();
387
			} else if ( wc_stripe_params.billing_address_1 ) {
388
				extra_details.owner.address.line1       = wc_stripe_params.billing_address_1;
389
				extra_details.owner.address.line2       = wc_stripe_params.billing_address_2;
390
				extra_details.owner.address.state       = wc_stripe_params.billing_state;
391
				extra_details.owner.address.city        = wc_stripe_params.billing_city;
392
				extra_details.owner.address.postal_code = wc_stripe_params.billing_postcode;
393
				extra_details.owner.address.country     = wc_stripe_params.billing_country;
394
			}
395
396
			return extra_details;
397
		},
398
399
		createSource: function() {
400
			var extra_details = wc_stripe_form.getOwnerDetails(),
401
				source_type   = 'card';
402
403
			if ( wc_stripe_form.isBancontactChosen() ) {
404
				source_type = 'bancontact';
405
			}
406
407
			if ( wc_stripe_form.isSepaChosen() ) {
408
				source_type = 'sepa_debit';
409
			}
410
411
			if ( wc_stripe_form.isIdealChosen() ) {
412
				source_type = 'ideal';
413
			}
414
415
			if ( wc_stripe_form.isSofortChosen() ) {
416
				source_type = 'sofort';
417
			}
418
419
			if ( wc_stripe_form.isBitcoinChosen() ) {
420
				source_type = 'bitcoin';
421
			}
422
423
			if ( wc_stripe_form.isGiropayChosen() ) {
424
				source_type = 'giropay';
425
			}
426
427
			if ( wc_stripe_form.isAlipayChosen() ) {
428
				source_type = 'alipay';
429
			}
430
431
			if ( 'card' === source_type ) {
432
				stripe.createSource( stripe_card, extra_details ).then( wc_stripe_form.sourceResponse );
433
			} else {
434
				switch ( source_type ) {
0 ignored issues
show
Coding Style introduced by
As per coding-style, switch statements should have a default case.
Loading history...
435
					case 'bancontact':
436
					case 'giropay':
437
					case 'ideal':
438
					case 'sofort':
439
					case 'alipay':
440
						// These redirect flow payment methods need this information to be set at source creation.
441
						extra_details.amount   = $( '#stripe-' + source_type + '-payment-data' ).data( 'amount' );
442
						extra_details.currency = $( '#stripe-' + source_type + '-payment-data' ).data( 'currency' );
443
						extra_details.redirect = { return_url: wc_stripe_params.return_url };
444
445
						if ( wc_stripe_params.statement_descriptor ) {
446
							extra_details.statement_descriptor = wc_stripe_params.statement_descriptor;
447
						}
448
449
						break;
450
				}
451
452
				// Handle special inputs that are unique to a payment method.
453
				switch ( source_type ) {
0 ignored issues
show
Coding Style introduced by
As per coding-style, switch statements should have a default case.
Loading history...
454
					case 'sepa_debit':
455
						var owner = $( '#stripe-payment-data' ),
456
							email = $( '#billing_email' ).length ? $( '#billing_email' ).val() : owner.data( 'email' );
457
458
						extra_details.currency    = $( '#stripe-' + source_type + '-payment-data' ).data( 'currency' );
459
						extra_details.owner.name  = $( '#stripe-sepa-owner' ).val();
460
						extra_details.owner.email = email;
461
						extra_details.sepa_debit  = { iban: $( '#stripe-sepa-iban' ).val() };
462
						extra_details.mandate     = { notification_method: wc_stripe_params.sepa_mandate_notification };
463
						break;
464
					case 'ideal':
465
						extra_details.ideal = { bank: $( '#stripe-ideal-bank' ).val() };
466
						break;
467
					case 'bitcoin':
468
					case 'alipay':
469
						extra_details.currency = $( '#stripe-' + source_type + '-payment-data' ).data( 'currency' );
470
						extra_details.amount = $( '#stripe-' + source_type + '-payment-data' ).data( 'amount' );
471
						break;
472
					case 'sofort':
473
						extra_details.sofort = { country: $( '#billing_country' ).val() };
474
						break;
475
				}
476
477
				extra_details.type = source_type;
478
479
				stripe.createSource( extra_details ).then( wc_stripe_form.sourceResponse );
480
			}
481
		},
482
483
		sourceResponse: function( response ) {
484
			if ( response.error ) {
485
				$( document.body ).trigger( 'stripeError', response );
486
			} else if ( 'no' === wc_stripe_params.allow_prepaid_card && 'card' === response.source.type && 'prepaid' === response.source.card.funding ) {
487
				response.error = { message: wc_stripe_params.no_prepaid_card_msg };
488
489
				if ( wc_stripe_params.is_stripe_checkout ) {
490
					wc_stripe_form.submitError( '<ul class="woocommerce-error"><li>' + wc_stripe_params.no_prepaid_card_msg + '</li></ul>' );
491
				} else {
492
					$( document.body ).trigger( 'stripeError', response );
493
				}
494
			} else {
495
				wc_stripe_form.processStripeResponse( response.source );
496
			}
497
		},
498
499
		processStripeResponse: function( source ) {
500
			wc_stripe_form.reset();
501
502
			// Insert the Source into the form so it gets submitted to the server.
503
			wc_stripe_form.form.append( "<input type='hidden' class='stripe-source' name='stripe_source' value='" + source.id + "'/>" );
504
505
			if ( $( 'form#add_payment_method' ).length ) {
506
				$( wc_stripe_form.form ).off( 'submit', wc_stripe_form.form.onSubmit );
507
			}
508
509
			wc_stripe_form.form.submit();
510
		},
511
512
		// Legacy
513
		createToken: function() {
514
			var card       = $( '#stripe-card-number' ).val(),
515
				cvc        = $( '#stripe-card-cvc' ).val(),
516
				expires    = $( '#stripe-card-expiry' ).payment( 'cardExpiryVal' ),
517
				first_name = $( '#billing_first_name' ).length ? $( '#billing_first_name' ).val() : wc_stripe_params.billing_first_name,
518
				last_name  = $( '#billing_last_name' ).length ? $( '#billing_last_name' ).val() : wc_stripe_params.billing_last_name,
519
				data       = {
520
					number   : card,
521
					cvc      : cvc,
522
					exp_month: parseInt( expires.month, 10 ) || 0,
523
					exp_year : parseInt( expires.year, 10 ) || 0
524
				};
525
526
			if ( first_name && last_name ) {
527
				data.name = first_name + ' ' + last_name;
528
			}
529
530
			if ( $( '#billing_address_1' ).length > 0 ) {
531
				data.address_line1   = $( '#billing_address_1' ).val();
532
				data.address_line2   = $( '#billing_address_2' ).val();
533
				data.address_state   = $( '#billing_state' ).val();
534
				data.address_city    = $( '#billing_city' ).val();
535
				data.address_zip     = $( '#billing_postcode' ).val();
536
				data.address_country = $( '#billing_country' ).val();
537
			} else if ( wc_stripe_params.billing_address_1 ) {
538
				data.address_line1   = wc_stripe_params.billing_address_1;
539
				data.address_line2   = wc_stripe_params.billing_address_2;
540
				data.address_state   = wc_stripe_params.billing_state;
541
				data.address_city    = wc_stripe_params.billing_city;
542
				data.address_zip     = wc_stripe_params.billing_postcode;
543
				data.address_country = wc_stripe_params.billing_country;
544
			}
545
			Stripe.setPublishableKey( wc_stripe_params.key );
0 ignored issues
show
Bug introduced by
The variable Stripe seems to be never declared. If this is a global, consider adding a /** global: Stripe */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
546
			Stripe.createToken( data, wc_stripe_form.onStripeTokenResponse );
547
		},
548
549
		// Legacy
550
		onStripeTokenResponse: function( status, response ) {
551
			if ( response.error ) {
552
				$( document ).trigger( 'stripeError', response );
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
553
			} else {
554
				// check if we allow prepaid cards
555
				if ( 'no' === wc_stripe_params.allow_prepaid_card && 'prepaid' === response.card.funding ) {
556
					response.error = { message: wc_stripe_params.no_prepaid_card_msg };
557
558
					$( document ).trigger( 'stripeError', { response: response } );
559
560
					return false;
561
				}
562
563
				// token contains id, last4, and card type
564
				var token = response.id;
565
566
				// insert the token into the form so it gets submitted to the server
567
				wc_stripe_form.form.append( "<input type='hidden' class='stripe_token' name='stripe_token' value='" + token + "'/>" );
568
569
				if ( $( 'form#add_payment_method' ).length ) {
570
					$( wc_stripe_form.form ).off( 'submit', wc_stripe_form.form.onSubmit );
571
				}
572
573
				wc_stripe_form.form.submit();
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
574
			}
575
		},
576
577
		onSubmit: function( e ) {
578
			if ( wc_stripe_form.isStripeChosen() && ! wc_stripe_form.isStripeSaveCardChosen() && ! wc_stripe_form.hasSource() && ! wc_stripe_form.hasToken() ) {
579
				e.preventDefault();
580
581
				// Stripe Checkout.
582
				if ( 'yes' === wc_stripe_params.is_stripe_checkout && wc_stripe_form.isStripeModalNeeded() && wc_stripe_form.isStripeCardChosen() ) {
583
					// Since in mobile actions cannot be deferred, no dynamic validation applied.
584
					if ( wc_stripe_form.isMobile() || 'no' === wc_stripe_params.validate_modal_checkout ) {
585
						wc_stripe_form.openModal();
586
					} else {
587
						wc_stripe_form.validateCheckout();
588
					}
589
590
					return false;
591
				}
592
593
				wc_stripe_form.block();
594
595
				// Process legacy card token.
596
				if ( wc_stripe_form.isStripeCardChosen() && 'no' === wc_stripe_params.use_elements ) {
597
					wc_stripe_form.createToken();
598
					return false;
599
				}
600
601
				if ( wc_stripe_form.isSepaChosen() ) {
602
					// Check if SEPA owner is filled before proceed.
603
					if ( '' === $( '#stripe-sepa-owner' ).val() ) {
604
						$( document.body ).trigger( 'stripeError', { error: { message: wc_stripe_params.no_sepa_owner_msg } } );
605
						return false;
606
					}
607
608
					// Check if SEPA IBAN is filled before proceed.
609
					if ( '' === $( '#stripe-sepa-iban' ).val() ) {
610
						$( document.body ).trigger( 'stripeError', { error: { message: wc_stripe_params.no_sepa_iban_msg } } );
611
						return false;
612
					}
613
				}
614
615
				/*
616
				 * For methods that needs redirect, we will create the
617
				 * source server side so we can obtain the order ID.
618
				 */
619
				if (
620
					wc_stripe_form.isBancontactChosen() ||
621
					wc_stripe_form.isGiropayChosen() ||
622
					wc_stripe_form.isIdealChosen() ||
623
					wc_stripe_form.isAlipayChosen() ||
624
					wc_stripe_form.isSofortChosen() ||
625
					wc_stripe_form.isP24Chosen()
626
				) {
627
					if ( $( 'form#order_review' ).length ) {
628
						$( 'form#order_review' )
629
							.off(
630
								'submit',
631
								this.onSubmit
632
							);
633
634
						wc_stripe_form.form.submit();
635
					}
636
637
					if ( $( 'form.woocommerce-checkout' ).length ) {
638
						$( 'form.woocommerce-checkout' )
639
							.off(
640
								'submit',
641
								this.onSubmit
642
							);
643
644
						return true;
645
					}
646
647
					if ( $( 'form#add_payment_method' ).length ) {
648
						$( 'form#add_payment_method' )
649
							.off(
650
								'submit',
651
								this.onSubmit
652
							);
653
654
						wc_stripe_form.form.submit();
655
					}
656
				}
657
658
				wc_stripe_form.createSource();
659
660
				// Prevent form submitting
661
				return false;
662
			} else if ( $( 'form#add_payment_method' ).length ) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if $("form#add_payment_method").length is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
663
				e.preventDefault();
664
665
				// Stripe Checkout.
666
				if ( 'yes' === wc_stripe_params.is_stripe_checkout && wc_stripe_form.isStripeModalNeeded() && wc_stripe_form.isStripeCardChosen() ) {
667
					wc_stripe_form.openModal();
668
669
					return false;
670
				}
671
672
				wc_stripe_form.block();
673
674
				// Process legacy card token.
675
				if ( wc_stripe_form.isStripeCardChosen() && 'no' === wc_stripe_params.use_elements ) {
676
					wc_stripe_form.createToken();
677
					return false;
678
				}
679
680
				wc_stripe_form.createSource();
681
				return false;
682
			}
683
		},
684
685
		onCCFormChange: function() {
686
			wc_stripe_form.reset();
687
		},
688
689
		reset: function() {
690
			$( '.wc-stripe-error, .stripe-source, .stripe_token' ).remove();
691
692
			// Stripe Checkout.
693
			if ( 'yes' === wc_stripe_params.is_stripe_checkout ) {
694
				wc_stripe_form.stripe_submit = false;
695
			}
696
		},
697
698
		getRequiredFields: function() {
699
			return wc_stripe_form.form.find( '.form-row.validate-required > input:visible, .form-row.validate-required > select:visible, .form-row.validate-required > textarea:visible' );
700
		},
701
702
		validateCheckout: function() {
703
			var data = {
704
				'nonce': wc_stripe_params.stripe_nonce,
705
				'required_fields': wc_stripe_form.getRequiredFields().serialize(),
706
				'all_fields': wc_stripe_form.form.serialize()
707
			};
708
709
			$.ajax( {
710
				type:		'POST',
711
				url:		wc_stripe_form.getAjaxURL( 'validate_checkout' ),
712
				data:		data,
713
				dataType:   'json',
714
				success:	function( result ) {
715
					if ( 'success' === result ) {
716
						wc_stripe_form.openModal();
717
					} else if ( result.messages ) {
718
						wc_stripe_form.resetModal();
719
						wc_stripe_form.reset();
720
						wc_stripe_form.submitError( result.messages );
721
					}
722
				}
723
			} );
724
		},
725
726
		onError: function( e, result ) {
727
			var message = result.error.message,
728
				errorContainer = wc_stripe_form.getSelectedPaymentElement().parents( 'li' ).eq(0).find( '.stripe-source-errors' );
729
730
			/*
731
			 * Customers do not need to know the specifics of the below type of errors
732
			 * therefore return a generic localizable error message.
733
			 */
734
			if (
735
				'invalid_request_error' === result.error.type ||
736
				'api_connection_error'  === result.error.type ||
737
				'api_error'             === result.error.type ||
738
				'authentication_error'  === result.error.type ||
739
				'rate_limit_error'      === result.error.type
740
			) {
741
				message = wc_stripe_params.invalid_request_error;
742
			}
743
744
			if ( 'card_error' === result.error.type && wc_stripe_params.hasOwnProperty( result.error.code ) ) {
745
				message = wc_stripe_params[ result.error.code ];
746
			}
747
748
			if ( 'validation_error' === result.error.type && wc_stripe_params.hasOwnProperty( result.error.code ) ) {
749
				message = wc_stripe_params[ result.error.code ];
750
			}
751
752
			wc_stripe_form.reset();
753
			$( '.woocommerce-NoticeGroup-checkout' ).remove();
754
			console.log( result.error.message ); // Leave for troubleshooting.
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
755
			$( errorContainer ).html( '<ul class="woocommerce_error woocommerce-error wc-stripe-error"><li>' + message + '</li></ul>' );
756
757
			if ( $( '.wc-stripe-error' ).length ) {
758
				$( 'html, body' ).animate({
759
					scrollTop: ( $( '.wc-stripe-error' ).offset().top - 200 )
760
				}, 200 );
761
			}
762
			wc_stripe_form.unblock();
763
		},
764
765
		submitError: function( error_message ) {
766
			$( '.woocommerce-NoticeGroup-checkout, .woocommerce-error, .woocommerce-message' ).remove();
767
			wc_stripe_form.form.prepend( '<div class="woocommerce-NoticeGroup woocommerce-NoticeGroup-checkout">' + error_message + '</div>' );
768
			wc_stripe_form.form.removeClass( 'processing' ).unblock();
769
			wc_stripe_form.form.find( '.input-text, select, input:checkbox' ).blur();
770
			
771
			var selector = '';
772
773
			if ( $( '#add_payment_method' ).length ) {
774
				selector = $( '#add_payment_method' );
775
			}
776
777
			if ( $( '#order_review' ).length ) {
778
				selector = $( '#order_review' );
779
			}
780
781
			if ( $( 'form.checkout' ).length ) {
782
				selector = $( 'form.checkout' );
783
			}
784
785
			if ( selector.length ) {
786
				$( 'html, body' ).animate({
787
					scrollTop: ( selector.offset().top - 100 )
788
				}, 500 );
789
			}
790
791
			$( document.body ).trigger( 'checkout_error' );
792
			wc_stripe_form.unblock();
793
		}
794
	};
795
796
	wc_stripe_form.init();
797
} );
798