Completed
Push — master ( 493a95...724a6b )
by Roy
02:11
created

assets/js/stripe.js   F

Complexity

Total Complexity 168
Complexity/F 3.82

Size

Lines of Code 823
Function Count 44

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 0
wmc 168
c 1
b 0
f 0
nc 1342177280
mnd 4
bc 135
fnc 44
dl 0
loc 823
rs 2.1818
bpm 3.0681
cpm 3.8181
noi 19

How to fix   Complexity   

Complexity

Complex classes like assets/js/stripe.js often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

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 elements = stripe.elements(),
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
		/**
32
		 * Initialize event handlers and UI state.
33
		 */
34
		init: function() {
35
			// Initialize tokenization script if on change payment method page and pay for order page.
36
			if ( 'yes' === wc_stripe_params.is_change_payment_page ) {
37
				$( document.body ).trigger( 'wc-credit-card-form-init' );
38
			}
39
40
			// Stripe Checkout.
41
			this.stripe_checkout_submit = false;
42
43
			// checkout page
44
			if ( $( 'form.woocommerce-checkout' ).length ) {
45
				this.form = $( 'form.woocommerce-checkout' );
46
			}
47
48
			$( 'form.woocommerce-checkout' )
49
				.on(
50
					'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',
51
					this.onSubmit
52
				);
53
54
			// pay order page
55
			if ( $( 'form#order_review' ).length ) {
56
				this.form = $( 'form#order_review' );
57
			}
58
59
			$( 'form#order_review' )
60
				.on(
61
					'submit',
62
					this.onSubmit
63
				);
64
65
			// add payment method page
66
			if ( $( 'form#add_payment_method' ).length ) {
67
				this.form = $( 'form#add_payment_method' );
68
			}
69
70
			$( 'form#add_payment_method' )
71
				.on(
72
					'submit',
73
					this.onSubmit
74
				);
75
76
			$( 'form.woocommerce-checkout' )
77
				.on(
78
					'change',
79
					'#stripe-bank-country',
80
					this.reset
81
				);
82
83
			$( document )
84
				.on(
85
					'stripeError',
86
					this.onError
87
				)
88
				.on(
89
					'checkout_error',
90
					this.reset
91
				);
92
93
			var elementStyles = {
94
				base: {
95
					iconColor: '#666EE8',
96
					color: '#31325F',
97
					fontSize: '15px',
98
					'::placeholder': {
99
				  		color: '#CFD7E0',
100
					}
101
				}
102
			};
103
104
			var elementClasses = {
105
				focus: 'focused',
106
				empty: 'empty',
107
				invalid: 'invalid',
108
			};
109
110
			if ( 'yes' === wc_stripe_params.use_elements && $( '#stripe-card-element' ).length ) {
111
				elementStyles  = wc_stripe_params.elements_styling ? wc_stripe_params.elements_styling : elementStyles;
112
				elementClasses = wc_stripe_params.elements_classes ? wc_stripe_params.elements_classes : elementClasses;
113
114
				if ( 'yes' === wc_stripe_params.inline_cc_form ) {
115
					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...
116
117
					stripe_card.addEventListener( 'change', function( event ) {
118
						wc_stripe_form.onCCFormChange();
119
120
						if ( event.error ) {
121
							$( document.body ).trigger( 'stripeError', event );
122
						}
123
					} );
124
				} else {
125
					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...
126
					stripe_exp  = elements.create( 'cardExpiry', { style: elementStyles, classes: elementClasses } );
127
					stripe_cvc  = elements.create( 'cardCvc', { style: elementStyles, classes: elementClasses } );
128
129
					stripe_card.addEventListener( 'change', function( event ) {
130
						wc_stripe_form.onCCFormChange();
131
132
						if ( event.error ) {
133
							$( document.body ).trigger( 'stripeError', event );
134
						}
135
					} );
136
137
					stripe_exp.addEventListener( 'change', function( event ) {
138
						wc_stripe_form.onCCFormChange();
139
140
						if ( event.error ) {
141
							$( document.body ).trigger( 'stripeError', event );
142
						}
143
					} );
144
145
					stripe_cvc.addEventListener( 'change', function( event ) {
146
						wc_stripe_form.onCCFormChange();
147
148
						if ( event.error ) {
149
							$( document.body ).trigger( 'stripeError', event );
150
						}
151
					} );
152
				}
153
154
				/**
155
				 * Only in checkout page we need to delay the mounting of the
156
				 * card as some AJAX process needs to happen before we do.
157
				 */
158
				if ( wc_stripe_params.is_checkout ) {
159
					$( document.body ).on( 'updated_checkout', function() {
160
						// Don't mount elements a second time.
161
						if ( stripe_card ) {
162
							if ( 'yes' === wc_stripe_params.inline_cc_form ) {
163
								stripe_card.unmount( '#stripe-card-element' );
164
							} else {
165
								stripe_card.unmount( '#stripe-card-element' );
166
								stripe_exp.unmount( '#stripe-exp-element' );
0 ignored issues
show
Bug introduced by
The variable stripe_exp seems to not be initialized for all possible execution paths.
Loading history...
167
								stripe_cvc.unmount( '#stripe-cvc-element' );
0 ignored issues
show
Bug introduced by
The variable stripe_cvc seems to not be initialized for all possible execution paths.
Loading history...
168
							}
169
						}
170
171
						if ( 'yes' === wc_stripe_params.inline_cc_form ) {
172
							stripe_card.mount( '#stripe-card-element' );
173
						} else {
174
							stripe_card.mount( '#stripe-card-element' );
175
							stripe_exp.mount( '#stripe-exp-element' );
176
							stripe_cvc.mount( '#stripe-cvc-element' );
177
						}
178
					});
179
				} else if ( $( 'form#add_payment_method' ).length || $( 'form#order_review' ).length ) {
180
					if ( 'yes' === wc_stripe_params.inline_cc_form ) {
181
						stripe_card.mount( '#stripe-card-element' );
182
					} else {
183
						stripe_card.mount( '#stripe-card-element' );
184
						stripe_exp.mount( '#stripe-exp-element' );
185
						stripe_cvc.mount( '#stripe-cvc-element' );
186
					}
187
				}
188
			}
189
		},
