Completed
Push — master ( 6d8164...bf7249 )
by Roy
03:26
created

stripe.js ➔ ... ➔ wc_stripe_form.createSource   F

Complexity

Conditions 20
Paths 2048

Size

Total Lines 78

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 20
nc 2048
nop 0
dl 0
loc 78
rs 2.2556
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like stripe.js ➔ ... ➔ wc_stripe_form.createSource 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' ) || '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
				token = $form.find( 'input.stripe_token' );
307
308
			token.val( '' );
309
310
			var token_action = function( res ) {
311
				$form.find( 'input.stripe_token' ).remove();
312
				$form.append( '<input type="hidden" class="stripe_token" name="stripe_token" value="' + res.id + '"/>' );
313
				$form.append( "<input type='hidden' class='stripe-checkout-object' name='stripe_checkout_object' value='" + wc_stripe_form.prepareSourceToServer( res ) + "'/>" );
314
				wc_stripe_form.stripe_submit = true;
315
316
				if ( $( 'form#add_payment_method' ).length ) {
317
					$( wc_stripe_form.form ).off( 'submit', wc_stripe_form.form.onSubmit );
318
				}
319
320
				$form.submit();
321
			};
322
323
			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...
324
				key               : wc_stripe_params.key,
325
				billingAddress    : 'yes' === wc_stripe_params.stripe_checkout_require_billing_address,
326
				amount            : $data.data( 'amount' ),
327
				name              : $data.data( 'name' ),
328
				description       : $data.data( 'description' ),
329
				currency          : $data.data( 'currency' ),
330
				image             : $data.data( 'image' ),
331
				bitcoin           : $data.data( 'bitcoin' ),
332
				locale            : $data.data( 'locale' ),
333
				email             : $( '#billing_email' ).val() || $data.data( 'email' ),
334
				panelLabel        : $data.data( 'panel-label' ),
335
				allowRememberMe   : $data.data( 'allow-remember-me' ),
336
				token             : token_action,
337
				closed            : wc_stripe_form.onClose()
338
			});
339
		},
340
341
		// Stripe Checkout.
342
		resetModal: function() {
343
			wc_stripe_form.reset();
344
			wc_stripe_form.stripe_checkout_submit = false;
345
		},
346
347
		// Stripe Checkout.
348
		onClose: function() {
349
			wc_stripe_form.unblock();
350
		},
351
352
		onError: function( e, result ) {
353
			var message = result.error.message,
354
				errorContainer = wc_stripe_form.getSelectedPaymentElement().parent( '.wc_payment_method, .woocommerce-PaymentMethod' ).find( '.stripe-source-errors' );
355
356
			// Customers do not need to know the specifics of the below type of errors
357
			// therefore return a generic localizable error message.
358
			if (
359
				'invalid_request_error' === result.error.type ||
360
				'api_connection_error'  === result.error.type ||
361
				'api_error'             === result.error.type ||
362
				'authentication_error'  === result.error.type ||
363
				'rate_limit_error'      === result.error.type
364
			) {
365
				message = wc_stripe_params.invalid_request_error;
366
			}
367
368
			if ( 'card_error' === result.error.type && wc_stripe_params.hasOwnProperty( result.error.code ) ) {
369
				message = wc_stripe_params[ result.error.code ];
370
			}
371
372
			wc_stripe_form.reset();
373
			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...
374
			$( errorContainer ).html( '<ul class="woocommerce_error woocommerce-error wc-stripe-error"><li>' + message + '</li></ul>' );
375
			wc_stripe_form.unblock();
376
		},
