Completed
Pull Request — master (#605)
by Roy
05:45
created

stripe.js ➔ ... ➔ $.each   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
/* global wc_stripe_params */
2
3
jQuery( function( $ ) {
4
	'use strict';
5
6
	var stripe = Stripe( wc_stripe_params.key );
7
8
	var stripe_elements_options = wc_stripe_params.elements_options.length ? wc_stripe_params.elements_options : {},
9
		elements = stripe.elements( stripe_elements_options ),
10
		stripe_card,
11
		stripe_exp,
12
		stripe_cvc;
13
14
15
	/**
16
	 * Object to handle Stripe elements payment form.
17
	 */
18
	var wc_stripe_form = {
19
		/**
20
		 * Get WC AJAX endpoint URL.
21
		 *
22
		 * @param  {String} endpoint Endpoint.
23
		 * @return {String}
24
		 */
25
		getAjaxURL: function( endpoint ) {
26
			return wc_stripe_params.ajaxurl
27
				.toString()
28
				.replace( '%%endpoint%%', 'wc_stripe_' + endpoint );
29
		},
30
31
		unmountElements: function() {
32
			if ( 'yes' === wc_stripe_params.inline_cc_form ) {
33
				stripe_card.unmount( '#stripe-card-element' );
34
			} else {
35
				stripe_card.unmount( '#stripe-card-element' );
36
				stripe_exp.unmount( '#stripe-exp-element' );
37
				stripe_cvc.unmount( '#stripe-cvc-element' );
38
			}
39
		},
40
41
		mountElements: function() {
42
			if ( ! $( '#stripe-card-element' ).length ) {
43
				return;
44
			}
45
			if ( 'yes' === wc_stripe_params.inline_cc_form ) {
46
				stripe_card.mount( '#stripe-card-element' );
47
			} else {
48
				stripe_card.mount( '#stripe-card-element' );
49
				stripe_exp.mount( '#stripe-exp-element' );
50
				stripe_cvc.mount( '#stripe-cvc-element' );
51
			}
52
		},
53
54
		createElements: function() {
55
			var elementStyles = {
56
				base: {
57
					iconColor: '#666EE8',
58
					color: '#31325F',
59
					fontSize: '15px',
60
					'::placeholder': {
61
				  		color: '#CFD7E0',
62
					}
63
				}
64
			};
65
66
			var elementClasses = {
67
				focus: 'focused',
68
				empty: 'empty',
69
				invalid: 'invalid',
70
			};
71
72
			elementStyles  = wc_stripe_params.elements_styling ? wc_stripe_params.elements_styling : elementStyles;
73
			elementClasses = wc_stripe_params.elements_classes ? wc_stripe_params.elements_classes : elementClasses;
74
75
			if ( 'yes' === wc_stripe_params.inline_cc_form ) {
76
				stripe_card = elements.create( 'card', { style: elementStyles, hidePostalCode: true } );
77
78
				stripe_card.addEventListener( 'change', function( event ) {
79
					wc_stripe_form.onCCFormChange();
80
81
					if ( event.error ) {
82
						$( document.body ).trigger( 'stripeError', event );
83
					}
84
				} );
85
			} else {
86
				stripe_card = elements.create( 'cardNumber', { style: elementStyles, classes: elementClasses } );
87
				stripe_exp  = elements.create( 'cardExpiry', { style: elementStyles, classes: elementClasses } );
88
				stripe_cvc  = elements.create( 'cardCvc', { style: elementStyles, classes: elementClasses } );
89
90
				stripe_card.addEventListener( 'change', function( event ) {
91
					wc_stripe_form.onCCFormChange();
92
93
					wc_stripe_form.updateCardBrand( event.brand );
94
95
					if ( event.error ) {
96
						$( document.body ).trigger( 'stripeError', event );
97
					}
98
				} );
99
100
				stripe_exp.addEventListener( 'change', function( event ) {
101
					wc_stripe_form.onCCFormChange();
102
103
					if ( event.error ) {
104
						$( document.body ).trigger( 'stripeError', event );
105
					}
106
				} );
107
108
				stripe_cvc.addEventListener( 'change', function( event ) {
109
					wc_stripe_form.onCCFormChange();
110
111
					if ( event.error ) {
112
						$( document.body ).trigger( 'stripeError', event );
113
					}
114
				} );
115
			}
116
117
			/**
118
			 * Only in checkout page we need to delay the mounting of the
119
			 * card as some AJAX process needs to happen before we do.
120
			 */
121
			if ( 'yes' === wc_stripe_params.is_checkout ) {
122
				$( document.body ).on( 'updated_checkout', function() {
123
					// Don't mount elements a second time.
124
					if ( stripe_card ) {
125
						wc_stripe_form.unmountElements();
126
					}
127
128
					wc_stripe_form.mountElements();
129
				} );
130
			} else if ( $( 'form#add_payment_method' ).length || $( 'form#order_review' ).length ) {
131
				wc_stripe_form.mountElements();
132
			}
133
		},
134
135
		updateCardBrand: function( brand ) {
136
			var brandClass = {
137
				'visa': 'stripe-visa-brand',
138
				'mastercard': 'stripe-mastercard-brand',
139
				'amex': 'stripe-amex-brand',
140
				'discover': 'stripe-discover-brand',
141
				'diners': 'stripe-diners-brand',
142
				'jcb': 'stripe-jcb-brand',
143
				'unknown': 'stripe-credit-card-brand'
144
			};
145
146
			var imageElement = $( '.stripe-card-brand' ),
147
				imageClass = 'stripe-credit-card-brand';
148
149
			if ( brand in brandClass ) {
150
				imageClass = brandClass[ brand ];
151
			}
152
153
			// Remove existing card brand class.
154
			$.each( brandClass, function( index, el ) {
155
				imageElement.removeClass( el );
156
			} );
157
158
			imageElement.addClass( imageClass );
159
		},
160
161
		/**
162
		 * Initialize event handlers and UI state.
163
		 */
164
		init: function() {
165
			// Initialize tokenization script if on change payment method page and pay for order page.
166
			if ( 'yes' === wc_stripe_params.is_change_payment_page || 'yes' === wc_stripe_params.is_pay_for_order_page ) {
167
				$( document.body ).trigger( 'wc-credit-card-form-init' );
168
			}
169
170
			// Stripe Checkout.
171
			this.stripe_checkout_submit = false;
172
173
			// checkout page
174
			if ( $( 'form.woocommerce-checkout' ).length ) {
175
				this.form = $( 'form.woocommerce-checkout' );
176
			}
177
178
			$( 'form.woocommerce-checkout' )
179
				.on(
180
					'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',
181
					this.onSubmit
182
				);
183
184
			// pay order page
185
			if ( $( 'form#order_review' ).length ) {
186
				this.form = $( 'form#order_review' );
187
			}
188
189
			$( 'form#order_review, form#add_payment_method' )
190
				.on(
191
					'submit',
192
					this.onSubmit
193
				);
194
195
			// add payment method page
196
			if ( $( 'form#add_payment_method' ).length ) {
197
				this.form = $( 'form#add_payment_method' );
198
			}
199
200
			$( 'form.woocommerce-checkout' )
201
				.on(
202
					'change',
203
					this.reset
204
				);
205
206
			$( document )
207
				.on(
208
					'stripeError',
209
					this.onError
210
				)
211
				.on(
212
					'checkout_error',
213
					this.reset
214
				);
215
216
			wc_stripe_form.createElements();
217
218
			if ( 'yes' === wc_stripe_params.is_stripe_checkout ) {
219
				$( document.body ).on( 'click', '.wc-stripe-checkout-button', function() {
220
					wc_stripe_form.openModal();
221
					return false;
222
				} );
223
			}
224
		},
225
226
		// Check to see if Stripe in general is being used for checkout.
227
		isStripeChosen: function() {
228
			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, #payment_method_stripe_eps, #payment_method_stripe_multibanco' ).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() );
229
		},
230
231
		// Currently only support saved cards via credit cards and SEPA. No other payment method.
232
		isStripeSaveCardChosen: function() {
233
			return ( $( '#payment_method_stripe' ).is( ':checked' ) && ( $( 'input[name="wc-stripe-payment-token"]' ).is( ':checked' ) && 'new' !== $( 'input[name="wc-stripe-payment-token"]:checked' ).val() ) ) ||
234
				( $( '#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() ) );
235
		},
236
237
		// Stripe credit card used.
238
		isStripeCardChosen: function() {
239
			return $( '#payment_method_stripe' ).is( ':checked' );
240
		},
241
242
		isBancontactChosen: function() {
243
			return $( '#payment_method_stripe_bancontact' ).is( ':checked' );
244
		},
245
246
		isGiropayChosen: function() {
247
			return $( '#payment_method_stripe_giropay' ).is( ':checked' );
248
		},
249
250
		isIdealChosen: function() {
251
			return $( '#payment_method_stripe_ideal' ).is( ':checked' );
252
		},
253
254
		isSofortChosen: function() {
255
			return $( '#payment_method_stripe_sofort' ).is( ':checked' );
256
		},
257
258
		isAlipayChosen: function() {
259
			return $( '#payment_method_stripe_alipay' ).is( ':checked' );
260
		},
261
262
		isSepaChosen: function() {
263
			return $( '#payment_method_stripe_sepa' ).is( ':checked' );
264
		},
265
266
		isBitcoinChosen: function() {
267
			return $( '#payment_method_stripe_bitcoin' ).is( ':checked' );
268
		},
269
270
		isP24Chosen: function() {
271
			return $( '#payment_method_stripe_p24' ).is( ':checked' );
272
		},
273
274
		isEpsChosen: function() {
275
			return $( '#payment_method_stripe_eps' ).is( ':checked' );
276
		},
277
278
		isMultibancoChosen: function() {
279
			return $( '#payment_method_stripe_multibanco' ).is( ':checked' );
280
		},
281
282
		hasSource: function() {
283
			return 0 < $( 'input.stripe-source' ).length;
284
		},
285
286
		// Legacy
287
		hasToken: function() {
288
			return 0 < $( 'input.stripe_token' ).length;
289
		},
290
291
		isMobile: function() {
292
			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...
293
				return true;
294
			}
295
296
			return false;
297
		},
298
299
		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...
300
			var token = wc_stripe_form.form.find( 'input.stripe_token' ),
301
				$required_inputs;
0 ignored issues
show
Unused Code introduced by
The variable $required_inputs seems to be never used. Consider removing it.
Loading history...
302
303
			// If this is a stripe submission (after modal) and token exists, allow submit.
304
			if ( wc_stripe_form.stripe_submit && token ) {
305
				return false;
306
			}
307
308
			// Don't affect submission if modal is not needed.
309
			if ( ! wc_stripe_form.isStripeChosen() ) {
310
				return false;
311
			}
312
313
			return true;
314
		},
315
316
		block: function() {
317
			if ( ! wc_stripe_form.isMobile() ) {
318
				wc_stripe_form.form.block( {
319
					message: null,
320
					overlayCSS: {
321
						background: '#fff',
322
						opacity: 0.6
323
					}
324
				} );
325
			}
326
		},
327
328
		unblock: function() {
329
			wc_stripe_form.form.unblock();
330
		},
331
332
		getSelectedPaymentElement: function() {
333
			return $( '.payment_methods input[name="payment_method"]:checked' );
334
		},
335
336
		// Stripe Checkout.
337
		openModal: function() {
338
			// Capture submittal and open stripecheckout
339
			var $form = wc_stripe_form.form,
340
				$data = $( '#stripe-payment-data' );
341
342
			wc_stripe_form.reset();
343
344
			var token_action = function( res ) {
345
				$form.find( 'input.stripe_source' ).remove();
346
347
				/* Since source was introduced in 4.0. We need to
348
				 * convert the token into a source.
349
				 */
350
				if ( 'token' === res.object ) {
351
					stripe.createSource( {
352
						type: 'card',
353
						token: res.id,
354
					} ).then( wc_stripe_form.sourceResponse );
355
				} else if ( 'source' === res.object ) {
356
					var response = { source: res };
357
					wc_stripe_form.sourceResponse( response );
358
				}
359
			};
360
361
			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...
362
				key               : wc_stripe_params.key,
363
				billingAddress    : $data.data( 'billing-address' ),
364
				zipCode           : $data.data( 'verify-zip' ),
365
				amount            : $data.data( 'amount' ),
366
				name              : $data.data( 'name' ),
367
				description       : $data.data( 'description' ),
368
				currency          : $data.data( 'currency' ),
369
				image             : $data.data( 'image' ),
370
				bitcoin           : $data.data( 'bitcoin' ),
371
				locale            : $data.data( 'locale' ),
372
				email             : $( '#billing_email' ).val() || $data.data( 'email' ),
373
				panelLabel        : $data.data( 'panel-label' ),
374
				allowRememberMe   : $data.data( 'allow-remember-me' ),
375
				token             : token_action,
376
				closed            : wc_stripe_form.onClose()
377
			} );
378
		},
379
380
		// Stripe Checkout.
381
		resetModal: function() {
382
			wc_stripe_form.reset();
383
			wc_stripe_form.stripe_checkout_submit = false;
384
		},
385
386
		// Stripe Checkout.
387
		onClose: function() {
388
			wc_stripe_form.unblock();
389
		},
390
391
		getOwnerDetails: function() {
392
			var first_name = $( '#billing_first_name' ).length ? $( '#billing_first_name' ).val() : wc_stripe_params.billing_first_name,
393
				last_name  = $( '#billing_last_name' ).length ? $( '#billing_last_name' ).val() : wc_stripe_params.billing_last_name,
394
				extra_details = { owner: { name: '', address: {}, email: '', phone: '' } };
395
396
			extra_details.owner.name = first_name;
397
398
			if ( first_name && last_name ) {
399
				extra_details.owner.name = first_name + ' ' + last_name;
400
			}
401
402
			extra_details.owner.email = $( '#billing_email' ).val();
403
			extra_details.owner.phone = $( '#billing_phone' ).val();
404
405
			/* Stripe does not like empty string values so
406
			 * we need to remove the parameter if we're not
407
			 * passing any value.
408
			 */
409
			if ( typeof extra_details.owner.phone !== 'undefined' && 0 >= extra_details.owner.phone.length ) {
410
				delete extra_details.owner.phone;
411
			}
412
413
			if ( typeof extra_details.owner.email !== 'undefined' && 0 >= extra_details.owner.email.length ) {
414
				delete extra_details.owner.email;
415
			}
416
417
			if ( typeof extra_details.owner.name !== 'undefined' && 0 >= extra_details.owner.name.length ) {
418
				delete extra_details.owner.name;
419
			}
420
421
			if ( $( '#billing_address_1' ).length > 0 ) {
422
				extra_details.owner.address.line1       = $( '#billing_address_1' ).val();
423
				extra_details.owner.address.line2       = $( '#billing_address_2' ).val();
424
				extra_details.owner.address.state       = $( '#billing_state' ).val();
425
				extra_details.owner.address.city        = $( '#billing_city' ).val();
426
				extra_details.owner.address.postal_code = $( '#billing_postcode' ).val();
427
				extra_details.owner.address.country     = $( '#billing_country' ).val();
428
			} else if ( wc_stripe_params.billing_address_1 ) {
429
				extra_details.owner.address.line1       = wc_stripe_params.billing_address_1;
430
				extra_details.owner.address.line2       = wc_stripe_params.billing_address_2;
431
				extra_details.owner.address.state       = wc_stripe_params.billing_state;
432
				extra_details.owner.address.city        = wc_stripe_params.billing_city;
433
				extra_details.owner.address.postal_code = wc_stripe_params.billing_postcode;
434
				extra_details.owner.address.country     = wc_stripe_params.billing_country;
435
			}
436
437
			return extra_details;
438
		},
439
440
		createSource: function() {
441
			var extra_details = wc_stripe_form.getOwnerDetails(),
442
				source_type   = 'card';
443
444
			if ( wc_stripe_form.isBancontactChosen() ) {
445
				source_type = 'bancontact';
446
			}
447
448
			if ( wc_stripe_form.isSepaChosen() ) {
449
				source_type = 'sepa_debit';
450
			}
451
452
			if ( wc_stripe_form.isIdealChosen() ) {
453
				source_type = 'ideal';
454
			}
455
456
			if ( wc_stripe_form.isSofortChosen() ) {
457
				source_type = 'sofort';
458
			}
459
460
			if ( wc_stripe_form.isBitcoinChosen() ) {
461
				source_type = 'bitcoin';
462
			}
463
464
			if ( wc_stripe_form.isGiropayChosen() ) {
465
				source_type = 'giropay';
466
			}
467
468
			if ( wc_stripe_form.isAlipayChosen() ) {
469
				source_type = 'alipay';
470
			}
471
472
			if ( 'card' === source_type ) {
473
				stripe.createSource( stripe_card, extra_details ).then( wc_stripe_form.sourceResponse );
474
			} else {
475
				switch ( source_type ) {
0 ignored issues
show
Coding Style introduced by
As per coding-style, switch statements should have a default case.
Loading history...
476
					case 'bancontact':
477
					case 'giropay':
478
					case 'ideal':
479
					case 'sofort':
480
					case 'alipay':
481
						// These redirect flow payment methods need this information to be set at source creation.
482
						extra_details.amount   = $( '#stripe-' + source_type + '-payment-data' ).data( 'amount' );
483
						extra_details.currency = $( '#stripe-' + source_type + '-payment-data' ).data( 'currency' );
484
						extra_details.redirect = { return_url: wc_stripe_params.return_url };
485
486
						if ( wc_stripe_params.statement_descriptor ) {
487
							extra_details.statement_descriptor = wc_stripe_params.statement_descriptor;
488
						}
489
490
						break;
491
				}
492
493
				// Handle special inputs that are unique to a payment method.
494
				switch ( source_type ) {
0 ignored issues
show
Coding Style introduced by
As per coding-style, switch statements should have a default case.
Loading history...
495
					case 'sepa_debit':
496
						var owner = $( '#stripe-payment-data' ),
497
							email = $( '#billing_email' ).length ? $( '#billing_email' ).val() : owner.data( 'email' );
498
499
						extra_details.currency    = $( '#stripe-' + source_type + '-payment-data' ).data( 'currency' );
500
						extra_details.owner.name  = $( '#stripe-sepa-owner' ).val();
501
						extra_details.owner.email = email;
502
						extra_details.sepa_debit  = { iban: $( '#stripe-sepa-iban' ).val() };
503
						extra_details.mandate     = { notification_method: wc_stripe_params.sepa_mandate_notification };
504
						break;
505
					case 'ideal':
506
						extra_details.ideal = { bank: $( '#stripe-ideal-bank' ).val() };
507
						break;
508
					case 'bitcoin':
509
					case 'alipay':
510
						extra_details.currency = $( '#stripe-' + source_type + '-payment-data' ).data( 'currency' );
511
						extra_details.amount = $( '#stripe-' + source_type + '-payment-data' ).data( 'amount' );
512
						break;
513
					case 'sofort':
514
						extra_details.sofort = { country: $( '#billing_country' ).val() };
515
						break;
516
				}
517
518
				extra_details.type = source_type;
519
520
				stripe.createSource( extra_details ).then( wc_stripe_form.sourceResponse );
521
			}
522
		},
523
524
		sourceResponse: function( response ) {
525
			if ( response.error ) {
526
				$( document.body ).trigger( 'stripeError', response );
527
			} else if ( 'no' === wc_stripe_params.allow_prepaid_card && 'card' === response.source.type && 'prepaid' === response.source.card.funding ) {
528
				response.error = { message: wc_stripe_params.no_prepaid_card_msg };
529
530
				if ( 'yes' === wc_stripe_params.is_stripe_checkout ) {
531
					wc_stripe_form.submitError( '<ul class="woocommerce-error"><li>' + wc_stripe_params.no_prepaid_card_msg + '</li></ul>' );
532
				} else {
533
					$( document.body ).trigger( 'stripeError', response );
534
				}
535
			} else {
536
				wc_stripe_form.processStripeResponse( response.source );
537
			}
538
		},
539
540
		processStripeResponse: function( source ) {
541
			wc_stripe_form.reset();
542
543
			// Insert the Source into the form so it gets submitted to the server.
544
			wc_stripe_form.form.append( "<input type='hidden' class='stripe-source' name='stripe_source' value='" + source.id + "'/>" );
545
546
			if ( $( 'form#add_payment_method' ).length ) {
547
				$( wc_stripe_form.form ).off( 'submit', wc_stripe_form.form.onSubmit );
548
			}
549
550
			wc_stripe_form.form.submit();
551
		},
552
553
		onSubmit: function( e ) {
554
			if ( ! wc_stripe_form.isStripeChosen() ) {
555
				return;
556
			}
557
558
			if ( ! wc_stripe_form.isStripeSaveCardChosen() && ! wc_stripe_form.hasSource() && ! wc_stripe_form.hasToken() ) {
559
				e.preventDefault();
560
561
				wc_stripe_form.block();
562
563
				// Stripe Checkout.
564
				if ( 'yes' === wc_stripe_params.is_stripe_checkout && wc_stripe_form.isStripeModalNeeded() && wc_stripe_form.isStripeCardChosen() ) {
565
					if ( 'yes' === wc_stripe_params.is_checkout ) {
566
						return true;
567
					} else {
568
						wc_stripe_form.openModal();
569
						return false;
570
					}
571
				}
572
573
				if ( wc_stripe_form.isSepaChosen() ) {
574
					// Check if SEPA owner is filled before proceed.
575
					if ( '' === $( '#stripe-sepa-owner' ).val() ) {
576
						$( document.body ).trigger( 'stripeError', { error: { message: wc_stripe_params.no_sepa_owner_msg } } );
577
						return false;
578
					}
579
580
					// Check if SEPA IBAN is filled before proceed.
581
					if ( '' === $( '#stripe-sepa-iban' ).val() ) {
582
						$( document.body ).trigger( 'stripeError', { error: { message: wc_stripe_params.no_sepa_iban_msg } } );
583
						return false;
584
					}
585
				}
586
587
				/*
588
				 * For methods that needs redirect, we will create the
589
				 * source server side so we can obtain the order ID.
590
				 */
591
				if (
592
					wc_stripe_form.isBancontactChosen() ||
593
					wc_stripe_form.isGiropayChosen() ||
594
					wc_stripe_form.isIdealChosen() ||
595
					wc_stripe_form.isAlipayChosen() ||
596
					wc_stripe_form.isSofortChosen() ||
597
					wc_stripe_form.isP24Chosen() ||
598
					wc_stripe_form.isEpsChosen() ||
599
					wc_stripe_form.isMultibancoChosen()
600
				) {
601
					if ( $( 'form#order_review' ).length ) {
602
						$( 'form#order_review' )
603
							.off(
604
								'submit',
605
								this.onSubmit
606
							);
607
608
						wc_stripe_form.form.submit();
609
610
						return false;
611
					}
612
613
					if ( $( 'form.woocommerce-checkout' ).length ) {
614
						return true;
615
					}
616
617
					if ( $( 'form#add_payment_method' ).length ) {
618
						$( 'form#add_payment_method' )
619
							.off(
620
								'submit',
621
								this.onSubmit
622
							);
623
624
						wc_stripe_form.form.submit();
625
626
						return false;
627
					}
628
				}
629
630
				wc_stripe_form.createSource();
631
632
				// Prevent form submitting
633
				return false;
634
			} 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...
635
				e.preventDefault();
636
637
				// Stripe Checkout.
638
				if ( 'yes' === wc_stripe_params.is_stripe_checkout && wc_stripe_form.isStripeModalNeeded() && wc_stripe_form.isStripeCardChosen() ) {
639
					wc_stripe_form.openModal();
640
641
					return false;
642
				}
643
644
				wc_stripe_form.block();
645
646
				wc_stripe_form.createSource();
647
				return false;
648
			}
649
		},
650
651
		onCCFormChange: function() {
652
			wc_stripe_form.reset();
653
		},
654
655
		reset: function() {
656
			$( '.wc-stripe-error, .stripe-source, .stripe_token' ).remove();
657
658
			// Stripe Checkout.
659
			if ( 'yes' === wc_stripe_params.is_stripe_checkout ) {
660
				wc_stripe_form.stripe_submit = false;
661
			}
662
		},
663
664
		onError: function( e, result ) {
665
			var message = result.error.message,
666
				errorContainer = wc_stripe_form.getSelectedPaymentElement().parents( 'li' ).eq(0).find( '.stripe-source-errors' );
667
668
			/*
669
			 * Customers do not need to know the specifics of the below type of errors
670
			 * therefore return a generic localizable error message.
671
			 */
672
			if (
673
				'invalid_request_error' === result.error.type ||
674
				'api_connection_error'  === result.error.type ||
675
				'api_error'             === result.error.type ||
676
				'authentication_error'  === result.error.type ||
677
				'rate_limit_error'      === result.error.type
678
			) {
679
				message = wc_stripe_params.invalid_request_error;
680
			}
681
682
			if ( 'card_error' === result.error.type && wc_stripe_params.hasOwnProperty( result.error.code ) ) {
683
				message = wc_stripe_params[ result.error.code ];
684
			}
685
686
			if ( 'validation_error' === result.error.type && wc_stripe_params.hasOwnProperty( result.error.code ) ) {
687
				message = wc_stripe_params[ result.error.code ];
688
			}
689
690
			wc_stripe_form.reset();
691
			$( '.woocommerce-NoticeGroup-checkout' ).remove();
692
			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...
693
			$( errorContainer ).html( '<ul class="woocommerce_error woocommerce-error wc-stripe-error"><li>' + message + '</li></ul>' );
694
695
			if ( $( '.wc-stripe-error' ).length ) {
696
				$( 'html, body' ).animate({
697
					scrollTop: ( $( '.wc-stripe-error' ).offset().top - 200 )
698
				}, 200 );
699
			}
700
			wc_stripe_form.unblock();
701
		},
702
703
		submitError: function( error_message ) {
704
			$( '.woocommerce-NoticeGroup-checkout, .woocommerce-error, .woocommerce-message' ).remove();
705
			wc_stripe_form.form.prepend( '<div class="woocommerce-NoticeGroup woocommerce-NoticeGroup-checkout">' + error_message + '</div>' );
706
			wc_stripe_form.form.removeClass( 'processing' ).unblock();
707
			wc_stripe_form.form.find( '.input-text, select, input:checkbox' ).blur();
708
			
709
			var selector = '';
710
711
			if ( $( '#add_payment_method' ).length ) {
712
				selector = $( '#add_payment_method' );
713
			}
714
715
			if ( $( '#order_review' ).length ) {
716
				selector = $( '#order_review' );
717
			}
718
719
			if ( $( 'form.checkout' ).length ) {
720
				selector = $( 'form.checkout' );
721
			}
722
723
			if ( selector.length ) {
724
				$( 'html, body' ).animate({
725
					scrollTop: ( selector.offset().top - 100 )
726
				}, 500 );
727
			}
728
729
			$( document.body ).trigger( 'checkout_error' );
730
			wc_stripe_form.unblock();
731
		}
732
	};
733
734
	wc_stripe_form.init();
735
} );
736