190
191
		// Check to see if Stripe in general is being used for checkout.
192
		isStripeChosen: function() {
193
			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() );
194
		},
195
196
		// Currently only support saved cards via credit cards and SEPA. No other payment method.
197
		isStripeSaveCardChosen: function() {
198
			return ( $( '#payment_method_stripe' ).is( ':checked' ) && ( $( 'input[name="wc-stripe-payment-token"]' ).is( ':checked' ) && 'new' !== $( 'input[name="wc-stripe-payment-token"]:checked' ).val() ) ) ||
199
				( $( '#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() ) );
200
		},
201
202
		// Stripe credit card used.
203
		isStripeCardChosen: function() {
204
			return $( '#payment_method_stripe' ).is( ':checked' );
205
		},
206
207
		isBancontactChosen: function() {
208
			return $( '#payment_method_stripe_bancontact' ).is( ':checked' );
209
		},
210
211
		isGiropayChosen: function() {
212
			return $( '#payment_method_stripe_giropay' ).is( ':checked' );
213
		},
214
215
		isIdealChosen: function() {
216
			return $( '#payment_method_stripe_ideal' ).is( ':checked' );
217
		},
218
219
		isSofortChosen: function() {
220
			return $( '#payment_method_stripe_sofort' ).is( ':checked' );
221
		},
222
223
		isAlipayChosen: function() {
224
			return $( '#payment_method_stripe_alipay' ).is( ':checked' );
225
		},
226
227
		isSepaChosen: function() {
228
			return $( '#payment_method_stripe_sepa' ).is( ':checked' );
229
		},
230
231
		isBitcoinChosen: function() {
232
			return $( '#payment_method_stripe_bitcoin' ).is( ':checked' );
233
		},
234
235
		hasSource: function() {
236
			return 0 < $( 'input.stripe-source' ).length;
237
		},
238
239
		// Legacy
240
		hasToken: function() {
241
			return 0 < $( 'input.stripe_token' ).length;
242
		},
243
244
		isMobile: function() {
245
			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...
246
				return true;
247
			}
248
249
			return false;
250
		},
251
252
		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...
253
			var token = wc_stripe_form.form.find( 'input.stripe_token' ),
254
				$required_inputs;
0 ignored issues
show
Unused Code introduced by
The variable $required_inputs seems to be never used. Consider removing it.
Loading history...
255
256
			// If this is a stripe submission (after modal) and token exists, allow submit.
257
			if ( wc_stripe_form.stripe_submit && token ) {
258
				return false;
259
			}
260
261
			// Don't affect submission if modal is not needed.
262
			if ( ! wc_stripe_form.isStripeChosen() ) {
263
				return false;
264
			}
265
266
			return true;
267
		},