377
378
		getOwnerDetails: function() {
379
			var first_name = $( '#billing_first_name' ).length ? $( '#billing_first_name' ).val() : wc_stripe_params.billing_first_name,
380
				last_name  = $( '#billing_last_name' ).length ? $( '#billing_last_name' ).val() : wc_stripe_params.billing_last_name,
381
				extra_details = { owner: { name: '', address: {}, email: '', phone: '' } };
382
383
			extra_details.owner.name = first_name;
384
385
			if ( first_name && last_name ) {
386
				extra_details.owner.name = first_name + ' ' + last_name;
387
			}
388
389
			extra_details.owner.email = $( '#billing_email' ).val();
390
			extra_details.owner.phone = $( '#billing_phone' ).val();
391
392
			if ( $( '#billing_address_1' ).length > 0 ) {
393
				extra_details.owner.address.line1       = $( '#billing_address_1' ).val();
394
				extra_details.owner.address.line2       = $( '#billing_address_2' ).val();
395
				extra_details.owner.address.state       = $( '#billing_state' ).val();
396
				extra_details.owner.address.city        = $( '#billing_city' ).val();
397
				extra_details.owner.address.postal_code = $( '#billing_postcode' ).val();
398
				extra_details.owner.address.country     = $( '#billing_country' ).val();
399
			} else if ( wc_stripe_params.billing_address_1 ) {
400
				extra_details.owner.address.line1       = wc_stripe_params.billing_address_1;
401
				extra_details.owner.address.line2       = wc_stripe_params.billing_address_2;
402
				extra_details.owner.address.state       = wc_stripe_params.billing_state;
403
				extra_details.owner.address.city        = wc_stripe_params.billing_city;
404
				extra_details.owner.address.postal_code = wc_stripe_params.billing_postcode;
405
				extra_details.owner.address.country     = wc_stripe_params.billing_country;
406
			}
407
408
			return extra_details;
409
		},
410
411
		createSource: function() {
412
			var extra_details = wc_stripe_form.getOwnerDetails(),
413
				source_type   = 'card';
414
415
			if ( wc_stripe_form.isBancontactChosen() ) {
416
				source_type = 'bancontact';
417
			}
418
419
			if ( wc_stripe_form.isSepaChosen() ) {
420
				source_type = 'sepa_debit';
421
			}
422
423
			if ( wc_stripe_form.isIdealChosen() ) {
424
				source_type = 'ideal';
425
			}
426
427
			if ( wc_stripe_form.isSofortChosen() ) {
428
				source_type = 'sofort';
429
			}
430
431
			if ( wc_stripe_form.isBitcoinChosen() ) {
432
				source_type = 'bitcoin';
433
			}
434
435
			if ( wc_stripe_form.isGiropayChosen() ) {
436
				source_type = 'giropay';
437
			}
438
439
			if ( wc_stripe_form.isAlipayChosen() ) {
440
				source_type = 'alipay';
441
			}
442
443
			if ( 'card' === source_type ) {
444
				stripe.createSource( stripe_card, extra_details ).then( wc_stripe_form.sourceResponse );
445
			} else {
446
				switch ( source_type ) {
0 ignored issues
show
Coding Style introduced by
As per coding-style, switch statements should have a default case.
Loading history...
447
					case 'bancontact':
448
					case 'giropay':
449
					case 'ideal':
450
					case 'sofort':
451
					case 'alipay':
452
						// These redirect flow payment methods need this information to be set at source creation.
453
						extra_details.amount               = $( '#stripe-' + source_type + '-payment-data' ).data( 'amount' );
454
						extra_details.currency             = $( '#stripe-' + source_type + '-payment-data' ).data( 'currency' );
455
						extra_details.redirect             = { return_url: wc_stripe_params.return_url };
456
457
						if ( wc_stripe_params.statement_descriptor ) {
458
							extra_details.statement_descriptor = wc_stripe_params.statement_descriptor;
459
						}
460
461
						break;
462
				}
463
464
				// Handle special inputs that are unique to a payment method.
465
				switch ( source_type ) {
0 ignored issues
show
Coding Style introduced by
As per coding-style, switch statements should have a default case.
Loading history...
466
					case 'sepa_debit':
467
						extra_details.currency = $( '#stripe-' + source_type + '-payment-data' ).data( 'currency' );
468
						extra_details.owner.name = $( '#stripe-sepa-owner' ).val();
469
						extra_details.sepa_debit = { iban: $( '#stripe-sepa-iban' ).val() };
470
						break;
471
					case 'ideal':
472
						extra_details.ideal = { bank: $( '#stripe-ideal-bank' ).val() };
473
						break;
474
					case 'sofort':
475
						extra_details.sofort = { country: $( '#stripe-sofort-country' ).val() };
476
						break;
477
					case 'bitcoin':
478
					case 'alipay':
479
						extra_details.currency = $( '#stripe-' + source_type + '-payment-data' ).data( 'currency' );
480
						extra_details.amount = $( '#stripe-' + source_type + '-payment-data' ).data( 'amount' );
481
						break;
482
				}
483
484
				extra_details.type = source_type;
485
486
				stripe.createSource( extra_details ).then( wc_stripe_form.sourceResponse );
487
			}
488
		},
