Completed
Pull Request — master (#510)
by Roy
02:13
created

stripe.js ➔ ... ➔ $.ajax.success   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

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