268
269
		block: function() {
270
			if ( wc_stripe_form.isMobile() ) {
271
				$.blockUI({
272
					message: null,
273
					overlayCSS: {
274
						background: '#fff',
275
						opacity: 0.6
276
					}
277
				});
278
			} else {
279
				wc_stripe_form.form.block({
280
					message: null,
281
					overlayCSS: {
282
						background: '#fff',
283
						opacity: 0.6
284
					}
285
				});
286
			}
287
		},
288
289
		unblock: function() {
290
			if ( wc_stripe_form.isMobile() ) {
291
				$.unblockUI();
292
			} else {
293
				wc_stripe_form.form.unblock();
294
			}
295
		},
296
297
		getSelectedPaymentElement: function() {
298
			return $( '.payment_methods input[name="payment_method"]:checked' );
299
		},
300
301
		// Stripe Checkout.
302
		openModal: function() {
303
			// Capture submittal and open stripecheckout
304
			var $form = wc_stripe_form.form,
305
				$data = $( '#stripe-payment-data' );
306
307
			wc_stripe_form.reset();
308
309
			var token_action = function( res ) {
310
				$form.find( 'input.stripe_source' ).remove();
311
312
				/* Since source was introduced in 4.0. We need to
313
				 * convert the token into a source.
314
				 */
315
				if ( 'token' === res.object ) {
316
					stripe.createSource( {
317
						type: 'card',
318
						token: res.id,
319
					} ).then( wc_stripe_form.sourceResponse );
320
				} else if ( 'source' === res.object ) {
321
					var response = { source: res };
322
					wc_stripe_form.sourceResponse( response );
323
				}
324
			};
325
326
			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...
327
				key               : wc_stripe_params.key,
328
				billingAddress    : 'yes' === wc_stripe_params.stripe_checkout_require_billing_address,
329
				amount            : $data.data( 'amount' ),
330
				name              : $data.data( 'name' ),
331
				description       : $data.data( 'description' ),
332
				currency          : $data.data( 'currency' ),
333
				image             : $data.data( 'image' ),
334
				bitcoin           : $data.data( 'bitcoin' ),
335
				locale            : $data.data( 'locale' ),
336
				email             : $( '#billing_email' ).val() || $data.data( 'email' ),
337
				panelLabel        : $data.data( 'panel-label' ),
338
				allowRememberMe   : $data.data( 'allow-remember-me' ),
339
				token             : token_action,
340
				closed            : wc_stripe_form.onClose()
341
			});
342
		},
343
344
		// Stripe Checkout.
345
		resetModal: function() {
346
			wc_stripe_form.reset();
347
			wc_stripe_form.stripe_checkout_submit = false;
348
		},
349
350
		// Stripe Checkout.