489
490
		sourceResponse: function( response ) {
491
			if ( response.error ) {
492
				$( document.body ).trigger( 'stripeError', response );
493
			} else if ( 'no' === wc_stripe_params.allow_prepaid_card && 'card' === response.source.type && 'prepaid' === response.source.card.funding ) {
494
				response.error = { message: wc_stripe_params.no_prepaid_card_msg };
495
496
				$( document.body ).trigger( 'stripeError', response );
497
			} else {
498
				wc_stripe_form.processStripeResponse( response.source );
499
			}
500
		},
501
502
		// Legacy
503
		createToken: function() {
504
			var card       = $( '#stripe-card-number' ).val(),
505
				cvc        = $( '#stripe-card-cvc' ).val(),
506
				expires    = $( '#stripe-card-expiry' ).payment( 'cardExpiryVal' ),
507
				first_name = $( '#billing_first_name' ).length ? $( '#billing_first_name' ).val() : wc_stripe_params.billing_first_name,
508
				last_name  = $( '#billing_last_name' ).length ? $( '#billing_last_name' ).val() : wc_stripe_params.billing_last_name,
509
				data       = {
510
					number   : card,
511
					cvc      : cvc,
512
					exp_month: parseInt( expires.month, 10 ) || 0,
513
					exp_year : parseInt( expires.year, 10 ) || 0
514
				};
515
516
			if ( first_name && last_name ) {
517
				data.name = first_name + ' ' + last_name;
518
			}
519
520
			if ( $( '#billing_address_1' ).length > 0 ) {
521
				data.address_line1   = $( '#billing_address_1' ).val();
522
				data.address_line2   = $( '#billing_address_2' ).val();
523
				data.address_state   = $( '#billing_state' ).val();
524
				data.address_city    = $( '#billing_city' ).val();
525
				data.address_zip     = $( '#billing_postcode' ).val();
526
				data.address_country = $( '#billing_country' ).val();
527
			} else if ( wc_stripe_params.billing_address_1 ) {
528
				data.address_line1   = wc_stripe_params.billing_address_1;
529
				data.address_line2   = wc_stripe_params.billing_address_2;
530
				data.address_state   = wc_stripe_params.billing_state;
531
				data.address_city    = wc_stripe_params.billing_city;
532
				data.address_zip     = wc_stripe_params.billing_postcode;
533
				data.address_country = wc_stripe_params.billing_country;
534
			}
535
			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...
536
			Stripe.createToken( data, wc_stripe_form.onStripeTokenResponse );
537
		},
538
539
		// Legacy