351
		onClose: function() {
352
			wc_stripe_form.unblock();
353
		},
354
355
		onError: function( e, result ) {
356
			var message = result.error.message,
357
				errorContainer = wc_stripe_form.getSelectedPaymentElement().parent( '.wc_payment_method, .woocommerce-PaymentMethod' ).find( '.stripe-source-errors' );
358
359
			// Customers do not need to know the specifics of the below type of errors
360
			// therefore return a generic localizable error message.
361
			if (
362
				'invalid_request_error' === result.error.type ||
363
				'api_connection_error'  === result.error.type ||
364
				'api_error'             === result.error.type ||
365
				'authentication_error'  === result.error.type ||
366
				'rate_limit_error'      === result.error.type
367
			) {
368
				message = wc_stripe_params.invalid_request_error;
369
			}
370
371
			if ( 'card_error' === result.error.type && wc_stripe_params.hasOwnProperty( result.error.code ) ) {
372
				message = wc_stripe_params[ result.error.code ];
373
			}
374
375
			if ( 'validation_error' === result.error.type && wc_stripe_params.hasOwnProperty( result.error.code ) ) {
376
				message = wc_stripe_params[ result.error.code ];
377
			}
378
379
			wc_stripe_form.reset();
380
			$( '.woocommerce-NoticeGroup-checkout' ).remove();
381
			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...
382
			$( errorContainer ).html( '<ul class="woocommerce_error woocommerce-error wc-stripe-error"><li>' + message + '</li></ul>' );
383
384
			if ( $( '.wc-stripe-error' ).length ) {
385
				$( 'html, body' ).animate({
386
					scrollTop: ( $( '.wc-stripe-error' ).offset().top - 200 )
387
				}, 200 );
388
			}
389
			wc_stripe_form.unblock();
390
		},
391
392
		getOwnerDetails: function() {
393
			var first_name = $( '#billing_first_name' ).length ? $( '#billing_first_name' ).val() : wc_stripe_params.billing_first_name,
394
				last_name  = $( '#billing_last_name' ).length ? $( '#billing_last_name' ).val() : wc_stripe_params.billing_last_name,
395
				extra_details = { owner: { name: '', address: {}, email: '', phone: '' } };
396
397
			extra_details.owner.name = first_name;
398
399
			if ( first_name && last_name ) {
400
				extra_details.owner.name = first_name + ' ' + last_name;
401
			}
402
403
			extra_details.owner.email = $( '#billing_email' ).val();
404
			extra_details.owner.phone = $( '#billing_phone' ).val();
405
406
			/* Stripe does not like empty string values so
407
			 * we need to remove the parameter if we're not
408
			 * passing any value.
409
			 */
410
			if ( typeof extra_details.owner.phone !== 'undefined' && 0 >= extra_details.owner.phone.length ) {
411
				delete extra_details.owner.phone;
412
			}
413
414
			if ( typeof extra_details.owner.email !== 'undefined' && 0 >= extra_details.owner.email.length ) {
415
				delete extra_details.owner.email;
416
			}
417
418
			if ( $( '#billing_address_1' ).length > 0 ) {
419
				extra_details.owner.address.line1       = $( '#billing_address_1' ).val();
420
				extra_details.owner.address.line2       = $( '#billing_address_2' ).val();
421
				extra_details.owner.address.state       = $( '#billing_state' ).val();
422
				extra_details.owner.address.city        = $( '#billing_city' ).val();
423
				extra_details.owner.address.postal_code = $( '#billing_postcode' ).val();
424
				extra_details.owner.address.country     = $( '#billing_country' ).val();
425
			} else if ( wc_stripe_params.billing_address_1 ) {
426
				extra_details.owner.address.line1       = wc_stripe_params.billing_address_1;
427
				extra_details.owner.address.line2       = wc_stripe_params.billing_address_2;
428
				extra_details.owner.address.state       = wc_stripe_params.billing_state;
429
				extra_details.owner.address.city        = wc_stripe_params.billing_city;
430
				extra_details.owner.address.postal_code = wc_stripe_params.billing_postcode;
431
				extra_details.owner.address.country     = wc_stripe_params.billing_country;
432
			}
433
434
			return extra_details;
435
		},