540
		onStripeTokenResponse: function( status, response ) {
541
			if ( response.error ) {
542
				$( 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...
543
			} else {
544
				// check if we allow prepaid cards
545
				if ( 'no' === wc_stripe_params.allow_prepaid_card && 'prepaid' === response.card.funding ) {
546
					response.error = { message: wc_stripe_params.no_prepaid_card_msg };
547
548
					$( document ).trigger( 'stripeError', { response: response } );
549
550
					return false;
551
				}
552
553
				// token contains id, last4, and card type
554
				var token = response.id;
555
556
				// insert the token into the form so it gets submitted to the server
557
				wc_stripe_form.form.append( "<input type='hidden' class='stripe_token' name='stripe_token' value='" + token + "'/>" );
558
559
				if ( $( 'form#add_payment_method' ).length ) {
560
					$( wc_stripe_form.form ).off( 'submit', wc_stripe_form.form.onSubmit );
561
				}
562
563
				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...
564
			}
565
		},
566
567
		onSubmit: function( e ) {
568
			if ( wc_stripe_form.isStripeChosen() && ! wc_stripe_form.isStripeSaveCardChosen() && ! wc_stripe_form.hasSource() && ! wc_stripe_form.hasToken() ) {
569
				e.preventDefault();
570
571
				// Stripe Checkout.
572
				if ( 'yes' === wc_stripe_params.is_stripe_checkout && wc_stripe_form.isStripeModalNeeded() && wc_stripe_form.isStripeCardChosen() ) {
573
					// Since in mobile actions cannot be deferred, no dynamic validation applied.
574
					if ( wc_stripe_form.isMobile() ) {
575
						wc_stripe_form.openModal();
576
					} else {
577
						wc_stripe_form.validateCheckout( 'modal' );
578
					}
579
580
					return false;
581
				}
582
583
				wc_stripe_form.block();
584
585
				// Process legacy card token.
586
				if ( wc_stripe_form.isStripeCardChosen() && 'no' === wc_stripe_params.use_elements ) {
587
					wc_stripe_form.createToken();
588
					return false;
589
				}
590
591
				if (
592
					wc_stripe_form.isBancontactChosen() ||
593
					wc_stripe_form.isGiropayChosen() ||
594
					wc_stripe_form.isIdealChosen() ||
595
					wc_stripe_form.isAlipayChosen()
596
				) {
597
					if ( $( 'form#order_review' ).length ) {
598
						$( 'form#order_review' )
599
							.off(
600
								'submit',
601
								this.onSubmit
602
							);
603
604
						wc_stripe_form.form.submit();
605
					}
606
607
					return true;
608
				}
609
610
				if ( wc_stripe_form.isSofortChosen() ) {
611
					// Check if Sofort bank country is chosen before proceed.
612
					if ( '-1' === $( '#stripe-bank-country' ).val() ) {
613
						var error = { error: { message: wc_stripe_params.no_bank_country_msg } };
614
						$( document.body ).trigger( 'stripeError', error );
615
						return false;
616
					}
617
618
					if ( $( 'form#order_review' ).length ) {
619
						$( 'form#order_review' )
620
							.off(
621
								'submit',
622
								this.onSubmit
623
							);
624
625
						wc_stripe_form.form.submit();
626
					}
627
628
					return true;
629
				}
630
631
				wc_stripe_form.validateCheckout();
632
633
				// Prevent form submitting
634
				return false;
635
			} 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...
636
				e.preventDefault();
637
638
				// Stripe Checkout.
639
				if ( 'yes' === wc_stripe_params.is_stripe_checkout && wc_stripe_form.isStripeModalNeeded() && wc_stripe_form.isStripeCardChosen() ) {
640
					wc_stripe_form.openModal();
641
642
					return false;
643
				}
644
645
				if ( wc_stripe_form.isSepaChosen() ) {
646
					// Check if SEPA owner is filled before proceed.
647
					if ( '' === $( '#stripe-sepa-owner' ).val() ) {
648
						$( document.body ).trigger( 'stripeError', { error: { message: wc_stripe_params.no_sepa_owner_msg } } );
649
						return false;
650
					}
651
652
					// Check if SEPA IBAN is filled before proceed.
653
					if ( '' === $( '#stripe-sepa-iban' ).val() ) {
654
						$( document.body ).trigger( 'stripeError', { error: { message: wc_stripe_params.no_sepa_iban_msg } } );
655
						return false;
656
					}
657
				}
658
659
				wc_stripe_form.block();
660
661
				// Process legacy card token.
662
				if ( wc_stripe_form.isStripeCardChosen() && 'no' === wc_stripe_params.use_elements ) {
663
					wc_stripe_form.createToken();
664
					return false;
665
				}
666
667
				wc_stripe_form.createSource();
668
				return false;
669
			}
670
		},