436
437
		createSource: function() {
438
			var extra_details = wc_stripe_form.getOwnerDetails(),
439
				source_type   = 'card';
440
441
			if ( wc_stripe_form.isBancontactChosen() ) {
442
				source_type = 'bancontact';
443
			}
444
445
			if ( wc_stripe_form.isSepaChosen() ) {
446
				source_type = 'sepa_debit';
447
			}
448
449
			if ( wc_stripe_form.isIdealChosen() ) {
450
				source_type = 'ideal';
451
			}
452
453
			if ( wc_stripe_form.isSofortChosen() ) {
454
				source_type = 'sofort';
455
			}
456
457
			if ( wc_stripe_form.isBitcoinChosen() ) {
458
				source_type = 'bitcoin';
459
			}
460
461
			if ( wc_stripe_form.isGiropayChosen() ) {
462
				source_type = 'giropay';
463
			}
464
465
			if ( wc_stripe_form.isAlipayChosen() ) {
466
				source_type = 'alipay';
467
			}
468
469
			if ( 'card' === source_type ) {
470
				stripe.createSource( stripe_card, extra_details ).then( wc_stripe_form.sourceResponse );
471
			} else {
472
				switch ( source_type ) {
0 ignored issues
show
Coding Style introduced by
As per coding-style, switch statements should have a default case.
Loading history...
473
					case 'bancontact':
474
					case 'giropay':
475
					case 'ideal':
476
					case 'sofort':
477
					case 'alipay':
478
						// These redirect flow payment methods need this information to be set at source creation.
479
						extra_details.amount   = $( '#stripe-' + source_type + '-payment-data' ).data( 'amount' );
480
						extra_details.currency = $( '#stripe-' + source_type + '-payment-data' ).data( 'currency' );
481
						extra_details.redirect = { return_url: wc_stripe_params.return_url };
482
483
						if ( wc_stripe_params.statement_descriptor ) {
484
							extra_details.statement_descriptor = wc_stripe_params.statement_descriptor;
485
						}
486
487
						break;
488
				}
489
490
				// Handle special inputs that are unique to a payment method.
491
				switch ( source_type ) {
0 ignored issues
show
Coding Style introduced by
As per coding-style, switch statements should have a default case.
Loading history...
492
					case 'sepa_debit':
493
						extra_details.currency = $( '#stripe-' + source_type + '-payment-data' ).data( 'currency' );
494
						extra_details.owner.name = $( '#stripe-sepa-owner' ).val();
495
						extra_details.sepa_debit = { iban: $( '#stripe-sepa-iban' ).val() };
496
						break;
497
					case 'ideal':
498
						extra_details.ideal = { bank: $( '#stripe-ideal-bank' ).val() };
499
						break;
500
					case 'bitcoin':
501
					case 'alipay':
502
						extra_details.currency = $( '#stripe-' + source_type + '-payment-data' ).data( 'currency' );
503
						extra_details.amount = $( '#stripe-' + source_type + '-payment-data' ).data( 'amount' );
504
						break;
505
				}
506
507
				extra_details.type = source_type;
508
509
				stripe.createSource( extra_details ).then( wc_stripe_form.sourceResponse );
510
			}
511
		},
512
513
		sourceResponse: function( response ) {
514
			if ( response.error ) {
515
				$( document.body ).trigger( 'stripeError', response );
516
			} else if ( 'no' === wc_stripe_params.allow_prepaid_card && 'card' === response.source.type && 'prepaid' === response.source.card.funding ) {
517
				response.error = { message: wc_stripe_params.no_prepaid_card_msg };
518
519
				if ( wc_stripe_params.is_stripe_checkout ) {
520
					wc_stripe_form.submitError( '<ul class="woocommerce-error"><li>' + wc_stripe_params.no_prepaid_card_msg + '</li></ul>' );
521
				} else {
522
					$( document.body ).trigger( 'stripeError', response );
523
				}
524
			} else {
525
				wc_stripe_form.processStripeResponse( response.source );
526
			}
527
		},
528
529
		// Legacy
530
		createToken: function() {
531
			var card       = $( '#stripe-card-number' ).val(),
532
				cvc        = $( '#stripe-card-cvc' ).val(),
533
				expires    = $( '#stripe-card-expiry' ).payment( 'cardExpiryVal' ),
534
				first_name = $( '#billing_first_name' ).length ? $( '#billing_first_name' ).val() : wc_stripe_params.billing_first_name,
535
				last_name  = $( '#billing_last_name' ).length ? $( '#billing_last_name' ).val() : wc_stripe_params.billing_last_name,
536
				data       = {
537
					number   : card,
538
					cvc      : cvc,
539
					exp_month: parseInt( expires.month, 10 ) || 0,
540
					exp_year : parseInt( expires.year, 10 ) || 0
541
				};
542
543
			if ( first_name && last_name ) {
544
				data.name = first_name + ' ' + last_name;
545
			}
546
547
			if ( $( '#billing_address_1' ).length > 0 ) {
548
				data.address_line1   = $( '#billing_address_1' ).val();
549
				data.address_line2   = $( '#billing_address_2' ).val();
550
				data.address_state   = $( '#billing_state' ).val();
551
				data.address_city    = $( '#billing_city' ).val();
552
				data.address_zip     = $( '#billing_postcode' ).val();
553
				data.address_country = $( '#billing_country' ).val();
554
			} else if ( wc_stripe_params.billing_address_1 ) {
555
				data.address_line1   = wc_stripe_params.billing_address_1;
556
				data.address_line2   = wc_stripe_params.billing_address_2;
557
				data.address_state   = wc_stripe_params.billing_state;
558
				data.address_city    = wc_stripe_params.billing_city;
559
				data.address_zip     = wc_stripe_params.billing_postcode;
560
				data.address_country = wc_stripe_params.billing_country;
561
			}
562
			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...
563
			Stripe.createToken( data, wc_stripe_form.onStripeTokenResponse );
564
		},
565
566
		// Legacy