671
672
		onCCFormChange: function() {
673
			wc_stripe_form.reset();
674
		},
675
676
		prepareSourceToServer: function( source ) {
677
			var preparedSource = {
678
				id:      source.id,
679
				card:    source.card ? source.card : '',
680
				bitcoin: source.bitcoin ? source.bitcoin : '',
681
				flow:    source.flow,
682
				object:  source.object,
683
				status:  source.status,
684
				type:    source.type,
685
				usage:   source.usage
686
			};
687
688
			return preparedSource;
689
		},
690
691
		processStripeResponse: function( source ) {
692
			wc_stripe_form.reset();
693
694
			// Insert the Source into the form so it gets submitted to the server.
695
			wc_stripe_form.form.append( "<input type='hidden' class='stripe-source' name='stripe_source' value='" + JSON.stringify( wc_stripe_form.prepareSourceToServer( source ) ) + "'/>" );
696
697
			if ( $( 'form#add_payment_method' ).length ) {
698
				$( wc_stripe_form.form ).off( 'submit', wc_stripe_form.form.onSubmit );
699
			}
700
701
			wc_stripe_form.form.submit();
702
		},
703
704
		reset: function() {
705
			$( '.wc-stripe-error, .stripe-source, .stripe_token, .stripe-checkout-object' ).remove();
706
707
			// Stripe Checkout.
708
			if ( 'yes' === wc_stripe_params.is_stripe_checkout ) {
709
				wc_stripe_form.stripe_submit = false;
710
			}
711
		},
712
713
		getRequiredFields: function() {
714
			return wc_stripe_form.form.find( '.form-row.validate-required > input, .form-row.validate-required > select' );
715
		},
716
717
		validateCheckout: function( type ) {
718
			if ( typeof type === 'undefined' ) {
719
				type = '';
720
			}
721
722
			var data = {
723
				'nonce': wc_stripe_params.stripe_nonce,
724
				'required_fields': wc_stripe_form.getRequiredFields().serialize(),
725
				'all_fields': wc_stripe_form.form.serialize(),
726
				'source_type': wc_stripe_form.getSelectedPaymentElement().val()
727
			};
728
729
			$.ajax({
730
				type:		'POST',
731
				url:		wc_stripe_form.getAjaxURL( 'validate_checkout' ),
732
				data:		data,
733
				dataType:   'json',
734
				success:	function( result ) {
735
					if ( 'success' === result ) {
736
						// Stripe Checkout.
737
						if ( 'modal' === type ) {
738
							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...
739
						} else {
740
							if ( wc_stripe_form.isSepaChosen() ) {
741
								// Check if SEPA owner is filled before proceed.
742
								if ( '' === $( '#stripe-sepa-owner' ).val() ) {
743
									$( document.body ).trigger( 'stripeError', { error: { message: wc_stripe_params.no_sepa_owner_msg } } );
744
									return false;
745
								}
746
747
								// Check if SEPA IBAN is filled before proceed.
748
								if ( '' === $( '#stripe-sepa-iban' ).val() ) {
749
									$( document.body ).trigger( 'stripeError', { error: { message: wc_stripe_params.no_sepa_iban_msg } } );
750
									return false;
751
								}
752
							}
753
754
							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...
755
						}
756
					} 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...
757
						wc_stripe_form.resetModal();
758
						wc_stripe_form.reset();
759
						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...
760
					}
761
				}
762
			});
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
			$( 'html, body' ).animate({
771
				scrollTop: ( $( 'form.checkout' ).offset().top - 100 )
772
			}, 1000 );
773
			$( document.body ).trigger( 'checkout_error' );
774
			wc_stripe_form.unblock();
775
		}
776
	};
777
778
	wc_stripe_form.init();
779
} );
780