567
		onStripeTokenResponse: function( status, response ) {
568
			if ( response.error ) {
569
				$( 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...
570
			} else {
571
				// check if we allow prepaid cards
572
				if ( 'no' === wc_stripe_params.allow_prepaid_card && 'prepaid' === response.card.funding ) {
573
					response.error = { message: wc_stripe_params.no_prepaid_card_msg };
574
575
					$( document ).trigger( 'stripeError', { response: response } );
576
577
					return false;
578
				}
579
580
				// token contains id, last4, and card type
581
				var token = response.id;
582
583
				// insert the token into the form so it gets submitted to the server
584
				wc_stripe_form.form.append( "<input type='hidden' class='stripe_token' name='stripe_token' value='" + token + "'/>" );
585
586
				if ( $( 'form#add_payment_method' ).length ) {
587
					$( wc_stripe_form.form ).off( 'submit', wc_stripe_form.form.onSubmit );
588
				}
589
590
				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...
591
			}
592
		},
593
594
		onSubmit: function( e ) {
595
			if ( wc_stripe_form.isStripeChosen() && ! wc_stripe_form.isStripeSaveCardChosen() && ! wc_stripe_form.hasSource() && ! wc_stripe_form.hasToken() ) {
596
				e.preventDefault();
597
598
				// Stripe Checkout.
599
				if ( 'yes' === wc_stripe_params.is_stripe_checkout && wc_stripe_form.isStripeModalNeeded() && wc_stripe_form.isStripeCardChosen() ) {
600
					// Since in mobile actions cannot be deferred, no dynamic validation applied.
601
					if ( wc_stripe_form.isMobile() ) {
602
						wc_stripe_form.openModal();
603
					} else {
604
						wc_stripe_form.validateCheckout( 'modal' );
605
					}
606
607
					return false;
608
				}
609
610
				wc_stripe_form.block();
611
612
				// Process legacy card token.
613
				if ( wc_stripe_form.isStripeCardChosen() && 'no' === wc_stripe_params.use_elements ) {
614
					wc_stripe_form.createToken();
615
					return false;
616
				}
617
618
				if (
619
					wc_stripe_form.isBancontactChosen() ||
620
					wc_stripe_form.isGiropayChosen() ||
621
					wc_stripe_form.isIdealChosen() ||
622
					wc_stripe_form.isAlipayChosen()
623
				) {
624
					if ( $( 'form#order_review' ).length ) {
625
						$( 'form#order_review' )
626
							.off(
627
								'submit',
628
								this.onSubmit
629
							);
630
631
						wc_stripe_form.form.submit();
632
					}
633
634
					return true;
635
				}
636
637
				if ( wc_stripe_form.isSofortChosen() ) {
638
					// Check if Sofort bank country is chosen before proceed.
639
					if ( '-1' === $( '#stripe-bank-country' ).val() ) {
640
						var error = { error: { message: wc_stripe_params.no_bank_country_msg } };
641
						$( document.body ).trigger( 'stripeError', error );
642
						return false;
643
					}
644
645
					if ( $( 'form#order_review' ).length ) {
646
						$( 'form#order_review' )
647
							.off(
648
								'submit',
649
								this.onSubmit
650
							);
651
652
						wc_stripe_form.form.submit();
653
					}
654
655
					return true;
656
				}
657
658
				wc_stripe_form.validateCheckout();
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
				if ( wc_stripe_form.isSepaChosen() ) {
673
					// Check if SEPA owner is filled before proceed.
674
					if ( '' === $( '#stripe-sepa-owner' ).val() ) {
675
						$( document.body ).trigger( 'stripeError', { error: { message: wc_stripe_params.no_sepa_owner_msg } } );
676
						return false;
677
					}
678
679
					// Check if SEPA IBAN is filled before proceed.
680
					if ( '' === $( '#stripe-sepa-iban' ).val() ) {
681
						$( document.body ).trigger( 'stripeError', { error: { message: wc_stripe_params.no_sepa_iban_msg } } );
682
						return false;
683
					}
684
				}
685
686
				wc_stripe_form.block();
687
688
				// Process legacy card token.
689
				if ( wc_stripe_form.isStripeCardChosen() && 'no' === wc_stripe_params.use_elements ) {
690
					wc_stripe_form.createToken();
691
					return false;
692
				}
693
694
				wc_stripe_form.createSource();
695
				return false;
696
			}
697
		},
698
699
		onCCFormChange: function() {
700
			wc_stripe_form.reset();
701
		},
702
703
		prepareSourceToServer: function( source ) {
704
			var preparedSource = {
705
				id:      source.id,
706
				card:    source.card ? source.card : '',
707
				bitcoin: source.bitcoin ? source.bitcoin : '',
708
				flow:    source.flow,
709
				object:  source.object,
710
				status:  source.status,
711
				type:    source.type,
712
				usage:   source.usage
713
			};
714
715
			return preparedSource;
716
		},
717
718
		processStripeResponse: function( source ) {
719
			wc_stripe_form.reset();
720
721
			// Insert the Source into the form so it gets submitted to the server.
722
			wc_stripe_form.form.append( "<input type='hidden' class='stripe-source' name='stripe_source' value='" + source.id + "'/>" );
723
724
			if ( $( 'form#add_payment_method' ).length ) {
725
				$( wc_stripe_form.form ).off( 'submit', wc_stripe_form.form.onSubmit );
726
			}
727
728
			wc_stripe_form.form.submit();
729
		},
730
731
		reset: function() {
732
			$( '.wc-stripe-error, .stripe-source, .stripe_token, .stripe-checkout-object' ).remove();
733
734
			// Stripe Checkout.
735
			if ( 'yes' === wc_stripe_params.is_stripe_checkout ) {
736
				wc_stripe_form.stripe_submit = false;
737
			}
738
		},
739
740
		getRequiredFields: function() {
741
			return wc_stripe_form.form.find( '.form-row.validate-required > input, .form-row.validate-required > select, .form-row.validate-required > textarea' );
742
		},
743
744
		validateCheckout: function( type ) {
745
			if ( typeof type === 'undefined' ) {
746
				type = '';
747
			}
748
749
			var data = {
750
				'nonce': wc_stripe_params.stripe_nonce,
751
				'required_fields': wc_stripe_form.getRequiredFields().serialize(),
752
				'all_fields': wc_stripe_form.form.serialize(),
753
				'source_type': wc_stripe_form.getSelectedPaymentElement().val(),
754
				'is_add_payment_page': wc_stripe_params.is_add_payment_method_page
755
			};
756
757
			$.ajax({
758
				type:		'POST',
759
				url:		wc_stripe_form.getAjaxURL( 'validate_checkout' ),
760
				data:		data,
761
				dataType:   'json',
762
				success:	function( result ) {
763
					if ( 'success' === result ) {
764
						// Stripe Checkout.
765
						if ( 'modal' === type ) {
766
							wc_stripe_form.openModal();
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...
767
						} else {
768
							if ( wc_stripe_form.isSepaChosen() ) {
769
								// Check if SEPA owner is filled before proceed.
770
								if ( '' === $( '#stripe-sepa-owner' ).val() ) {
771
									$( document.body ).trigger( 'stripeError', { error: { message: wc_stripe_params.no_sepa_owner_msg } } );
772
									return false;
773
								}
774
775
								// Check if SEPA IBAN is filled before proceed.
776
								if ( '' === $( '#stripe-sepa-iban' ).val() ) {
777
									$( document.body ).trigger( 'stripeError', { error: { message: wc_stripe_params.no_sepa_iban_msg } } );
778
									return false;
779
								}
780
							}
781
782
							wc_stripe_form.createSource();
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...
783
						}
784
					} else if ( result.messages ) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if result.messages 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...
785
						wc_stripe_form.resetModal();
786
						wc_stripe_form.reset();
787
						wc_stripe_form.submitError( result.messages );
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...
788
					}
789
				}
790
			});
791
		},
792
793
		submitError: function( error_message ) {
794
			$( '.woocommerce-NoticeGroup-checkout, .woocommerce-error, .woocommerce-message' ).remove();
795
			wc_stripe_form.form.prepend( '<div class="woocommerce-NoticeGroup woocommerce-NoticeGroup-checkout">' + error_message + '</div>' );
796
			wc_stripe_form.form.removeClass( 'processing' ).unblock();
797
			wc_stripe_form.form.find( '.input-text, select, input:checkbox' ).blur();
798
			
799
			var selector = '';
800
801
			if ( $( '#add_payment_method' ).length ) {
802
				selector = $( '#add_payment_method' );
803
			}
804
805
			if ( $( '#order_review' ).length ) {
806
				selector = $( '#order_review' );
807
			}
808
809
			if ( $( 'form.checkout' ).length ) {
810
				selector = $( 'form.checkout' );
811
			}
812
813
			if ( selector.length ) {
814
				$( 'html, body' ).animate({
815
					scrollTop: ( selector.offset().top - 100 )
816
				}, 500 );
817
			}
818
819
			$( document.body ).trigger( 'checkout_error' );
820
			wc_stripe_form.unblock();
821
		}
822
	};
823
824
	wc_stripe_form.init();
825
} );
826