WooCommerce Stripe Payment Gateway - Version 4.2.0

Version Description

  • 2019-05-29 =
  • Update - Enable Payment Request buttons for Puerto Rico based stores.
  • Update - Add support for Strong Customer Authentication (SCA) for user-initiated payments.
  • Remove - Stripe Modal Checkout.
  • Remove - 3D Secure settings are no longer available in the gateway settings. Use Stripe Radar instead.
  • Fix - Display error messages only next to the chosen saved card.

See changelog for all versions.

=

Download this release

Release Info

Developer woothemes
Plugin Icon 128x128 WooCommerce Stripe Payment Gateway
Version 4.2.0
Comparing to
See all releases

Code changes from version 4.1.16 to 4.2.0

assets/css/stripe-styles.css CHANGED
@@ -1 +1 @@
1
- .wc-stripe-elements-field,.wc-stripe-iban-element-field{border:1px solid #ddd;margin:5px 0;padding:5px;background-color:#fff;outline:0}#payment .methods li.woocommerce-SavedPaymentMethods-token label{display:inline}#payment .methods li.woocommerce-SavedPaymentMethods-new label{display:inline}#add_payment_method #payment ul.payment_methods li img.stripe-icon,.woocommerce-checkout #payment ul.payment_methods li img.stripe-icon{max-width:40px;padding-left:3px;margin:0}#add_payment_method #payment ul.payment_methods li img.stripe-bancontact-icon,.woocommerce-checkout #payment ul.payment_methods li img.stripe-bancontact-icon{max-height:65px;max-width:45px}#add_payment_method #payment ul.payment_methods li img.stripe-ideal-icon,.woocommerce-checkout #payment ul.payment_methods li img.stripe-ideal-icon{max-height:35px}#add_payment_method #payment ul.payment_methods li img.stripe-p24-icon,.woocommerce-checkout #payment ul.payment_methods li img.stripe-p24-icon{max-width:65px}#add_payment_method #payment ul.payment_methods li img.stripe-alipay-icon,.woocommerce-checkout #payment ul.payment_methods li img.stripe-alipay-icon{max-width:50px}#add_payment_method #payment ul.payment_methods li img.stripe-sofort-icon,.woocommerce-checkout #payment ul.payment_methods li img.stripe-sofort-icon{max-width:55px}#add_payment_method #payment ul.payment_methods li img.stripe-sepa-icon,.woocommerce-checkout #payment ul.payment_methods li img.stripe-sepa-icon{max-width:50px}#add_payment_method #payment ul.payment_methods li img.stripe-multibanco-icon,.woocommerce-checkout #payment ul.payment_methods li img.stripe-multibanco-icon{max-height:30px}#add_payment_method #payment ul.payment_methods li img.stripe-eps-icon,.woocommerce-checkout #payment ul.payment_methods li img.stripe-eps-icon{max-height:30px}#add_payment_method #payment ul.payment_methods li img.stripe-giropay-icon,.woocommerce-checkout #payment ul.payment_methods li img.stripe-giropay-icon{max-width:50px}#add_payment_method #payment ul.payment_methods li .stripe-credit-card-brand,.woocommerce-checkout #payment ul.payment_methods li .stripe-credit-card-brand{position:absolute;top:50%;margin-top:-10px;right:10px;background:no-repeat url(../images/credit-card.svg);display:block;width:30px;height:24px}#add_payment_method #payment ul.payment_methods li .stripe-visa-brand,.woocommerce-checkout #payment ul.payment_methods li .stripe-visa-brand{position:absolute;top:50%;margin-top:-10px;right:10px;background:no-repeat url(../images/visa.svg);display:block;width:30px;height:24px}#add_payment_method #payment ul.payment_methods li .stripe-amex-brand,.woocommerce-checkout #payment ul.payment_methods li .stripe-amex-brand{position:absolute;top:50%;margin-top:-10px;right:10px;background:no-repeat url(../images/amex.svg);display:block;width:30px;height:24px}#add_payment_method #payment ul.payment_methods li .stripe-diners-brand,.woocommerce-checkout #payment ul.payment_methods li .stripe-diners-brand{position:absolute;top:50%;margin-top:-10px;right:10px;background:no-repeat url(../images/diners.svg);display:block;width:30px;height:24px}#add_payment_method #payment ul.payment_methods li .stripe-discover-brand,.woocommerce-checkout #payment ul.payment_methods li .stripe-discover-brand{position:absolute;top:50%;margin-top:-10px;right:10px;background:no-repeat url(../images/discover.svg);display:block;width:30px;height:24px}#add_payment_method #payment ul.payment_methods li .stripe-jcb-brand,.woocommerce-checkout #payment ul.payment_methods li .stripe-jcb-brand{position:absolute;top:50%;margin-top:-10px;right:10px;background:no-repeat url(../images/jcb.svg);display:block;width:30px;height:24px}#add_payment_method #payment ul.payment_methods li .stripe-maestro-brand,.woocommerce-checkout #payment ul.payment_methods li .stripe-maestro-brand{position:absolute;top:50%;margin-top:-10px;right:10px;background:no-repeat url(../images/maestro.svg);display:block;width:30px;height:24px}#add_payment_method #payment ul.payment_methods li .stripe-mastercard-brand,.woocommerce-checkout #payment ul.payment_methods li .stripe-mastercard-brand{position:absolute;top:50%;margin-top:-10px;right:10px;background:no-repeat url(../images/mastercard.svg);display:block;width:30px;height:24px}#add_payment_method #payment ul.payment_methods .stripe-card-group,.woocommerce-checkout #payment ul.payment_methods .stripe-card-group{position:relative}
1
+ .wc-stripe-elements-field,.wc-stripe-iban-element-field{border:1px solid #ddd;margin:5px 0;padding:5px;background-color:#fff;outline:0}#payment .methods li.woocommerce-SavedPaymentMethods-token label{display:inline}#payment .methods li.woocommerce-SavedPaymentMethods-new label{display:inline}#add_payment_method #payment ul.payment_methods li img.stripe-icon,.woocommerce-checkout #payment ul.payment_methods li img.stripe-icon{max-width:40px;padding-left:3px;margin:0}#add_payment_method #payment ul.payment_methods li img.stripe-bancontact-icon,.woocommerce-checkout #payment ul.payment_methods li img.stripe-bancontact-icon{max-height:65px;max-width:45px}#add_payment_method #payment ul.payment_methods li img.stripe-ideal-icon,.woocommerce-checkout #payment ul.payment_methods li img.stripe-ideal-icon{max-height:35px}#add_payment_method #payment ul.payment_methods li img.stripe-p24-icon,.woocommerce-checkout #payment ul.payment_methods li img.stripe-p24-icon{max-width:65px}#add_payment_method #payment ul.payment_methods li img.stripe-alipay-icon,.woocommerce-checkout #payment ul.payment_methods li img.stripe-alipay-icon{max-width:50px}#add_payment_method #payment ul.payment_methods li img.stripe-sofort-icon,.woocommerce-checkout #payment ul.payment_methods li img.stripe-sofort-icon{max-width:55px}#add_payment_method #payment ul.payment_methods li img.stripe-sepa-icon,.woocommerce-checkout #payment ul.payment_methods li img.stripe-sepa-icon{max-width:50px}#add_payment_method #payment ul.payment_methods li img.stripe-multibanco-icon,.woocommerce-checkout #payment ul.payment_methods li img.stripe-multibanco-icon{max-height:30px}#add_payment_method #payment ul.payment_methods li img.stripe-eps-icon,.woocommerce-checkout #payment ul.payment_methods li img.stripe-eps-icon{max-height:30px}#add_payment_method #payment ul.payment_methods li img.stripe-giropay-icon,.woocommerce-checkout #payment ul.payment_methods li img.stripe-giropay-icon{max-width:50px}#add_payment_method #payment ul.payment_methods li .stripe-credit-card-brand,.woocommerce-checkout #payment ul.payment_methods li .stripe-credit-card-brand{position:absolute;top:50%;margin-top:-10px;right:10px;background:no-repeat url(../images/credit-card.svg);display:block;width:30px;height:24px}#add_payment_method #payment ul.payment_methods li .stripe-visa-brand,.woocommerce-checkout #payment ul.payment_methods li .stripe-visa-brand{position:absolute;top:50%;margin-top:-10px;right:10px;background:no-repeat url(../images/visa.svg);display:block;width:30px;height:24px}#add_payment_method #payment ul.payment_methods li .stripe-amex-brand,.woocommerce-checkout #payment ul.payment_methods li .stripe-amex-brand{position:absolute;top:50%;margin-top:-10px;right:10px;background:no-repeat url(../images/amex.svg);display:block;width:30px;height:24px}#add_payment_method #payment ul.payment_methods li .stripe-diners-brand,.woocommerce-checkout #payment ul.payment_methods li .stripe-diners-brand{position:absolute;top:50%;margin-top:-10px;right:10px;background:no-repeat url(../images/diners.svg);display:block;width:30px;height:24px}#add_payment_method #payment ul.payment_methods li .stripe-discover-brand,.woocommerce-checkout #payment ul.payment_methods li .stripe-discover-brand{position:absolute;top:50%;margin-top:-10px;right:10px;background:no-repeat url(../images/discover.svg);display:block;width:30px;height:24px}#add_payment_method #payment ul.payment_methods li .stripe-jcb-brand,.woocommerce-checkout #payment ul.payment_methods li .stripe-jcb-brand{position:absolute;top:50%;margin-top:-10px;right:10px;background:no-repeat url(../images/jcb.svg);display:block;width:30px;height:24px}#add_payment_method #payment ul.payment_methods li .stripe-maestro-brand,.woocommerce-checkout #payment ul.payment_methods li .stripe-maestro-brand{position:absolute;top:50%;margin-top:-10px;right:10px;background:no-repeat url(../images/maestro.svg);display:block;width:30px;height:24px}#add_payment_method #payment ul.payment_methods li .stripe-mastercard-brand,.woocommerce-checkout #payment ul.payment_methods li .stripe-mastercard-brand{position:absolute;top:50%;margin-top:-10px;right:10px;background:no-repeat url(../images/mastercard.svg);display:block;width:30px;height:24px}#add_payment_method #payment ul.payment_methods .stripe-card-group,.woocommerce-checkout #payment ul.payment_methods .stripe-card-group{position:relative}.woocommerce-SavedPaymentMethods-token .stripe-source-errors .woocommerce-error{margin-top:1em;margin-bottom:2em}
assets/js/stripe-admin.js CHANGED
@@ -42,15 +42,6 @@ jQuery( function( $ ) {
42
 
43
  $( '#woocommerce_stripe_testmode' ).change();
44
 
45
- // Toggle Stripe Checkout settings.
46
- $( '#woocommerce_stripe_stripe_checkout' ).change( function() {
47
- if ( $( this ).is( ':checked' ) ) {
48
- $( '#woocommerce_stripe_stripe_checkout_image, #woocommerce_stripe_stripe_checkout_description' ).closest( 'tr' ).show();
49
- } else {
50
- $( '#woocommerce_stripe_stripe_checkout_image, #woocommerce_stripe_stripe_checkout_description' ).closest( 'tr' ).hide();
51
- }
52
- } ).change();
53
-
54
  // Toggle Payment Request buttons settings.
55
  $( '#woocommerce_stripe_payment_request' ).change( function() {
56
  if ( $( this ).is( ':checked' ) ) {
@@ -59,6 +50,18 @@ jQuery( function( $ ) {
59
  $( '#woocommerce_stripe_payment_request_button_theme, #woocommerce_stripe_payment_request_button_type, #woocommerce_stripe_payment_request_button_height' ).closest( 'tr' ).hide();
60
  }
61
  } ).change();
 
 
 
 
 
 
 
 
 
 
 
 
62
  }
63
  };
64
 
42
 
43
  $( '#woocommerce_stripe_testmode' ).change();
44
 
 
 
 
 
 
 
 
 
 
45
  // Toggle Payment Request buttons settings.
46
  $( '#woocommerce_stripe_payment_request' ).change( function() {
47
  if ( $( this ).is( ':checked' ) ) {
50
  $( '#woocommerce_stripe_payment_request_button_theme, #woocommerce_stripe_payment_request_button_type, #woocommerce_stripe_payment_request_button_height' ).closest( 'tr' ).hide();
51
  }
52
  } ).change();
53
+
54
+ // Make the 3DS notice dismissable.
55
+ $( '.wc-stripe-3ds-missing' ).each( function() {
56
+ var $setting = $( this );
57
+
58
+ $setting.find( '.notice-dismiss' ).on( 'click.wc-stripe-dismiss-notice', function() {
59
+ $.ajax( {
60
+ type: 'head',
61
+ url: window.location.href + '&stripe_dismiss_3ds=' + $setting.data( 'nonce' ),
62
+ } );
63
+ } );
64
+ } );
65
  }
66
  };
67
 
assets/js/stripe-admin.min.js CHANGED
@@ -1 +1 @@
1
- jQuery(function(r){"use strict";var e={isTestMode:function(){return r("#woocommerce_stripe_testmode").is(":checked")},getSecretKey:function(){return e.isTestMode()?r("#woocommerce_stripe_test_secret_key").val():r("#woocommerce_stripe_secret_key").val()},init:function(){r(document.body).on("change","#woocommerce_stripe_testmode",function(){var e=r("#woocommerce_stripe_test_secret_key").parents("tr").eq(0),t=r("#woocommerce_stripe_test_publishable_key").parents("tr").eq(0),o=r("#woocommerce_stripe_secret_key").parents("tr").eq(0),c=r("#woocommerce_stripe_publishable_key").parents("tr").eq(0);r(this).is(":checked")?(e.show(),t.show(),o.hide(),c.hide()):(e.hide(),t.hide(),o.show(),c.show())}),r("#woocommerce_stripe_testmode").change(),r("#woocommerce_stripe_stripe_checkout").change(function(){r(this).is(":checked")?r("#woocommerce_stripe_stripe_checkout_image, #woocommerce_stripe_stripe_checkout_description").closest("tr").show():r("#woocommerce_stripe_stripe_checkout_image, #woocommerce_stripe_stripe_checkout_description").closest("tr").hide()}).change(),r("#woocommerce_stripe_payment_request").change(function(){r(this).is(":checked")?r("#woocommerce_stripe_payment_request_button_theme, #woocommerce_stripe_payment_request_button_type, #woocommerce_stripe_payment_request_button_height").closest("tr").show():r("#woocommerce_stripe_payment_request_button_theme, #woocommerce_stripe_payment_request_button_type, #woocommerce_stripe_payment_request_button_height").closest("tr").hide()}).change()}};e.init()});
1
+ jQuery(function(c){"use strict";var e={isTestMode:function(){return c("#woocommerce_stripe_testmode").is(":checked")},getSecretKey:function(){return e.isTestMode()?c("#woocommerce_stripe_test_secret_key").val():c("#woocommerce_stripe_secret_key").val()},init:function(){c(document.body).on("change","#woocommerce_stripe_testmode",function(){var e=c("#woocommerce_stripe_test_secret_key").parents("tr").eq(0),t=c("#woocommerce_stripe_test_publishable_key").parents("tr").eq(0),o=c("#woocommerce_stripe_secret_key").parents("tr").eq(0),s=c("#woocommerce_stripe_publishable_key").parents("tr").eq(0);c(this).is(":checked")?(e.show(),t.show(),o.hide(),s.hide()):(e.hide(),t.hide(),o.show(),s.show())}),c("#woocommerce_stripe_testmode").change(),c("#woocommerce_stripe_payment_request").change(function(){c(this).is(":checked")?c("#woocommerce_stripe_payment_request_button_theme, #woocommerce_stripe_payment_request_button_type, #woocommerce_stripe_payment_request_button_height").closest("tr").show():c("#woocommerce_stripe_payment_request_button_theme, #woocommerce_stripe_payment_request_button_type, #woocommerce_stripe_payment_request_button_height").closest("tr").hide()}).change(),c(".wc-stripe-3ds-missing").each(function(){var e=c(this);e.find(".notice-dismiss").on("click.wc-stripe-dismiss-notice",function(){c.ajax({type:"head",url:window.location.href+"&stripe_dismiss_3ds="+e.data("nonce")})})})}};e.init()});
assets/js/stripe.js CHANGED
@@ -4,7 +4,9 @@ jQuery( function( $ ) {
4
  'use strict';
5
 
6
  try {
7
- var stripe = Stripe( wc_stripe_params.key );
 
 
8
  } catch( error ) {
9
  console.log( error );
10
  return;
@@ -34,6 +36,9 @@ jQuery( function( $ ) {
34
  .replace( '%%endpoint%%', 'wc_stripe_' + endpoint );
35
  },
36
 
 
 
 
37
  unmountElements: function() {
38
  if ( 'yes' === wc_stripe_params.inline_cc_form ) {
39
  stripe_card.unmount( '#stripe-card-element' );
@@ -44,20 +49,26 @@ jQuery( function( $ ) {
44
  }
45
  },
46
 
 
 
 
47
  mountElements: function() {
48
  if ( ! $( '#stripe-card-element' ).length ) {
49
  return;
50
  }
51
 
52
  if ( 'yes' === wc_stripe_params.inline_cc_form ) {
53
- stripe_card.mount( '#stripe-card-element' );
54
- } else {
55
- stripe_card.mount( '#stripe-card-element' );
56
- stripe_exp.mount( '#stripe-exp-element' );
57
- stripe_cvc.mount( '#stripe-cvc-element' );
58
  }
 
 
 
 
59
  },
60
 
 
 
 
61
  createElements: function() {
62
  var elementStyles = {
63
  base: {
@@ -147,6 +158,11 @@ jQuery( function( $ ) {
147
  }
148
  },
149
 
 
 
 
 
 
150
  updateCardBrand: function( brand ) {
151
  var brandClass = {
152
  'visa': 'stripe-visa-brand',
@@ -182,9 +198,6 @@ jQuery( function( $ ) {
182
  $( document.body ).trigger( 'wc-credit-card-form-init' );
183
  }
184
 
185
- // Stripe Checkout.
186
- this.stripe_checkout_submit = false;
187
-
188
  // checkout page
189
  if ( $( 'form.woocommerce-checkout' ).length ) {
190
  this.form = $( 'form.woocommerce-checkout' );
@@ -235,100 +248,153 @@ jQuery( function( $ ) {
235
 
236
  wc_stripe_form.createElements();
237
 
238
- if ( 'yes' === wc_stripe_params.is_stripe_checkout ) {
239
- $( document.body ).on( 'click', '.wc-stripe-checkout-button', function() {
240
- wc_stripe_form.openModal();
241
- return false;
242
- } );
243
- }
244
  },
245
 
246
- // Check to see if Stripe in general is being used for checkout.
 
 
 
 
247
  isStripeChosen: function() {
248
  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_eps, #payment_method_stripe_multibanco' ).is( ':checked' ) || ( $( '#payment_method_stripe' ).is( ':checked' ) && 'new' === $( 'input[name="wc-stripe-payment-token"]:checked' ).val() ) || ( $( '#payment_method_stripe_sepa' ).is( ':checked' ) && 'new' === $( 'input[name="wc-stripe-payment-token"]:checked' ).val() );
249
  },
250
 
251
- // Currently only support saved cards via credit cards and SEPA. No other payment method.
 
 
 
 
252
  isStripeSaveCardChosen: function() {
253
- return ( $( '#payment_method_stripe' ).is( ':checked' ) && ( $( 'input[name="wc-stripe-payment-token"]' ).is( ':checked' ) && 'new' !== $( 'input[name="wc-stripe-payment-token"]:checked' ).val() ) ) ||
254
- ( $( '#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() ) );
 
 
 
 
 
 
 
255
  },
256
 
257
- // Stripe credit card used.
 
 
 
 
258
  isStripeCardChosen: function() {
259
  return $( '#payment_method_stripe' ).is( ':checked' );
260
  },
261
 
 
 
 
 
 
262
  isBancontactChosen: function() {
263
  return $( '#payment_method_stripe_bancontact' ).is( ':checked' );
264
  },
265
 
 
 
 
 
 
266
  isGiropayChosen: function() {
267
  return $( '#payment_method_stripe_giropay' ).is( ':checked' );
268
  },
269
 
 
 
 
 
 
270
  isIdealChosen: function() {
271
  return $( '#payment_method_stripe_ideal' ).is( ':checked' );
272
  },
273
 
 
 
 
 
 
274
  isSofortChosen: function() {
275
  return $( '#payment_method_stripe_sofort' ).is( ':checked' );
276
  },
277
 
 
 
 
 
 
278
  isAlipayChosen: function() {
279
  return $( '#payment_method_stripe_alipay' ).is( ':checked' );
280
  },
281
 
 
 
 
 
 
282
  isSepaChosen: function() {
283
  return $( '#payment_method_stripe_sepa' ).is( ':checked' );
284
  },
285
 
 
 
 
 
 
286
  isP24Chosen: function() {
287
  return $( '#payment_method_stripe_p24' ).is( ':checked' );
288
  },
289
 
 
 
 
 
 
290
  isEpsChosen: function() {
291
  return $( '#payment_method_stripe_eps' ).is( ':checked' );
292
  },
293
 
 
 
 
 
 
294
  isMultibancoChosen: function() {
295
  return $( '#payment_method_stripe_multibanco' ).is( ':checked' );
296
  },
297
 
 
 
 
 
 
 
298
  hasSource: function() {
299
  return 0 < $( 'input.stripe-source' ).length;
300
  },
301
 
302
- // Legacy
303
- hasToken: function() {
304
- return 0 < $( 'input.stripe_token' ).length;
305
- },
306
-
307
  isMobile: function() {
308
- if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) {
309
  return true;
310
  }
311
 
312
  return false;
313
  },
314
 
315
- isStripeModalNeeded: function( e ) {
316
- var token = wc_stripe_form.form.find( 'input.stripe_token' ),
317
- $required_inputs;
318
-
319
- // If this is a stripe submission (after modal) and token exists, allow submit.
320
- if ( wc_stripe_form.stripe_submit && token ) {
321
- return false;
322
- }
323
-
324
- // Don't affect submission if modal is not needed.
325
- if ( ! wc_stripe_form.isStripeChosen() ) {
326
- return false;
327
- }
328
-
329
- return true;
330
- },
331
-
332
  block: function() {
333
  if ( ! wc_stripe_form.isMobile() ) {
334
  wc_stripe_form.form.block( {
@@ -341,221 +407,125 @@ jQuery( function( $ ) {
341
  }
342
  },
343
 
 
 
 
344
  unblock: function() {
345
- wc_stripe_form.form.unblock();
346
  },
347
 
 
 
 
 
 
348
  getSelectedPaymentElement: function() {
349
  return $( '.payment_methods input[name="payment_method"]:checked' );
350
  },
351
 
352
- // Stripe Checkout.
353
- openModal: function() {
354
- // Capture submittal and open stripecheckout
355
- var $form = wc_stripe_form.form,
356
- $data = $( '#stripe-payment-data' );
357
-
358
- wc_stripe_form.reset();
359
-
360
- var token_action = function( res ) {
361
- $form.find( 'input.stripe_source' ).remove();
362
-
363
- /* Since source was introduced in 4.0. We need to
364
- * convert the token into a source.
365
- */
366
- if ( 'token' === res.object ) {
367
- stripe.createSource( {
368
- type: 'card',
369
- token: res.id,
370
- } ).then( wc_stripe_form.sourceResponse );
371
- } else if ( 'source' === res.object ) {
372
- var response = { source: res };
373
- wc_stripe_form.sourceResponse( response );
374
- }
375
- };
376
-
377
- StripeCheckout.open( {
378
- key : wc_stripe_params.key,
379
- billingAddress : $data.data( 'billing-address' ),
380
- zipCode : $data.data( 'verify-zip' ),
381
- amount : $data.data( 'amount' ),
382
- name : $data.data( 'name' ),
383
- description : $data.data( 'description' ),
384
- currency : $data.data( 'currency' ),
385
- image : $data.data( 'image' ),
386
- locale : $data.data( 'locale' ),
387
- email : $( '#billing_email' ).val() || $data.data( 'email' ),
388
- panelLabel : $data.data( 'panel-label' ),
389
- allowRememberMe : $data.data( 'allow-remember-me' ),
390
- token : token_action,
391
- closed : wc_stripe_form.onClose()
392
- } );
393
- },
394
-
395
- // Stripe Checkout.
396
- resetModal: function() {
397
- wc_stripe_form.reset();
398
- wc_stripe_form.stripe_checkout_submit = false;
399
- },
400
-
401
- // Stripe Checkout.
402
- onClose: function() {
403
- wc_stripe_form.unblock();
404
- },
405
-
406
  getOwnerDetails: function() {
407
  var first_name = $( '#billing_first_name' ).length ? $( '#billing_first_name' ).val() : wc_stripe_params.billing_first_name,
408
  last_name = $( '#billing_last_name' ).length ? $( '#billing_last_name' ).val() : wc_stripe_params.billing_last_name,
409
- extra_details = { owner: { name: '', address: {}, email: '', phone: '' } };
410
 
411
- extra_details.owner.name = first_name;
412
 
413
  if ( first_name && last_name ) {
414
- extra_details.owner.name = first_name + ' ' + last_name;
415
  } else {
416
- extra_details.owner.name = $( '#stripe-payment-data' ).data( 'full-name' );
417
  }
418
 
419
- extra_details.owner.email = $( '#billing_email' ).val();
420
- extra_details.owner.phone = $( '#billing_phone' ).val();
421
 
422
  /* Stripe does not like empty string values so
423
  * we need to remove the parameter if we're not
424
  * passing any value.
425
  */
426
- if ( typeof extra_details.owner.phone === 'undefined' || 0 >= extra_details.owner.phone.length ) {
427
- delete extra_details.owner.phone;
428
  }
429
 
430
- if ( typeof extra_details.owner.email === 'undefined' || 0 >= extra_details.owner.email.length ) {
431
  if ( $( '#stripe-payment-data' ).data( 'email' ).length ) {
432
- extra_details.owner.email = $( '#stripe-payment-data' ).data( 'email' );
433
  } else {
434
- delete extra_details.owner.email;
435
  }
436
  }
437
 
438
- if ( typeof extra_details.owner.name === 'undefined' || 0 >= extra_details.owner.name.length ) {
439
- delete extra_details.owner.name;
440
  }
441
 
442
  if ( $( '#billing_address_1' ).length > 0 ) {
443
- extra_details.owner.address.line1 = $( '#billing_address_1' ).val();
444
- extra_details.owner.address.line2 = $( '#billing_address_2' ).val();
445
- extra_details.owner.address.state = $( '#billing_state' ).val();
446
- extra_details.owner.address.city = $( '#billing_city' ).val();
447
- extra_details.owner.address.postal_code = $( '#billing_postcode' ).val();
448
- extra_details.owner.address.country = $( '#billing_country' ).val();
449
  } else if ( wc_stripe_params.billing_address_1 ) {
450
- extra_details.owner.address.line1 = wc_stripe_params.billing_address_1;
451
- extra_details.owner.address.line2 = wc_stripe_params.billing_address_2;
452
- extra_details.owner.address.state = wc_stripe_params.billing_state;
453
- extra_details.owner.address.city = wc_stripe_params.billing_city;
454
- extra_details.owner.address.postal_code = wc_stripe_params.billing_postcode;
455
- extra_details.owner.address.country = wc_stripe_params.billing_country;
456
  }
457
 
458
- return extra_details;
 
 
459
  },
460
 
 
 
 
 
 
 
461
  createSource: function() {
462
- var extra_details = wc_stripe_form.getOwnerDetails(),
463
- source_type = 'card';
464
-
465
- if ( wc_stripe_form.isBancontactChosen() ) {
466
- source_type = 'bancontact';
467
- }
468
 
 
469
  if ( wc_stripe_form.isSepaChosen() ) {
470
- source_type = 'sepa_debit';
471
- }
472
-
473
- if ( wc_stripe_form.isIdealChosen() ) {
474
- source_type = 'ideal';
475
- }
476
 
477
- if ( wc_stripe_form.isSofortChosen() ) {
478
- source_type = 'sofort';
479
  }
480
 
481
- if ( wc_stripe_form.isGiropayChosen() ) {
482
- source_type = 'giropay';
483
- }
484
-
485
- if ( wc_stripe_form.isAlipayChosen() ) {
486
- source_type = 'alipay';
487
- }
488
-
489
- if ( 'card' === source_type ) {
490
- stripe.createSource( stripe_card, extra_details ).then( wc_stripe_form.sourceResponse );
491
- } else {
492
- switch ( source_type ) {
493
- case 'bancontact':
494
- case 'giropay':
495
- case 'ideal':
496
- case 'sofort':
497
- case 'alipay':
498
- // These redirect flow payment methods need this information to be set at source creation.
499
- extra_details.amount = $( '#stripe-' + source_type + '-payment-data' ).data( 'amount' );
500
- extra_details.currency = $( '#stripe-' + source_type + '-payment-data' ).data( 'currency' );
501
- extra_details.redirect = { return_url: wc_stripe_params.return_url };
502
-
503
- if ( wc_stripe_params.statement_descriptor ) {
504
- extra_details.statement_descriptor = wc_stripe_params.statement_descriptor;
505
- }
506
-
507
- break;
508
- }
509
-
510
- // Handle special inputs that are unique to a payment method.
511
- switch ( source_type ) {
512
- case 'sepa_debit':
513
- extra_details.currency = $( '#stripe-' + source_type + '-payment-data' ).data( 'currency' );
514
- extra_details.mandate = { notification_method: wc_stripe_params.sepa_mandate_notification };
515
- break;
516
- case 'ideal':
517
- extra_details.ideal = { bank: $( '#stripe-ideal-bank' ).val() };
518
- break;
519
- case 'alipay':
520
- extra_details.currency = $( '#stripe-' + source_type + '-payment-data' ).data( 'currency' );
521
- extra_details.amount = $( '#stripe-' + source_type + '-payment-data' ).data( 'amount' );
522
- break;
523
- case 'sofort':
524
- extra_details.sofort = { country: $( '#billing_country' ).val() };
525
- break;
526
- }
527
-
528
- extra_details.type = source_type;
529
-
530
- if ( 'sepa_debit' === source_type ) {
531
- stripe.createSource( iban, extra_details ).then( wc_stripe_form.sourceResponse );
532
- } else {
533
- stripe.createSource( extra_details ).then( wc_stripe_form.sourceResponse );
534
- }
535
- }
536
  },
537
 
 
 
 
 
 
538
  sourceResponse: function( response ) {
539
  if ( response.error ) {
540
- $( document.body ).trigger( 'stripeError', response );
541
- } else if ( 'no' === wc_stripe_params.allow_prepaid_card && 'card' === response.source.type && 'prepaid' === response.source.card.funding ) {
542
- response.error = { message: wc_stripe_params.no_prepaid_card_msg };
543
-
544
- if ( 'yes' === wc_stripe_params.is_stripe_checkout ) {
545
- wc_stripe_form.submitError( '<ul class="woocommerce-error"><li>' + wc_stripe_params.no_prepaid_card_msg + '</li></ul>' );
546
- } else {
547
- $( document.body ).trigger( 'stripeError', response );
548
- }
549
- } else {
550
- wc_stripe_form.processStripeResponse( response.source );
551
  }
552
- },
553
 
554
- processStripeResponse: function( source ) {
555
  wc_stripe_form.reset();
556
 
557
- // Insert the Source into the form so it gets submitted to the server.
558
- wc_stripe_form.form.append( "<input type='hidden' class='stripe-source' name='stripe_source' value='" + source.id + "'/>" );
 
 
 
 
559
 
560
  if ( $( 'form#add_payment_method' ).length ) {
561
  $( wc_stripe_form.form ).off( 'submit', wc_stripe_form.form.onSubmit );
@@ -564,117 +534,100 @@ jQuery( function( $ ) {
564
  wc_stripe_form.form.submit();
565
  },
566
 
567
- onSubmit: function( e ) {
 
 
 
 
 
 
568
  if ( ! wc_stripe_form.isStripeChosen() ) {
569
- return;
570
  }
571
 
572
- if ( ! wc_stripe_form.isStripeSaveCardChosen() && ! wc_stripe_form.hasSource() && ! wc_stripe_form.hasToken() ) {
573
- e.preventDefault();
574
-
575
- wc_stripe_form.block();
576
-
577
- // Stripe Checkout.
578
- if ( 'yes' === wc_stripe_params.is_stripe_checkout && wc_stripe_form.isStripeModalNeeded() && wc_stripe_form.isStripeCardChosen() ) {
579
- if ( 'yes' === wc_stripe_params.is_checkout ) {
580
- return true;
581
- } else {
582
- wc_stripe_form.openModal();
583
- return false;
584
- }
585
- }
586
-
587
- /*
588
- * For methods that needs redirect, we will create the
589
- * source server side so we can obtain the order ID.
590
- */
591
- if (
592
- wc_stripe_form.isBancontactChosen() ||
593
- wc_stripe_form.isGiropayChosen() ||
594
- wc_stripe_form.isIdealChosen() ||
595
- wc_stripe_form.isAlipayChosen() ||
596
- wc_stripe_form.isSofortChosen() ||
597
- wc_stripe_form.isP24Chosen() ||
598
- wc_stripe_form.isEpsChosen() ||
599
- wc_stripe_form.isMultibancoChosen()
600
- ) {
601
- if ( $( 'form#order_review' ).length ) {
602
- $( 'form#order_review' )
603
- .off(
604
- 'submit',
605
- this.onSubmit
606
- );
607
-
608
- wc_stripe_form.form.submit();
609
-
610
- return false;
611
- }
612
-
613
- if ( $( 'form.woocommerce-checkout' ).length ) {
614
- return true;
615
- }
616
-
617
- if ( $( 'form#add_payment_method' ).length ) {
618
- $( 'form#add_payment_method' )
619
- .off(
620
- 'submit',
621
- this.onSubmit
622
- );
623
-
624
- wc_stripe_form.form.submit();
625
-
626
- return false;
627
- }
628
- }
629
-
630
- wc_stripe_form.createSource();
631
-
632
- // Prevent form submitting
633
- return false;
634
- } else if ( $( 'form#add_payment_method' ).length ) {
635
- e.preventDefault();
636
-
637
- // Stripe Checkout.
638
- if ( 'yes' === wc_stripe_params.is_stripe_checkout && wc_stripe_form.isStripeModalNeeded() && wc_stripe_form.isStripeCardChosen() ) {
639
- wc_stripe_form.openModal();
640
 
641
- return false;
642
- }
 
 
 
 
 
 
 
 
 
 
 
643
 
644
- wc_stripe_form.block();
 
645
 
646
- wc_stripe_form.createSource();
647
- return false;
648
- }
649
  },
650
 
 
 
 
651
  onCCFormChange: function() {
652
  wc_stripe_form.reset();
653
  },
654
 
 
 
 
655
  reset: function() {
656
- $( '.wc-stripe-error, .stripe-source, .stripe_token' ).remove();
657
-
658
- // Stripe Checkout.
659
- if ( 'yes' === wc_stripe_params.is_stripe_checkout ) {
660
- wc_stripe_form.stripe_submit = false;
661
- }
662
  },
663
 
 
 
 
 
 
664
  onSepaError: function( e ) {
665
- var errorContainer = wc_stripe_form.getSelectedPaymentElement().parents( 'li' ).eq(0).find( '.stripe-source-errors' );
666
 
667
- if ( e.error ) {
668
- console.log( e.error.message ); // Leave for troubleshooting.
669
- $( errorContainer ).html( '<ul class="woocommerce_error woocommerce-error wc-stripe-error"><li>' + e.error.message + '</li></ul>' );
670
- } else {
671
- $( errorContainer ).html( '' );
672
  }
 
 
 
 
673
  },
674
 
 
 
 
 
 
 
675
  onError: function( e, result ) {
676
- var message = result.error.message,
677
- errorContainer = wc_stripe_form.getSelectedPaymentElement().parents( 'li' ).eq(0).find( '.stripe-source-errors' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
678
 
679
  /*
680
  * If payment method is SEPA and owner name is not completed,
@@ -684,7 +637,8 @@ jQuery( function( $ ) {
684
  */
685
  if ( wc_stripe_form.isSepaChosen() ) {
686
  if ( 'invalid_owner_name' === result.error.code && wc_stripe_params.hasOwnProperty( result.error.code ) ) {
687
- var error = '<ul class="woocommerce-error"><li>' + wc_stripe_params[ result.error.code ] + '</li></ul>';
 
688
 
689
  return wc_stripe_form.submitError( error );
690
  }
@@ -715,7 +669,8 @@ jQuery( function( $ ) {
715
  wc_stripe_form.reset();
716
  $( '.woocommerce-NoticeGroup-checkout' ).remove();
717
  console.log( result.error.message ); // Leave for troubleshooting.
718
- $( errorContainer ).html( '<ul class="woocommerce_error woocommerce-error wc-stripe-error"><li>' + message + '</li></ul>' );
 
719
 
720
  if ( $( '.wc-stripe-error' ).length ) {
721
  $( 'html, body' ).animate({
@@ -723,14 +678,20 @@ jQuery( function( $ ) {
723
  }, 200 );
724
  }
725
  wc_stripe_form.unblock();
 
726
  },
727
 
 
 
 
 
 
728
  submitError: function( error_message ) {
729
  $( '.woocommerce-NoticeGroup-checkout, .woocommerce-error, .woocommerce-message' ).remove();
730
  wc_stripe_form.form.prepend( '<div class="woocommerce-NoticeGroup woocommerce-NoticeGroup-checkout">' + error_message + '</div>' );
731
  wc_stripe_form.form.removeClass( 'processing' ).unblock();
732
  wc_stripe_form.form.find( '.input-text, select, input:checkbox' ).blur();
733
-
734
  var selector = '';
735
 
736
  if ( $( '#add_payment_method' ).length ) {
@@ -753,6 +714,78 @@ jQuery( function( $ ) {
753
 
754
  $( document.body ).trigger( 'checkout_error' );
755
  wc_stripe_form.unblock();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
756
  }
757
  };
758
 
4
  'use strict';
5
 
6
  try {
7
+ var stripe = Stripe( wc_stripe_params.key, {
8
+ betas: [ 'payment_intent_beta_3' ],
9
+ } );
10
  } catch( error ) {
11
  console.log( error );
12
  return;
36
  .replace( '%%endpoint%%', 'wc_stripe_' + endpoint );
37
  },
38
 
39
+ /**
40
+ * Unmounts all Stripe elements when the checkout page is being updated.
41
+ */
42
  unmountElements: function() {
43
  if ( 'yes' === wc_stripe_params.inline_cc_form ) {
44
  stripe_card.unmount( '#stripe-card-element' );
49
  }
50
  },
51
 
52
+ /**
53
+ * Mounts all elements to their DOM nodes on initial loads and updates.
54
+ */
55
  mountElements: function() {
56
  if ( ! $( '#stripe-card-element' ).length ) {
57
  return;
58
  }
59
 
60
  if ( 'yes' === wc_stripe_params.inline_cc_form ) {
61
+ return stripe_card.mount( '#stripe-card-element' );
 
 
 
 
62
  }
63
+
64
+ stripe_card.mount( '#stripe-card-element' );
65
+ stripe_exp.mount( '#stripe-exp-element' );
66
+ stripe_cvc.mount( '#stripe-cvc-element' );
67
  },
68
 
69
+ /**
70
+ * Creates all Stripe elements that will be used to enter cards or IBANs.
71
+ */
72
  createElements: function() {
73
  var elementStyles = {
74
  base: {
158
  }
159
  },
160
 
161
+ /**
162
+ * Updates the card brand logo with non-inline CC forms.
163
+ *
164
+ * @param {string} brand The identifier of the chosen brand.
165
+ */
166
  updateCardBrand: function( brand ) {
167
  var brandClass = {
168
  'visa': 'stripe-visa-brand',
198
  $( document.body ).trigger( 'wc-credit-card-form-init' );
199
  }
200
 
 
 
 
201
  // checkout page
202
  if ( $( 'form.woocommerce-checkout' ).length ) {
203
  this.form = $( 'form.woocommerce-checkout' );
248
 
249
  wc_stripe_form.createElements();
250
 
251
+ // Listen for hash changes in order to handle payment intents
252
+ window.addEventListener( 'hashchange', wc_stripe_form.onHashChange );
253
+ wc_stripe_form.maybeConfirmIntent();
 
 
 
254
  },
255
 
256
+ /**
257
+ * Check to see if Stripe in general is being used for checkout.
258
+ *
259
+ * @return {boolean}
260
+ */
261
  isStripeChosen: function() {
262
  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_eps, #payment_method_stripe_multibanco' ).is( ':checked' ) || ( $( '#payment_method_stripe' ).is( ':checked' ) && 'new' === $( 'input[name="wc-stripe-payment-token"]:checked' ).val() ) || ( $( '#payment_method_stripe_sepa' ).is( ':checked' ) && 'new' === $( 'input[name="wc-stripe-payment-token"]:checked' ).val() );
263
  },
264
 
265
+ /**
266
+ * Currently only support saved cards via credit cards and SEPA. No other payment method.
267
+ *
268
+ * @return {boolean}
269
+ */
270
  isStripeSaveCardChosen: function() {
271
+ return (
272
+ $( '#payment_method_stripe' ).is( ':checked' )
273
+ && $( 'input[name="wc-stripe-payment-token"]' ).is( ':checked' )
274
+ && 'new' !== $( 'input[name="wc-stripe-payment-token"]:checked' ).val()
275
+ ) || (
276
+ $( '#payment_method_stripe_sepa' ).is( ':checked' )
277
+ && $( 'input[name="wc-stripe_sepa-payment-token"]' ).is( ':checked' )
278
+ && 'new' !== $( 'input[name="wc-stripe_sepa-payment-token"]:checked' ).val()
279
+ );
280
  },
281
 
282
+ /**
283
+ * Check if Stripe credit card is being used used.
284
+ *
285
+ * @return {boolean}
286
+ */
287
  isStripeCardChosen: function() {
288
  return $( '#payment_method_stripe' ).is( ':checked' );
289
  },
290
 
291
+ /**
292
+ * Check if Stripe Bancontact is being used used.
293
+ *
294
+ * @return {boolean}
295
+ */
296
  isBancontactChosen: function() {
297
  return $( '#payment_method_stripe_bancontact' ).is( ':checked' );
298
  },
299
 
300
+ /**
301
+ * Check if Stripe Giropay is being used used.
302
+ *
303
+ * @return {boolean}
304
+ */
305
  isGiropayChosen: function() {
306
  return $( '#payment_method_stripe_giropay' ).is( ':checked' );
307
  },
308
 
309
+ /**
310
+ * Check if Stripe iDeal is being used used.
311
+ *
312
+ * @return {boolean}
313
+ */
314
  isIdealChosen: function() {
315
  return $( '#payment_method_stripe_ideal' ).is( ':checked' );
316
  },
317
 
318
+ /**
319
+ * Check if Stripe SOFORT is being used used.
320
+ *
321
+ * @return {boolean}
322
+ */
323
  isSofortChosen: function() {
324
  return $( '#payment_method_stripe_sofort' ).is( ':checked' );
325
  },
326
 
327
+ /**
328
+ * Check if Stripe Alipay is being used used.
329
+ *
330
+ * @return {boolean}
331
+ */
332
  isAlipayChosen: function() {
333
  return $( '#payment_method_stripe_alipay' ).is( ':checked' );
334
  },
335
 
336
+ /**
337
+ * Check if Stripe SEPA Direct Debit is being used used.
338
+ *
339
+ * @return {boolean}
340
+ */
341
  isSepaChosen: function() {
342
  return $( '#payment_method_stripe_sepa' ).is( ':checked' );
343
  },
344
 
345
+ /**
346
+ * Check if Stripe P24 is being used used.
347
+ *
348
+ * @return {boolean}
349
+ */
350
  isP24Chosen: function() {
351
  return $( '#payment_method_stripe_p24' ).is( ':checked' );
352
  },
353
 
354
+ /**
355
+ * Check if Stripe EPS is being used used.
356
+ *
357
+ * @return {boolean}
358
+ */
359
  isEpsChosen: function() {
360
  return $( '#payment_method_stripe_eps' ).is( ':checked' );
361
  },
362
 
363
+ /**
364
+ * Check if Stripe Multibanco is being used used.
365
+ *
366
+ * @return {boolean}
367
+ */
368
  isMultibancoChosen: function() {
369
  return $( '#payment_method_stripe_multibanco' ).is( ':checked' );
370
  },
371
 
372
+ /**
373
+ * Checks if a source ID is present as a hidden input.
374
+ * Only used when SEPA Direct Debit is chosen.
375
+ *
376
+ * @return {boolean}
377
+ */
378
  hasSource: function() {
379
  return 0 < $( 'input.stripe-source' ).length;
380
  },
381
 
382
+ /**
383
+ * Check whether a mobile device is being used.
384
+ *
385
+ * @return {boolean}
386
+ */
387
  isMobile: function() {
388
+ if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( navigator.userAgent ) ) {
389
  return true;
390
  }
391
 
392
  return false;
393
  },
394
 
395
+ /**
396
+ * Blocks payment forms with an overlay while being submitted.
397
+ */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
398
  block: function() {
399
  if ( ! wc_stripe_form.isMobile() ) {
400
  wc_stripe_form.form.block( {
407
  }
408
  },
409
 
410
+ /**
411
+ * Removes overlays from payment forms.
412
+ */
413
  unblock: function() {
414
+ wc_stripe_form.form && wc_stripe_form.form.unblock();
415
  },
416
 
417
+ /**
418
+ * Returns the selected payment method HTML element.
419
+ *
420
+ * @return {HTMLElement}
421
+ */
422
  getSelectedPaymentElement: function() {
423
  return $( '.payment_methods input[name="payment_method"]:checked' );
424
  },
425
 
426
+ /**
427
+ * Retrieves "owner" data from either the billing fields in a form or preset settings.
428
+ *
429
+ * @return {Object}
430
+ */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
431
  getOwnerDetails: function() {
432
  var first_name = $( '#billing_first_name' ).length ? $( '#billing_first_name' ).val() : wc_stripe_params.billing_first_name,
433
  last_name = $( '#billing_last_name' ).length ? $( '#billing_last_name' ).val() : wc_stripe_params.billing_last_name,
434
+ owner = { name: '', address: {}, email: '', phone: '' };
435
 
436
+ owner.name = first_name;
437
 
438
  if ( first_name && last_name ) {
439
+ owner.name = first_name + ' ' + last_name;
440
  } else {
441
+ owner.name = $( '#stripe-payment-data' ).data( 'full-name' );
442
  }
443
 
444
+ owner.email = $( '#billing_email' ).val();
445
+ owner.phone = $( '#billing_phone' ).val();
446
 
447
  /* Stripe does not like empty string values so
448
  * we need to remove the parameter if we're not
449
  * passing any value.
450
  */
451
+ if ( typeof owner.phone === 'undefined' || 0 >= owner.phone.length ) {
452
+ delete owner.phone;
453
  }
454
 
455
+ if ( typeof owner.email === 'undefined' || 0 >= owner.email.length ) {
456
  if ( $( '#stripe-payment-data' ).data( 'email' ).length ) {
457
+ owner.email = $( '#stripe-payment-data' ).data( 'email' );
458
  } else {
459
+ delete owner.email;
460
  }
461
  }
462
 
463
+ if ( typeof owner.name === 'undefined' || 0 >= owner.name.length ) {
464
+ delete owner.name;
465
  }
466
 
467
  if ( $( '#billing_address_1' ).length > 0 ) {
468
+ owner.address.line1 = $( '#billing_address_1' ).val();
469
+ owner.address.line2 = $( '#billing_address_2' ).val();
470
+ owner.address.state = $( '#billing_state' ).val();
471
+ owner.address.city = $( '#billing_city' ).val();
472
+ owner.address.postal_code = $( '#billing_postcode' ).val();
473
+ owner.address.country = $( '#billing_country' ).val();
474
  } else if ( wc_stripe_params.billing_address_1 ) {
475
+ owner.address.line1 = wc_stripe_params.billing_address_1;
476
+ owner.address.line2 = wc_stripe_params.billing_address_2;
477
+ owner.address.state = wc_stripe_params.billing_state;
478
+ owner.address.city = wc_stripe_params.billing_city;
479
+ owner.address.postal_code = wc_stripe_params.billing_postcode;
480
+ owner.address.country = wc_stripe_params.billing_country;
481
  }
482
 
483
+ return {
484
+ owner: owner,
485
+ };
486
  },
487
 
488
+ /**
489
+ * Initiates the creation of a Source object.
490
+ *
491
+ * Currently this is only used for credit cards and SEPA Direct Debit,
492
+ * all other payment methods work with redirects to create sources.
493
+ */
494
  createSource: function() {
495
+ var extra_details = wc_stripe_form.getOwnerDetails();
 
 
 
 
 
496
 
497
+ // Handle SEPA Direct Debit payments.
498
  if ( wc_stripe_form.isSepaChosen() ) {
499
+ extra_details.currency = $( '#stripe-sepa_debit-payment-data' ).data( 'currency' );
500
+ extra_details.mandate = { notification_method: wc_stripe_params.sepa_mandate_notification };
501
+ extra_details.type = 'sepa_debit';
 
 
 
502
 
503
+ return stripe.createSource( iban, extra_details ).then( wc_stripe_form.sourceResponse );
 
504
  }
505
 
506
+ // Handle card payments.
507
+ return stripe.createSource( stripe_card, extra_details )
508
+ .then( wc_stripe_form.sourceResponse );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
509
  },
510
 
511
+ /**
512
+ * Handles responses, based on source object.
513
+ *
514
+ * @param {Object} response The `stripe.createSource` response.
515
+ */
516
  sourceResponse: function( response ) {
517
  if ( response.error ) {
518
+ return $( document.body ).trigger( 'stripeError', response );
 
 
 
 
 
 
 
 
 
 
519
  }
 
520
 
 
521
  wc_stripe_form.reset();
522
 
523
+ wc_stripe_form.form.append(
524
+ $( '<input type="hidden" />' )
525
+ .addClass( 'stripe-source' )
526
+ .attr( 'name', 'stripe_source' )
527
+ .val( response.source.id )
528
+ );
529
 
530
  if ( $( 'form#add_payment_method' ).length ) {
531
  $( wc_stripe_form.form ).off( 'submit', wc_stripe_form.form.onSubmit );
534
  wc_stripe_form.form.submit();
535
  },
536
 
537
+ /**
538
+ * Performs payment-related actions when a checkout/payment form is being submitted.
539
+ *
540
+ * @return {boolean} An indicator whether the submission should proceed.
541
+ * WooCommerce's checkout.js stops only on `false`, so this needs to be explicit.
542
+ */
543
+ onSubmit: function() {
544
  if ( ! wc_stripe_form.isStripeChosen() ) {
545
+ return true;
546
  }
547
 
548
+ // If a source is already in place, submit the form as usual.
549
+ if ( wc_stripe_form.isStripeSaveCardChosen() || wc_stripe_form.hasSource() ) {
550
+ return true;
551
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
552
 
553
+ // For methods that needs redirect, we will create the source server side so we can obtain the order ID.
554
+ if (
555
+ wc_stripe_form.isBancontactChosen() ||
556
+ wc_stripe_form.isGiropayChosen() ||
557
+ wc_stripe_form.isIdealChosen() ||
558
+ wc_stripe_form.isAlipayChosen() ||
559
+ wc_stripe_form.isSofortChosen() ||
560
+ wc_stripe_form.isP24Chosen() ||
561
+ wc_stripe_form.isEpsChosen() ||
562
+ wc_stripe_form.isMultibancoChosen()
563
+ ) {
564
+ return true;
565
+ }
566
 
567
+ wc_stripe_form.block();
568
+ wc_stripe_form.createSource();
569
 
570
+ return false;
 
 
571
  },
572
 
573
+ /**
574
+ * If a new credit card is entered, reset sources.
575
+ */
576
  onCCFormChange: function() {
577
  wc_stripe_form.reset();
578
  },
579
 
580
+ /**
581
+ * Removes all Stripe errors and hidden fields with IDs from the form.
582
+ */
583
  reset: function() {
584
+ $( '.wc-stripe-error, .stripe-source' ).remove();
 
 
 
 
 
585
  },
586
 
587
+ /**
588
+ * Displays a SEPA-specific error message.
589
+ *
590
+ * @param {Event} e The event with the error.
591
+ */
592
  onSepaError: function( e ) {
593
+ var errorContainer = wc_stripe_form.getSelectedPaymentElement().parents( 'li' ).eq( 0 ).find( '.stripe-source-errors' );
594
 
595
+ if ( ! e.error ) {
596
+ return $( errorContainer ).html( '' );
 
 
 
597
  }
598
+
599
+ console.log( e.error.message ); // Leave for troubleshooting.
600
+ $( errorContainer ).html( '<ul class="woocommerce_error woocommerce-error wc-stripe-error"><li /></ul>' );
601
+ $( errorContainer ).find( 'li' ).text( e.error.message ); // Prevent XSS
602
  },
603
 
604
+ /**
605
+ * Displays stripe-related errors.
606
+ *
607
+ * @param {Event} e The jQuery event.
608
+ * @param {Object} result The result of Stripe call.
609
+ */
610
  onError: function( e, result ) {
611
+ var message = result.error.message;
612
+ var selectedMethodElement = wc_stripe_form.getSelectedPaymentElement().closest( 'li' );
613
+ var savedTokens = selectedMethodElement.find( '.woocommerce-SavedPaymentMethods-tokenInput' );
614
+ var errorContainer;
615
+
616
+ if ( savedTokens.length ) {
617
+ // In case there are saved cards too, display the message next to the correct one.
618
+ var selectedToken = savedTokens.filter( ':checked' );
619
+
620
+ if ( selectedToken.closest( '.woocommerce-SavedPaymentMethods-new' ).length ) {
621
+ // Display the error next to the CC fields if a new card is being entered.
622
+ errorContainer = $( '#wc-stripe-cc-form .stripe-source-errors' );
623
+ } else {
624
+ // Display the error next to the chosen saved card.
625
+ errorContainer = selectedToken.closest( 'li' ).find( '.stripe-source-errors' );
626
+ }
627
+ } else {
628
+ // When no saved cards are available, display the error next to CC fields.
629
+ errorContainer = selectedMethodElement.find( '.stripe-source-errors' );
630
+ }
631
 
632
  /*
633
  * If payment method is SEPA and owner name is not completed,
637
  */
638
  if ( wc_stripe_form.isSepaChosen() ) {
639
  if ( 'invalid_owner_name' === result.error.code && wc_stripe_params.hasOwnProperty( result.error.code ) ) {
640
+ var error = '<ul class="woocommerce-error"><li /></ul>';
641
+ error.find( 'li' ).text( wc_stripe_params[ result.error.code ] ); // Prevent XSS
642
 
643
  return wc_stripe_form.submitError( error );
644
  }
669
  wc_stripe_form.reset();
670
  $( '.woocommerce-NoticeGroup-checkout' ).remove();
671
  console.log( result.error.message ); // Leave for troubleshooting.
672
+ $( errorContainer ).html( '<ul class="woocommerce_error woocommerce-error wc-stripe-error"><li /></ul>' );
673
+ $( errorContainer ).find( 'li' ).text( message ); // Prevent XSS
674
 
675
  if ( $( '.wc-stripe-error' ).length ) {
676
  $( 'html, body' ).animate({
678
  }, 200 );
679
  }
680
  wc_stripe_form.unblock();
681
+ $.unblockUI(); // If arriving via Payment Request Button.
682
  },
683
 
684
+ /**
685
+ * Displays an error message in the beginning of the form and scrolls to it.
686
+ *
687
+ * @param {Object} error_message An error message jQuery object.
688
+ */
689
  submitError: function( error_message ) {
690
  $( '.woocommerce-NoticeGroup-checkout, .woocommerce-error, .woocommerce-message' ).remove();
691
  wc_stripe_form.form.prepend( '<div class="woocommerce-NoticeGroup woocommerce-NoticeGroup-checkout">' + error_message + '</div>' );
692
  wc_stripe_form.form.removeClass( 'processing' ).unblock();
693
  wc_stripe_form.form.find( '.input-text, select, input:checkbox' ).blur();
694
+
695
  var selector = '';
696
 
697
  if ( $( '#add_payment_method' ).length ) {
714
 
715
  $( document.body ).trigger( 'checkout_error' );
716
  wc_stripe_form.unblock();
717
+ },
718
+
719
+ /**
720
+ * Handles changes in the hash in order to show a modal for PaymentIntent confirmations.
721
+ *
722
+ * Listens for `hashchange` events and checks for a hash in the following format:
723
+ * #confirm-pi-<intentClientSecret>:<successRedirectURL>
724
+ *
725
+ * If such a hash appears, the partials will be used to call `stripe.handleCardPayment`
726
+ * in order to allow customers to confirm an 3DS/SCA authorization.
727
+ *
728
+ * Those redirects/hashes are generated in `WC_Gateway_Stripe::process_payment`.
729
+ */
730
+ onHashChange: function() {
731
+ var partials = window.location.hash.match( /^#?confirm-pi-([^:]+):(.+)$/ );
732
+
733
+ if ( ! partials || 3 > partials.length ) {
734
+ return;
735
+ }
736
+
737
+ var intentClientSecret = partials[1];
738
+ var redirectURL = decodeURIComponent( partials[2] );
739
+
740
+ // Cleanup the URL
741
+ window.location.hash = '';
742
+
743
+ wc_stripe_form.openIntentModal( intentClientSecret, redirectURL );
744
+ },
745
+
746
+ maybeConfirmIntent: function() {
747
+ if ( ! $( '#stripe-intent-id' ).length || ! $( '#stripe-intent-return' ).length ) {
748
+ return;
749
+ }
750
+
751
+ var intentSecret = $( '#stripe-intent-id' ).val();
752
+ var returnURL = $( '#stripe-intent-return' ).val();
753
+
754
+ wc_stripe_form.openIntentModal( intentSecret, returnURL, true );
755
+ },
756
+
757
+ /**
758
+ * Opens the modal for PaymentIntent authorizations.
759
+ *
760
+ * @param {string} intentClientSecret The client secret of the intent.
761
+ * @param {string} redirectURL The URL to ping on fail or redirect to on success.
762
+ * @param {boolean} alwaysRedirect If set to true, an immediate redirect will happen no matter the result.
763
+ * If not, an error will be displayed on failure.
764
+ */
765
+ openIntentModal: function( intentClientSecret, redirectURL, alwaysRedirect ) {
766
+ stripe.handleCardPayment( intentClientSecret )
767
+ .then( function( response ) {
768
+ if ( response.error ) {
769
+ throw response.error;
770
+ }
771
+
772
+ if ( 'requires_capture' !== response.paymentIntent.status && 'succeeded' !== response.paymentIntent.status ) {
773
+ return;
774
+ }
775
+
776
+ window.location = redirectURL;
777
+ } )
778
+ .catch( function( error ) {
779
+ if ( alwaysRedirect ) {
780
+ return window.location = redirectURL;
781
+ }
782
+
783
+ $( document.body ).trigger( 'stripeError', { error: error } );
784
+ wc_stripe_form.form && wc_stripe_form.form.removeClass( 'processing' );
785
+
786
+ // Report back to the server.
787
+ $.get( redirectURL + '&is_ajax' );
788
+ } );
789
  }
790
  };
791
 
assets/js/stripe.min.js CHANGED
@@ -1 +1 @@
1
- jQuery(function(a){"use strict";try{var o=Stripe(wc_stripe_params.key)}catch(e){return void console.log(e)}var t,n,s,e=Object.keys(wc_stripe_params.elements_options).length?wc_stripe_params.elements_options:{},r=Object.keys(wc_stripe_params.sepa_elements_options).length?wc_stripe_params.sepa_elements_options:{},i=o.elements(e),c=i.create("iban",r),p={getAjaxURL:function(e){return wc_stripe_params.ajaxurl.toString().replace("%%endpoint%%","wc_stripe_"+e)},unmountElements:function(){"yes"===wc_stripe_params.inline_cc_form?t.unmount("#stripe-card-element"):(t.unmount("#stripe-card-element"),n.unmount("#stripe-exp-element"),s.unmount("#stripe-cvc-element"))},mountElements:function(){a("#stripe-card-element").length&&("yes"===wc_stripe_params.inline_cc_form?t.mount("#stripe-card-element"):(t.mount("#stripe-card-element"),n.mount("#stripe-exp-element"),s.mount("#stripe-cvc-element")))},createElements:function(){var e={base:{iconColor:"#666EE8",color:"#31325F",fontSize:"15px","::placeholder":{color:"#CFD7E0"}}},r={focus:"focused",empty:"empty",invalid:"invalid"};e=wc_stripe_params.elements_styling?wc_stripe_params.elements_styling:e,r=wc_stripe_params.elements_classes?wc_stripe_params.elements_classes:r,"yes"===wc_stripe_params.inline_cc_form?(t=i.create("card",{style:e,hidePostalCode:!0})).addEventListener("change",function(e){p.onCCFormChange(),e.error&&a(document.body).trigger("stripeError",e)}):(t=i.create("cardNumber",{style:e,classes:r}),n=i.create("cardExpiry",{style:e,classes:r}),s=i.create("cardCvc",{style:e,classes:r}),t.addEventListener("change",function(e){p.onCCFormChange(),p.updateCardBrand(e.brand),e.error&&a(document.body).trigger("stripeError",e)}),n.addEventListener("change",function(e){p.onCCFormChange(),e.error&&a(document.body).trigger("stripeError",e)}),s.addEventListener("change",function(e){p.onCCFormChange(),e.error&&a(document.body).trigger("stripeError",e)})),"yes"===wc_stripe_params.is_checkout?a(document.body).on("updated_checkout",function(){t&&p.unmountElements(),p.mountElements(),a("#stripe-iban-element").length&&c.mount("#stripe-iban-element")}):(a("form#add_payment_method").length||a("form#order_review").length)&&(p.mountElements(),a("#stripe-iban-element").length&&c.mount("#stripe-iban-element"))},updateCardBrand:function(e){var r={visa:"stripe-visa-brand",mastercard:"stripe-mastercard-brand",amex:"stripe-amex-brand",discover:"stripe-discover-brand",diners:"stripe-diners-brand",jcb:"stripe-jcb-brand",unknown:"stripe-credit-card-brand"},t=a(".stripe-card-brand"),o="stripe-credit-card-brand";e in r&&(o=r[e]),a.each(r,function(e,r){t.removeClass(r)}),t.addClass(o)},init:function(){"yes"!==wc_stripe_params.is_change_payment_page&&"yes"!==wc_stripe_params.is_pay_for_order_page||a(document.body).trigger("wc-credit-card-form-init"),this.stripe_checkout_submit=!1,a("form.woocommerce-checkout").length&&(this.form=a("form.woocommerce-checkout")),a("form.woocommerce-checkout").on("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",this.onSubmit),a("form#order_review").length&&(this.form=a("form#order_review")),a("form#order_review, form#add_payment_method").on("submit",this.onSubmit),a("form#add_payment_method").length&&(this.form=a("form#add_payment_method")),a("form.woocommerce-checkout").on("change",this.reset),a(document).on("stripeError",this.onError).on("checkout_error",this.reset),c.on("change",this.onSepaError),p.createElements(),"yes"===wc_stripe_params.is_stripe_checkout&&a(document.body).on("click",".wc-stripe-checkout-button",function(){return p.openModal(),!1})},isStripeChosen:function(){return a("#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_eps, #payment_method_stripe_multibanco").is(":checked")||a("#payment_method_stripe").is(":checked")&&"new"===a('input[name="wc-stripe-payment-token"]:checked').val()||a("#payment_method_stripe_sepa").is(":checked")&&"new"===a('input[name="wc-stripe-payment-token"]:checked').val()},isStripeSaveCardChosen:function(){return a("#payment_method_stripe").is(":checked")&&a('input[name="wc-stripe-payment-token"]').is(":checked")&&"new"!==a('input[name="wc-stripe-payment-token"]:checked').val()||a("#payment_method_stripe_sepa").is(":checked")&&a('input[name="wc-stripe_sepa-payment-token"]').is(":checked")&&"new"!==a('input[name="wc-stripe_sepa-payment-token"]:checked').val()},isStripeCardChosen:function(){return a("#payment_method_stripe").is(":checked")},isBancontactChosen:function(){return a("#payment_method_stripe_bancontact").is(":checked")},isGiropayChosen:function(){return a("#payment_method_stripe_giropay").is(":checked")},isIdealChosen:function(){return a("#payment_method_stripe_ideal").is(":checked")},isSofortChosen:function(){return a("#payment_method_stripe_sofort").is(":checked")},isAlipayChosen:function(){return a("#payment_method_stripe_alipay").is(":checked")},isSepaChosen:function(){return a("#payment_method_stripe_sepa").is(":checked")},isP24Chosen:function(){return a("#payment_method_stripe_p24").is(":checked")},isEpsChosen:function(){return a("#payment_method_stripe_eps").is(":checked")},isMultibancoChosen:function(){return a("#payment_method_stripe_multibanco").is(":checked")},hasSource:function(){return 0<a("input.stripe-source").length},hasToken:function(){return 0<a("input.stripe_token").length},isMobile:function(){return!!/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)},isStripeModalNeeded:function(e){var r=p.form.find("input.stripe_token");return(!p.stripe_submit||!r)&&!!p.isStripeChosen()},block:function(){p.isMobile()||p.form.block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},unblock:function(){p.form.unblock()},getSelectedPaymentElement:function(){return a('.payment_methods input[name="payment_method"]:checked')},openModal:function(){var t=p.form,e=a("#stripe-payment-data");p.reset();StripeCheckout.open({key:wc_stripe_params.key,billingAddress:e.data("billing-address"),zipCode:e.data("verify-zip"),amount:e.data("amount"),name:e.data("name"),description:e.data("description"),currency:e.data("currency"),image:e.data("image"),locale:e.data("locale"),email:a("#billing_email").val()||e.data("email"),panelLabel:e.data("panel-label"),allowRememberMe:e.data("allow-remember-me"),token:function(e){if(t.find("input.stripe_source").remove(),"token"===e.object)o.createSource({type:"card",token:e.id}).then(p.sourceResponse);else if("source"===e.object){var r={source:e};p.sourceResponse(r)}},closed:p.onClose()})},resetModal:function(){p.reset(),p.stripe_checkout_submit=!1},onClose:function(){p.unblock()},getOwnerDetails:function(){var e=a("#billing_first_name").length?a("#billing_first_name").val():wc_stripe_params.billing_first_name,r=a("#billing_last_name").length?a("#billing_last_name").val():wc_stripe_params.billing_last_name,t={owner:{name:"",address:{},email:"",phone:""}};return t.owner.name=e,t.owner.name=e&&r?e+" "+r:a("#stripe-payment-data").data("full-name"),t.owner.email=a("#billing_email").val(),t.owner.phone=a("#billing_phone").val(),(void 0===t.owner.phone||t.owner.phone.length<=0)&&delete t.owner.phone,(void 0===t.owner.email||t.owner.email.length<=0)&&(a("#stripe-payment-data").data("email").length?t.owner.email=a("#stripe-payment-data").data("email"):delete t.owner.email),(void 0===t.owner.name||t.owner.name.length<=0)&&delete t.owner.name,0<a("#billing_address_1").length?(t.owner.address.line1=a("#billing_address_1").val(),t.owner.address.line2=a("#billing_address_2").val(),t.owner.address.state=a("#billing_state").val(),t.owner.address.city=a("#billing_city").val(),t.owner.address.postal_code=a("#billing_postcode").val(),t.owner.address.country=a("#billing_country").val()):wc_stripe_params.billing_address_1&&(t.owner.address.line1=wc_stripe_params.billing_address_1,t.owner.address.line2=wc_stripe_params.billing_address_2,t.owner.address.state=wc_stripe_params.billing_state,t.owner.address.city=wc_stripe_params.billing_city,t.owner.address.postal_code=wc_stripe_params.billing_postcode,t.owner.address.country=wc_stripe_params.billing_country),t},createSource:function(){var e=p.getOwnerDetails(),r="card";if(p.isBancontactChosen()&&(r="bancontact"),p.isSepaChosen()&&(r="sepa_debit"),p.isIdealChosen()&&(r="ideal"),p.isSofortChosen()&&(r="sofort"),p.isGiropayChosen()&&(r="giropay"),p.isAlipayChosen()&&(r="alipay"),"card"===r)o.createSource(t,e).then(p.sourceResponse);else{switch(r){case"bancontact":case"giropay":case"ideal":case"sofort":case"alipay":e.amount=a("#stripe-"+r+"-payment-data").data("amount"),e.currency=a("#stripe-"+r+"-payment-data").data("currency"),e.redirect={return_url:wc_stripe_params.return_url},wc_stripe_params.statement_descriptor&&(e.statement_descriptor=wc_stripe_params.statement_descriptor)}switch(r){case"sepa_debit":e.currency=a("#stripe-"+r+"-payment-data").data("currency"),e.mandate={notification_method:wc_stripe_params.sepa_mandate_notification};break;case"ideal":e.ideal={bank:a("#stripe-ideal-bank").val()};break;case"alipay":e.currency=a("#stripe-"+r+"-payment-data").data("currency"),e.amount=a("#stripe-"+r+"-payment-data").data("amount");break;case"sofort":e.sofort={country:a("#billing_country").val()}}"sepa_debit"===(e.type=r)?o.createSource(c,e).then(p.sourceResponse):o.createSource(e).then(p.sourceResponse)}},sourceResponse:function(e){e.error?a(document.body).trigger("stripeError",e):"no"===wc_stripe_params.allow_prepaid_card&&"card"===e.source.type&&"prepaid"===e.source.card.funding?(e.error={message:wc_stripe_params.no_prepaid_card_msg},"yes"===wc_stripe_params.is_stripe_checkout?p.submitError('<ul class="woocommerce-error"><li>'+wc_stripe_params.no_prepaid_card_msg+"</li></ul>"):a(document.body).trigger("stripeError",e)):p.processStripeResponse(e.source)},processStripeResponse:function(e){p.reset(),p.form.append("<input type='hidden' class='stripe-source' name='stripe_source' value='"+e.id+"'/>"),a("form#add_payment_method").length&&a(p.form).off("submit",p.form.onSubmit),p.form.submit()},onSubmit:function(e){if(p.isStripeChosen()){if(p.isStripeSaveCardChosen()||p.hasSource()||p.hasToken())return a("form#add_payment_method").length?(e.preventDefault(),"yes"===wc_stripe_params.is_stripe_checkout&&p.isStripeModalNeeded()&&p.isStripeCardChosen()?p.openModal():(p.block(),p.createSource()),!1):void 0;if(e.preventDefault(),p.block(),"yes"===wc_stripe_params.is_stripe_checkout&&p.isStripeModalNeeded()&&p.isStripeCardChosen())return"yes"===wc_stripe_params.is_checkout||(p.openModal(),!1);if(p.isBancontactChosen()||p.isGiropayChosen()||p.isIdealChosen()||p.isAlipayChosen()||p.isSofortChosen()||p.isP24Chosen()||p.isEpsChosen()||p.isMultibancoChosen()){if(a("form#order_review").length)return a("form#order_review").off("submit",this.onSubmit),p.form.submit(),!1;if(a("form.woocommerce-checkout").length)return!0;if(a("form#add_payment_method").length)return a("form#add_payment_method").off("submit",this.onSubmit),p.form.submit(),!1}return p.createSource(),!1}},onCCFormChange:function(){p.reset()},reset:function(){a(".wc-stripe-error, .stripe-source, .stripe_token").remove(),"yes"===wc_stripe_params.is_stripe_checkout&&(p.stripe_submit=!1)},onSepaError:function(e){var r=p.getSelectedPaymentElement().parents("li").eq(0).find(".stripe-source-errors");e.error?(console.log(e.error.message),a(r).html('<ul class="woocommerce_error woocommerce-error wc-stripe-error"><li>'+e.error.message+"</li></ul>")):a(r).html("")},onError:function(e,r){var t=r.error.message,o=p.getSelectedPaymentElement().parents("li").eq(0).find(".stripe-source-errors");if(p.isSepaChosen()&&"invalid_owner_name"===r.error.code&&wc_stripe_params.hasOwnProperty(r.error.code)){var n='<ul class="woocommerce-error"><li>'+wc_stripe_params[r.error.code]+"</li></ul>";return p.submitError(n)}"invalid_request_error"!==r.error.type&&"api_connection_error"!==r.error.type&&"api_error"!==r.error.type&&"authentication_error"!==r.error.type&&"rate_limit_error"!==r.error.type||(t=wc_stripe_params.invalid_request_error),"card_error"===r.error.type&&wc_stripe_params.hasOwnProperty(r.error.code)&&(t=wc_stripe_params[r.error.code]),"validation_error"===r.error.type&&wc_stripe_params.hasOwnProperty(r.error.code)&&(t=wc_stripe_params[r.error.code]),p.reset(),a(".woocommerce-NoticeGroup-checkout").remove(),console.log(r.error.message),a(o).html('<ul class="woocommerce_error woocommerce-error wc-stripe-error"><li>'+t+"</li></ul>"),a(".wc-stripe-error").length&&a("html, body").animate({scrollTop:a(".wc-stripe-error").offset().top-200},200),p.unblock()},submitError:function(e){a(".woocommerce-NoticeGroup-checkout, .woocommerce-error, .woocommerce-message").remove(),p.form.prepend('<div class="woocommerce-NoticeGroup woocommerce-NoticeGroup-checkout">'+e+"</div>"),p.form.removeClass("processing").unblock(),p.form.find(".input-text, select, input:checkbox").blur();var r="";a("#add_payment_method").length&&(r=a("#add_payment_method")),a("#order_review").length&&(r=a("#order_review")),a("form.checkout").length&&(r=a("form.checkout")),r.length&&a("html, body").animate({scrollTop:r.offset().top-100},500),a(document.body).trigger("checkout_error"),p.unblock()}};p.init()});
1
+ jQuery(function(c){"use strict";try{var n=Stripe(wc_stripe_params.key,{betas:["payment_intent_beta_3"]})}catch(e){return void console.log(e)}var t,o,i,e=Object.keys(wc_stripe_params.elements_options).length?wc_stripe_params.elements_options:{},r=Object.keys(wc_stripe_params.sepa_elements_options).length?wc_stripe_params.sepa_elements_options:{},s=n.elements(e),a=s.create("iban",r),m={getAjaxURL:function(e){return wc_stripe_params.ajaxurl.toString().replace("%%endpoint%%","wc_stripe_"+e)},unmountElements:function(){"yes"===wc_stripe_params.inline_cc_form?t.unmount("#stripe-card-element"):(t.unmount("#stripe-card-element"),o.unmount("#stripe-exp-element"),i.unmount("#stripe-cvc-element"))},mountElements:function(){if(c("#stripe-card-element").length){if("yes"===wc_stripe_params.inline_cc_form)return t.mount("#stripe-card-element");t.mount("#stripe-card-element"),o.mount("#stripe-exp-element"),i.mount("#stripe-cvc-element")}},createElements:function(){var e={base:{iconColor:"#666EE8",color:"#31325F",fontSize:"15px","::placeholder":{color:"#CFD7E0"}}},r={focus:"focused",empty:"empty",invalid:"invalid"};e=wc_stripe_params.elements_styling?wc_stripe_params.elements_styling:e,r=wc_stripe_params.elements_classes?wc_stripe_params.elements_classes:r,"yes"===wc_stripe_params.inline_cc_form?(t=s.create("card",{style:e,hidePostalCode:!0})).addEventListener("change",function(e){m.onCCFormChange(),e.error&&c(document.body).trigger("stripeError",e)}):(t=s.create("cardNumber",{style:e,classes:r}),o=s.create("cardExpiry",{style:e,classes:r}),i=s.create("cardCvc",{style:e,classes:r}),t.addEventListener("change",function(e){m.onCCFormChange(),m.updateCardBrand(e.brand),e.error&&c(document.body).trigger("stripeError",e)}),o.addEventListener("change",function(e){m.onCCFormChange(),e.error&&c(document.body).trigger("stripeError",e)}),i.addEventListener("change",function(e){m.onCCFormChange(),e.error&&c(document.body).trigger("stripeError",e)})),"yes"===wc_stripe_params.is_checkout?c(document.body).on("updated_checkout",function(){t&&m.unmountElements(),m.mountElements(),c("#stripe-iban-element").length&&a.mount("#stripe-iban-element")}):(c("form#add_payment_method").length||c("form#order_review").length)&&(m.mountElements(),c("#stripe-iban-element").length&&a.mount("#stripe-iban-element"))},updateCardBrand:function(e){var r={visa:"stripe-visa-brand",mastercard:"stripe-mastercard-brand",amex:"stripe-amex-brand",discover:"stripe-discover-brand",diners:"stripe-diners-brand",jcb:"stripe-jcb-brand",unknown:"stripe-credit-card-brand"},t=c(".stripe-card-brand"),n="stripe-credit-card-brand";e in r&&(n=r[e]),c.each(r,function(e,r){t.removeClass(r)}),t.addClass(n)},init:function(){"yes"!==wc_stripe_params.is_change_payment_page&&"yes"!==wc_stripe_params.is_pay_for_order_page||c(document.body).trigger("wc-credit-card-form-init"),c("form.woocommerce-checkout").length&&(this.form=c("form.woocommerce-checkout")),c("form.woocommerce-checkout").on("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",this.onSubmit),c("form#order_review").length&&(this.form=c("form#order_review")),c("form#order_review, form#add_payment_method").on("submit",this.onSubmit),c("form#add_payment_method").length&&(this.form=c("form#add_payment_method")),c("form.woocommerce-checkout").on("change",this.reset),c(document).on("stripeError",this.onError).on("checkout_error",this.reset),a.on("change",this.onSepaError),m.createElements(),window.addEventListener("hashchange",m.onHashChange),m.maybeConfirmIntent()},isStripeChosen:function(){return c("#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_eps, #payment_method_stripe_multibanco").is(":checked")||c("#payment_method_stripe").is(":checked")&&"new"===c('input[name="wc-stripe-payment-token"]:checked').val()||c("#payment_method_stripe_sepa").is(":checked")&&"new"===c('input[name="wc-stripe-payment-token"]:checked').val()},isStripeSaveCardChosen:function(){return c("#payment_method_stripe").is(":checked")&&c('input[name="wc-stripe-payment-token"]').is(":checked")&&"new"!==c('input[name="wc-stripe-payment-token"]:checked').val()||c("#payment_method_stripe_sepa").is(":checked")&&c('input[name="wc-stripe_sepa-payment-token"]').is(":checked")&&"new"!==c('input[name="wc-stripe_sepa-payment-token"]:checked').val()},isStripeCardChosen:function(){return c("#payment_method_stripe").is(":checked")},isBancontactChosen:function(){return c("#payment_method_stripe_bancontact").is(":checked")},isGiropayChosen:function(){return c("#payment_method_stripe_giropay").is(":checked")},isIdealChosen:function(){return c("#payment_method_stripe_ideal").is(":checked")},isSofortChosen:function(){return c("#payment_method_stripe_sofort").is(":checked")},isAlipayChosen:function(){return c("#payment_method_stripe_alipay").is(":checked")},isSepaChosen:function(){return c("#payment_method_stripe_sepa").is(":checked")},isP24Chosen:function(){return c("#payment_method_stripe_p24").is(":checked")},isEpsChosen:function(){return c("#payment_method_stripe_eps").is(":checked")},isMultibancoChosen:function(){return c("#payment_method_stripe_multibanco").is(":checked")},hasSource:function(){return 0<c("input.stripe-source").length},isMobile:function(){return!!/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)},block:function(){m.isMobile()||m.form.block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},unblock:function(){m.form&&m.form.unblock()},getSelectedPaymentElement:function(){return c('.payment_methods input[name="payment_method"]:checked')},getOwnerDetails:function(){var e=c("#billing_first_name").length?c("#billing_first_name").val():wc_stripe_params.billing_first_name,r=c("#billing_last_name").length?c("#billing_last_name").val():wc_stripe_params.billing_last_name,t={name:"",address:{},email:"",phone:""};return t.name=e,t.name=e&&r?e+" "+r:c("#stripe-payment-data").data("full-name"),t.email=c("#billing_email").val(),t.phone=c("#billing_phone").val(),(void 0===t.phone||t.phone.length<=0)&&delete t.phone,(void 0===t.email||t.email.length<=0)&&(c("#stripe-payment-data").data("email").length?t.email=c("#stripe-payment-data").data("email"):delete t.email),(void 0===t.name||t.name.length<=0)&&delete t.name,0<c("#billing_address_1").length?(t.address.line1=c("#billing_address_1").val(),t.address.line2=c("#billing_address_2").val(),t.address.state=c("#billing_state").val(),t.address.city=c("#billing_city").val(),t.address.postal_code=c("#billing_postcode").val(),t.address.country=c("#billing_country").val()):wc_stripe_params.billing_address_1&&(t.address.line1=wc_stripe_params.billing_address_1,t.address.line2=wc_stripe_params.billing_address_2,t.address.state=wc_stripe_params.billing_state,t.address.city=wc_stripe_params.billing_city,t.address.postal_code=wc_stripe_params.billing_postcode,t.address.country=wc_stripe_params.billing_country),{owner:t}},createSource:function(){var e=m.getOwnerDetails();return m.isSepaChosen()?(e.currency=c("#stripe-sepa_debit-payment-data").data("currency"),e.mandate={notification_method:wc_stripe_params.sepa_mandate_notification},e.type="sepa_debit",n.createSource(a,e).then(m.sourceResponse)):n.createSource(t,e).then(m.sourceResponse)},sourceResponse:function(e){if(e.error)return c(document.body).trigger("stripeError",e);m.reset(),m.form.append(c('<input type="hidden" />').addClass("stripe-source").attr("name","stripe_source").val(e.source.id)),c("form#add_payment_method").length&&c(m.form).off("submit",m.form.onSubmit),m.form.submit()},onSubmit:function(){return!m.isStripeChosen()||(!(!m.isStripeSaveCardChosen()&&!m.hasSource())||(!!(m.isBancontactChosen()||m.isGiropayChosen()||m.isIdealChosen()||m.isAlipayChosen()||m.isSofortChosen()||m.isP24Chosen()||m.isEpsChosen()||m.isMultibancoChosen())||(m.block(),m.createSource(),!1)))},onCCFormChange:function(){m.reset()},reset:function(){c(".wc-stripe-error, .stripe-source").remove()},onSepaError:function(e){var r=m.getSelectedPaymentElement().parents("li").eq(0).find(".stripe-source-errors");if(!e.error)return c(r).html("");console.log(e.error.message),c(r).html('<ul class="woocommerce_error woocommerce-error wc-stripe-error"><li /></ul>'),c(r).find("li").text(e.error.message)},onError:function(e,r){var t,n=r.error.message,o=m.getSelectedPaymentElement().closest("li"),i=o.find(".woocommerce-SavedPaymentMethods-tokenInput");if(i.length){var s=i.filter(":checked");t=s.closest(".woocommerce-SavedPaymentMethods-new").length?c("#wc-stripe-cc-form .stripe-source-errors"):s.closest("li").find(".stripe-source-errors")}else t=o.find(".stripe-source-errors");if(m.isSepaChosen()&&"invalid_owner_name"===r.error.code&&wc_stripe_params.hasOwnProperty(r.error.code)){var a='<ul class="woocommerce-error"><li /></ul>';return a.find("li").text(wc_stripe_params[r.error.code]),m.submitError(a)}"invalid_request_error"!==r.error.type&&"api_connection_error"!==r.error.type&&"api_error"!==r.error.type&&"authentication_error"!==r.error.type&&"rate_limit_error"!==r.error.type||(n=wc_stripe_params.invalid_request_error),"card_error"===r.error.type&&wc_stripe_params.hasOwnProperty(r.error.code)&&(n=wc_stripe_params[r.error.code]),"validation_error"===r.error.type&&wc_stripe_params.hasOwnProperty(r.error.code)&&(n=wc_stripe_params[r.error.code]),m.reset(),c(".woocommerce-NoticeGroup-checkout").remove(),console.log(r.error.message),c(t).html('<ul class="woocommerce_error woocommerce-error wc-stripe-error"><li /></ul>'),c(t).find("li").text(n),c(".wc-stripe-error").length&&c("html, body").animate({scrollTop:c(".wc-stripe-error").offset().top-200},200),m.unblock(),c.unblockUI()},submitError:function(e){c(".woocommerce-NoticeGroup-checkout, .woocommerce-error, .woocommerce-message").remove(),m.form.prepend('<div class="woocommerce-NoticeGroup woocommerce-NoticeGroup-checkout">'+e+"</div>"),m.form.removeClass("processing").unblock(),m.form.find(".input-text, select, input:checkbox").blur();var r="";c("#add_payment_method").length&&(r=c("#add_payment_method")),c("#order_review").length&&(r=c("#order_review")),c("form.checkout").length&&(r=c("form.checkout")),r.length&&c("html, body").animate({scrollTop:r.offset().top-100},500),c(document.body).trigger("checkout_error"),m.unblock()},onHashChange:function(){var e=window.location.hash.match(/^#?confirm-pi-([^:]+):(.+)$/);if(e&&!(e.length<3)){var r=e[1],t=decodeURIComponent(e[2]);window.location.hash="",m.openIntentModal(r,t)}},maybeConfirmIntent:function(){if(c("#stripe-intent-id").length&&c("#stripe-intent-return").length){var e=c("#stripe-intent-id").val(),r=c("#stripe-intent-return").val();m.openIntentModal(e,r,!0)}},openIntentModal:function(e,r,t){n.handleCardPayment(e).then(function(e){if(e.error)throw e.error;"requires_capture"!==e.paymentIntent.status&&"succeeded"!==e.paymentIntent.status||(window.location=r)}).catch(function(e){if(t)return window.location=r;c(document.body).trigger("stripeError",{error:e}),m.form&&m.form.removeClass("processing"),c.get(r+"&is_ajax")})}};m.init()});
changelog.txt CHANGED
@@ -1,5 +1,12 @@
1
  *** Changelog ***
2
 
 
 
 
 
 
 
 
3
  = 4.1.16 - 2019-04-18 =
4
  * Deprecate - Warn about the future removal of the Modal Checkout option.
5
  * Tweak - WC 3.6 compatibility.
1
  *** Changelog ***
2
 
3
+ = 4.2.0 - 2019-05-29 =
4
+ * Update - Enable Payment Request buttons for Puerto Rico based stores.
5
+ * Update - Add support for Strong Customer Authentication (SCA) for user-initiated payments.
6
+ * Remove - Stripe Modal Checkout.
7
+ * Remove - 3D Secure settings are no longer available in the gateway settings. Use Stripe Radar instead.
8
+ * Fix - Display error messages only next to the chosen saved card.
9
+
10
  = 4.1.16 - 2019-04-18 =
11
  * Deprecate - Warn about the future removal of the Modal Checkout option.
12
  * Tweak - WC 3.6 compatibility.
includes/abstracts/abstract-wc-stripe-payment-gateway.php CHANGED
@@ -405,24 +405,13 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
405
  WC_Stripe_Logger::log( 'Processing response: ' . print_r( $response, true ) );
406
 
407
  $order_id = WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $order->id : $order->get_id();
408
-
409
  $captured = ( isset( $response->captured ) && $response->captured ) ? 'yes' : 'no';
410
 
411
  // Store charge data.
412
  WC_Stripe_Helper::is_wc_lt( '3.0' ) ? update_post_meta( $order_id, '_stripe_charge_captured', $captured ) : $order->update_meta_data( '_stripe_charge_captured', $captured );
413
 
414
- // Store other data such as fees.
415
- if ( isset( $response->balance_transaction ) && isset( $response->balance_transaction->fee ) ) {
416
- // Fees and Net needs to both come from Stripe to be accurate as the returned
417
- // values are in the local currency of the Stripe account, not from WC.
418
- $fee = ! empty( $response->balance_transaction->fee ) ? WC_Stripe_Helper::format_balance_fee( $response->balance_transaction, 'fee' ) : 0;
419
- $net = ! empty( $response->balance_transaction->net ) ? WC_Stripe_Helper::format_balance_fee( $response->balance_transaction, 'net' ) : 0;
420
- WC_Stripe_Helper::update_stripe_fee( $order, $fee );
421
- WC_Stripe_Helper::update_stripe_net( $order, $net );
422
-
423
- // Store currency stripe.
424
- $currency = ! empty( $response->balance_transaction->currency ) ? strtoupper( $response->balance_transaction->currency ) : null;
425
- WC_Stripe_Helper::update_stripe_currency( $order, $currency );
426
  }
427
 
428
  if ( 'yes' === $captured ) {
@@ -551,38 +540,6 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
551
  return $source_object;
552
  }
553
 
554
- /**
555
- * Checks if 3DS is required.
556
- *
557
- * @since 4.0.4
558
- * @since 4.1.0 Add filter and changed optional to recommended.
559
- * @param object $source_object
560
- * @return bool
561
- */
562
- public function is_3ds_required( $source_object ) {
563
- return apply_filters(
564
- 'wc_stripe_require_3ds',
565
- (
566
- $source_object && ! empty( $source_object->card ) ) &&
567
- ( 'card' === $source_object->type && 'required' === $source_object->card->three_d_secure ||
568
- ( $this->three_d_secure && 'recommended' === $source_object->card->three_d_secure )
569
- ),
570
- $source_object,
571
- $this->three_d_secure
572
- );
573
- }
574
-
575
- /**
576
- * Checks if card is 3DS.
577
- *
578
- * @since 4.0.4
579
- * @param object $source_object
580
- * @return bool
581
- */
582
- public function is_3ds_card( $source_object ) {
583
- return ( $source_object && 'three_d_secure' === $source_object->type );
584
- }
585
-
586
  /**
587
  * Checks if card is a prepaid card.
588
  *
@@ -617,34 +574,6 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
617
  return ( isset( $_POST[ 'wc-' . $payment_method . '-payment-token' ] ) && 'new' !== $_POST[ 'wc-' . $payment_method . '-payment-token' ] );
618
  }
619
 
620
- /**
621
- * Creates the 3DS source for charge.
622
- *
623
- * @since 4.0.0
624
- * @since 4.0.4 Add $return_url
625
- * @param object $order
626
- * @param object $source_object
627
- * @param string $return_url
628
- * @return mixed
629
- */
630
- public function create_3ds_source( $order, $source_object, $return_url = '' ) {
631
- $currency = WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $order->get_order_currency() : $order->get_currency();
632
- $order_id = WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $order->id : $order->get_id();
633
- $return_url = empty( $return_url ) ? $this->get_stripe_return_url( $order ) : $return_url;
634
-
635
- $post_data = array();
636
- $post_data['amount'] = WC_Stripe_Helper::get_stripe_amount( $order->get_total(), $currency );
637
- $post_data['currency'] = strtolower( $currency );
638
- $post_data['type'] = 'three_d_secure';
639
- $post_data['owner'] = $this->get_owner_details( $order );
640
- $post_data['three_d_secure'] = array( 'card' => $source_object->id );
641
- $post_data['redirect'] = array( 'return_url' => $return_url );
642
-
643
- WC_Stripe_Logger::log( 'Info: Begin creating 3DS source...' );
644
-
645
- return WC_Stripe_API::request( apply_filters( 'wc_stripe_3ds_source', $post_data, $order ), 'sources' );
646
- }
647
-
648
  /**
649
  * Get payment source. This can be a new token/source or existing WC token.
650
  * If user is logged in and/or has WC account, create an account on Stripe.
@@ -890,7 +819,7 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
890
  public function process_refund( $order_id, $amount = null, $reason = '' ) {
891
  $order = wc_get_order( $order_id );
892
 
893
- if ( ! $order || ! $order->get_transaction_id() ) {
894
  return false;
895
  }
896
 
@@ -899,9 +828,15 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
899
  if ( WC_Stripe_Helper::is_wc_lt( '3.0' ) ) {
900
  $order_currency = get_post_meta( $order_id, '_order_currency', true );
901
  $captured = get_post_meta( $order_id, '_stripe_charge_captured', true );
 
902
  } else {
903
  $order_currency = $order->get_currency();
904
  $captured = $order->get_meta( '_stripe_charge_captured', true );
 
 
 
 
 
905
  }
906
 
907
  if ( ! is_null( $amount ) ) {
@@ -919,13 +854,37 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
919
  );
920
  }
921
 
922
- $request['charge'] = $order->get_transaction_id();
923
-
924
- WC_Stripe_Logger::log( "Info: Beginning refund for order {$order->get_transaction_id()} for the amount of {$amount}" );
925
 
926
  $request = apply_filters( 'wc_stripe_refund_request', $request, $order );
927
 
928
- $response = WC_Stripe_API::request( $request, 'refunds' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
929
 
930
  if ( ! empty( $response->error ) ) {
931
  WC_Stripe_Logger::log( 'Error: ' . $response->error->message );
@@ -1060,4 +1019,180 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
1060
 
1061
  return false;
1062
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1063
  }
405
  WC_Stripe_Logger::log( 'Processing response: ' . print_r( $response, true ) );
406
 
407
  $order_id = WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $order->id : $order->get_id();
 
408
  $captured = ( isset( $response->captured ) && $response->captured ) ? 'yes' : 'no';
409
 
410
  // Store charge data.
411
  WC_Stripe_Helper::is_wc_lt( '3.0' ) ? update_post_meta( $order_id, '_stripe_charge_captured', $captured ) : $order->update_meta_data( '_stripe_charge_captured', $captured );
412
 
413
+ if ( isset( $response->balance_transaction ) ) {
414
+ $this->update_fees( $order, is_string( $response->balance_transaction ) ? $response->balance_transaction : $response->balance_transaction->id );
 
 
 
 
 
 
 
 
 
 
415
  }
416
 
417
  if ( 'yes' === $captured ) {
540
  return $source_object;
541
  }
542
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
543
  /**
544
  * Checks if card is a prepaid card.
545
  *
574
  return ( isset( $_POST[ 'wc-' . $payment_method . '-payment-token' ] ) && 'new' !== $_POST[ 'wc-' . $payment_method . '-payment-token' ] );
575
  }
576
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
577
  /**
578
  * Get payment source. This can be a new token/source or existing WC token.
579
  * If user is logged in and/or has WC account, create an account on Stripe.
819
  public function process_refund( $order_id, $amount = null, $reason = '' ) {
820
  $order = wc_get_order( $order_id );
821
 
822
+ if ( ! $order ) {
823
  return false;
824
  }
825
 
828
  if ( WC_Stripe_Helper::is_wc_lt( '3.0' ) ) {
829
  $order_currency = get_post_meta( $order_id, '_order_currency', true );
830
  $captured = get_post_meta( $order_id, '_stripe_charge_captured', true );
831
+ $charge_id = get_post_meta( $order_id, '_transaction_id', true );
832
  } else {
833
  $order_currency = $order->get_currency();
834
  $captured = $order->get_meta( '_stripe_charge_captured', true );
835
+ $charge_id = $order->get_transaction_id();
836
+ }
837
+
838
+ if ( ! $charge_id ) {
839
+ return false;
840
  }
841
 
842
  if ( ! is_null( $amount ) ) {
854
  );
855
  }
856
 
857
+ $request['charge'] = $charge_id;
858
+ WC_Stripe_Logger::log( "Info: Beginning refund for order {$charge_id} for the amount of {$amount}" );
 
859
 
860
  $request = apply_filters( 'wc_stripe_refund_request', $request, $order );
861
 
862
+ $intent = $this->get_intent_from_order( $order );
863
+ $intent_cancelled = false;
864
+ if ( $intent ) {
865
+ // If the order has a Payment Intent pending capture, then the Intent itself must be refunded (cancelled), not the Charge
866
+ if ( ! empty( $intent->error ) ) {
867
+ $response = $intent;
868
+ $intent_cancelled = true;
869
+ } elseif ( 'requires_capture' === $intent->status ) {
870
+ $result = WC_Stripe_API::request(
871
+ array(),
872
+ 'payment_intents/' . $intent->id . '/cancel'
873
+ );
874
+ $intent_cancelled = true;
875
+
876
+ if ( ! empty( $result->error ) ) {
877
+ $response = $result;
878
+ } else {
879
+ $charge = end( $result->charges->data );
880
+ $response = end( $charge->refunds->data );
881
+ }
882
+ }
883
+ }
884
+
885
+ if ( ! $intent_cancelled ) {
886
+ $response = WC_Stripe_API::request( $request, 'refunds' );
887
+ }
888
 
889
  if ( ! empty( $response->error ) ) {
890
  WC_Stripe_Logger::log( 'Error: ' . $response->error->message );
1019
 
1020
  return false;
1021
  }
1022
+
1023
+ /**
1024
+ * Create a new PaymentIntent and attempt to confirm it.
1025
+ *
1026
+ * @param WC_Order $order The order that is being paid for.
1027
+ * @param object $prepared_source The source that is used for the payment.
1028
+ * @return object An intent (that is either successful or requires an action) or an error.
1029
+ */
1030
+ public function create_and_confirm_intent( $order, $prepared_source ) {
1031
+ // The request for a charge contains metadata for the intent.
1032
+ $full_request = $this->generate_payment_request( $order, $prepared_source );
1033
+
1034
+ $request = array(
1035
+ 'source' => $prepared_source->source,
1036
+ 'amount' => WC_Stripe_Helper::get_stripe_amount( $order->get_total() ),
1037
+ 'currency' => strtolower( WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $order->get_order_currency() : $order->get_currency() ),
1038
+ 'description' => $full_request['description'],
1039
+ 'metadata' => $full_request['metadata'],
1040
+ 'statement_descriptor' => $full_request['statement_descriptor'],
1041
+ 'capture_method' => ( 'true' === $full_request['capture'] ) ? 'automatic' : 'manual',
1042
+ 'payment_method_types' => array(
1043
+ 'card',
1044
+ ),
1045
+ );
1046
+
1047
+ if ( $prepared_source->customer ) {
1048
+ $request['customer'] = $prepared_source->customer;
1049
+ }
1050
+
1051
+ // Create an intent that awaits an action.
1052
+ $intent = WC_Stripe_API::request( $request, 'payment_intents' );
1053
+ if ( ! empty( $intent->error ) ) {
1054
+ return $intent;
1055
+ }
1056
+
1057
+ $order_id = WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $order->id : $order->get_id();
1058
+ WC_Stripe_Logger::log( "Stripe PaymentIntent $intent->id initiated for order $order_id" );
1059
+
1060
+ // Try to confirm the intent & capture the charge (if 3DS is not required).
1061
+ $confirm_request = array(
1062
+ 'source' => $request['source'],
1063
+ );
1064
+ $confirmed_intent = WC_Stripe_API::request( $confirm_request, "payment_intents/$intent->id/confirm" );
1065
+
1066
+ if ( ! empty( $confirmed_intent->error ) ) {
1067
+ return $confirmed_intent;
1068
+ }
1069
+
1070
+ // Save the intent ID to the order.
1071
+ $this->save_intent_to_order( $order, $confirmed_intent );
1072
+
1073
+ // Save a note about the status of the intent.
1074
+ if ( 'succeeded' === $confirmed_intent->status ) {
1075
+ WC_Stripe_Logger::log( "Stripe PaymentIntent $intent->id succeeded for order $order_id" );
1076
+ } elseif ( 'requires_action' === $confirmed_intent->status ) {
1077
+ WC_Stripe_Logger::log( "Stripe PaymentIntent $intent->id requires authentication for order $order_id" );
1078
+ }
1079
+
1080
+ return $confirmed_intent;
1081
+ }
1082
+
1083
+ /**
1084
+ * Updates an existing intent with updated amount, source, and customer.
1085
+ *
1086
+ * @param object $intent The existing intent object.
1087
+ * @param WC_Order $order The order.
1088
+ * @param object $prepared_source Currently selected source.
1089
+ * @return object An updated intent.
1090
+ */
1091
+ public function update_existing_intent( $intent, $order, $prepared_source ) {
1092
+ $request = array();
1093
+
1094
+ if ( $prepared_source->source !== $intent->source ) {
1095
+ $request['source'] = $prepared_source->source;
1096
+ }
1097
+
1098
+ $new_amount = WC_Stripe_Helper::get_stripe_amount( $order->get_total() );
1099
+ if ( $intent->amount !== $new_amount ) {
1100
+ $request['amount'] = $new_amount;
1101
+ }
1102
+
1103
+ if ( $prepared_source->customer && $intent->customer !== $prepared_source->customer ) {
1104
+ $request['customer'] = $prepared_source->customer;
1105
+ }
1106
+
1107
+ if ( empty( $request ) ) {
1108
+ return $intent;
1109
+ }
1110
+
1111
+ $updated_intent = WC_Stripe_API::request( $request, "payment_intents/$intent->id" );
1112
+
1113
+ if ( 'requires_confirmation' === $updated_intent->status ) {
1114
+ return WC_Stripe_API::request( array(), "payment_intents/$intent->id/confirm" );
1115
+ } else {
1116
+ return $updated_intent;
1117
+ }
1118
+ }
1119
+
1120
+ /**
1121
+ * Saves intent to order.
1122
+ *
1123
+ * @since 3.2.0
1124
+ * @param WC_Order $order For to which the source applies.
1125
+ * @param stdClass $intent Payment intent information.
1126
+ */
1127
+ public function save_intent_to_order( $order, $intent ) {
1128
+ $order_id = WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $order->id : $order->get_id();
1129
+
1130
+ if ( WC_Stripe_Helper::is_wc_lt( '3.0' ) ) {
1131
+ update_post_meta( $order_id, '_stripe_intent_id', $intent->id );
1132
+ } else {
1133
+ $order->update_meta_data( '_stripe_intent_id', $intent->id );
1134
+ }
1135
+
1136
+ if ( is_callable( array( $order, 'save' ) ) ) {
1137
+ $order->save();
1138
+ }
1139
+ }
1140
+
1141
+ /**
1142
+ * Retrieves the payment intent, associated with an order.
1143
+ *
1144
+ * @since 4.2
1145
+ * @param WC_Order $order The order to retrieve an intent for.
1146
+ * @return obect|bool Either the intent object or `false`.
1147
+ */
1148
+ public function get_intent_from_order( $order ) {
1149
+ $order_id = WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $order->id : $order->get_id();
1150
+
1151
+ if ( WC_Stripe_Helper::is_wc_lt( '3.0' ) ) {
1152
+ $intent_id = get_post_meta( $order_id, '_stripe_intent_id', true );
1153
+ } else {
1154
+ $intent_id = $order->get_meta( '_stripe_intent_id' );
1155
+ }
1156
+
1157
+ if ( ! $intent_id ) {
1158
+ return false;
1159
+ }
1160
+
1161
+ return WC_Stripe_API::request( array(), "payment_intents/$intent_id", 'GET' );
1162
+ }
1163
+
1164
+ /**
1165
+ * Locks an order for payment intent processing for 5 minutes.
1166
+ *
1167
+ * @since 4.2
1168
+ * @param WC_Order $order The order that is being paid.
1169
+ * @param stdClass $intent The intent that is being processed.
1170
+ * @return bool A flag that indicates whether the order is already locked.
1171
+ */
1172
+ public function lock_order_payment( $order, $intent ) {
1173
+ $order_id = WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $order->id : $order->get_id();
1174
+ $transient_name = 'wc_stripe_processing_intent_' . $order_id;
1175
+ $processing = get_transient( $transient_name );
1176
+
1177
+ // Block the process if the same intent is already being handled.
1178
+ if ( $processing === $intent->id ) {
1179
+ return true;
1180
+ }
1181
+
1182
+ // Save the new intent as a transient, eventually overwriting another one.
1183
+ set_transient( $transient_name, $intent->id, 5 * MINUTE_IN_SECONDS );
1184
+
1185
+ return false;
1186
+ }
1187
+
1188
+ /**
1189
+ * Unlocks an order for processing by payment intents.
1190
+ *
1191
+ * @since 4.2
1192
+ * @param WC_Order $order The order that is being unlocked.
1193
+ */
1194
+ public function unlock_order_payment( $order ) {
1195
+ $order_id = WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $order->id : $order->get_id();
1196
+ delete_transient( 'wc_stripe_processing_intent_' . $order_id );
1197
+ }
1198
  }
includes/admin/class-wc-stripe-admin-notices.php CHANGED
@@ -102,6 +102,7 @@ class WC_Stripe_Admin_Notices {
102
  $show_style_notice = get_option( 'wc_stripe_show_style_notice' );
103
  $show_ssl_notice = get_option( 'wc_stripe_show_ssl_notice' );
104
  $show_keys_notice = get_option( 'wc_stripe_show_keys_notice' );
 
105
  $show_phpver_notice = get_option( 'wc_stripe_show_phpver_notice' );
106
  $show_wcver_notice = get_option( 'wc_stripe_show_wcver_notice' );
107
  $show_curl_notice = get_option( 'wc_stripe_show_curl_notice' );
@@ -111,13 +112,16 @@ class WC_Stripe_Admin_Notices {
111
  $test_secret_key = isset( $options['test_secret_key'] ) ? $options['test_secret_key'] : '';
112
  $live_pub_key = isset( $options['publishable_key'] ) ? $options['publishable_key'] : '';
113
  $live_secret_key = isset( $options['secret_key'] ) ? $options['secret_key'] : '';
114
- $checkout_enabled = isset( $options['stripe_checkout'] ) && 'yes' === $options['stripe_checkout'];
115
 
116
  if ( isset( $options['enabled'] ) && 'yes' === $options['enabled'] ) {
117
- if ( $checkout_enabled ) {
118
- $url = 'https://docs.woocommerce.com/document/stripe/modal-checkout';
119
- $message = sprintf( __( 'WooCommerce Stripe - Support for Stripe Modal Checkout will be ending soon. This will impact the appearance of your checkout. <a href="%1$s" target="_blank">Click here to learn more.</a>', 'woocommerce-gateway-stripe' ), $url );
120
- $this->add_admin_notice( 'legacy_checkout', 'notice notice-warning', $message );
 
 
 
121
  }
122
 
123
  if ( empty( $show_style_notice ) ) {
@@ -258,6 +262,9 @@ class WC_Stripe_Admin_Notices {
258
  case 'keys':
259
  update_option( 'wc_stripe_show_keys_notice', 'no' );
260
  break;
 
 
 
261
  case 'Alipay':
262
  update_option( 'wc_stripe_show_alipay_notice', 'no' );
263
  break;
102
  $show_style_notice = get_option( 'wc_stripe_show_style_notice' );
103
  $show_ssl_notice = get_option( 'wc_stripe_show_ssl_notice' );
104
  $show_keys_notice = get_option( 'wc_stripe_show_keys_notice' );
105
+ $show_3ds_notice = get_option( 'wc_stripe_show_3ds_notice' );
106
  $show_phpver_notice = get_option( 'wc_stripe_show_phpver_notice' );
107
  $show_wcver_notice = get_option( 'wc_stripe_show_wcver_notice' );
108
  $show_curl_notice = get_option( 'wc_stripe_show_curl_notice' );
112
  $test_secret_key = isset( $options['test_secret_key'] ) ? $options['test_secret_key'] : '';
113
  $live_pub_key = isset( $options['publishable_key'] ) ? $options['publishable_key'] : '';
114
  $live_secret_key = isset( $options['secret_key'] ) ? $options['secret_key'] : '';
115
+ $three_d_secure = isset( $options['three_d_secure'] ) && 'yes' === $options['three_d_secure'];
116
 
117
  if ( isset( $options['enabled'] ) && 'yes' === $options['enabled'] ) {
118
+ if ( empty( $show_3ds_notice ) && $three_d_secure ) {
119
+ $url = 'https://stripe.com/docs/payments/dynamic-3ds';
120
+
121
+ /* translators: 1) A URL that explains Stripe Radar. */
122
+ $message = __( 'WooCommerce Stripe - We see that you had the "Require 3D secure when applicable" setting turned on. This setting is not available here anymore, because it is now replaced by Stripe Radar. You can learn more about it <a href="%s">here</a>.', 'woocommerce-gateway-stripe' );
123
+
124
+ $this->add_admin_notice( '3ds', 'notice notice-warning', sprintf( $message, $url ), true );
125
  }
126
 
127
  if ( empty( $show_style_notice ) ) {
262
  case 'keys':
263
  update_option( 'wc_stripe_show_keys_notice', 'no' );
264
  break;
265
+ case '3ds':
266
+ update_option( 'wc_stripe_show_3ds_notice', 'no' );
267
+ break;
268
  case 'Alipay':
269
  update_option( 'wc_stripe_show_alipay_notice', 'no' );
270
  break;
includes/admin/stripe-settings.php CHANGED
@@ -91,36 +91,6 @@ return apply_filters(
91
  'default' => 'yes',
92
  'desc_tip' => true,
93
  ),
94
- 'three_d_secure' => array(
95
- 'title' => __( '3D Secure', 'woocommerce-gateway-stripe' ),
96
- 'label' => __( 'Require 3D Secure when applicable', 'woocommerce-gateway-stripe' ),
97
- 'type' => 'checkbox',
98
- 'description' => __( 'Some payment methods have 3D Secure feature. This is an extra security layer for your store. Choose how to handle payments when 3D Secure is recommended. Enabling would require customers to use 3D Secure when recommended.', 'woocommerce-gateway-stripe' ),
99
- 'default' => 'yes',
100
- 'desc_tip' => true,
101
- ),
102
- 'stripe_checkout' => array(
103
- 'title' => __( 'Stripe Modal Checkout', 'woocommerce-gateway-stripe' ),
104
- 'label' => __( 'Enable Stripe Checkout', 'woocommerce-gateway-stripe' ),
105
- 'type' => 'checkbox',
106
- 'description' => __( 'If enabled, this option shows a "pay" button and modal credit card form on the checkout, instead of credit card fields directly on the page. We recommend you leave this disabled and use the embedded form as that is the preferred method.', 'woocommerce-gateway-stripe' ),
107
- 'default' => 'no',
108
- 'desc_tip' => true,
109
- ),
110
- 'stripe_checkout_image' => array(
111
- 'title' => __( 'Stripe Checkout Image', 'woocommerce-gateway-stripe' ),
112
- 'description' => __( 'Optionally enter the URL to a 128x128px image of your brand or product. e.g. <code>https://yoursite.com/wp-content/uploads/2013/09/yourimage.jpg</code>', 'woocommerce-gateway-stripe' ),
113
- 'type' => 'text',
114
- 'default' => '',
115
- 'desc_tip' => true,
116
- ),
117
- 'stripe_checkout_description' => array(
118
- 'title' => __( 'Stripe Checkout Description', 'woocommerce-gateway-stripe' ),
119
- 'type' => 'text',
120
- 'description' => __( 'Shows a description of your store on Stripe Modal Checkout.', 'woocommerce-gateway-stripe' ),
121
- 'default' => '',
122
- 'desc_tip' => true,
123
- ),
124
  'payment_request' => array(
125
  'title' => __( 'Payment Request Buttons', 'woocommerce-gateway-stripe' ),
126
  /* translators: 1) br tag 2) opening anchor tag 3) closing anchor tag */
91
  'default' => 'yes',
92
  'desc_tip' => true,
93
  ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  'payment_request' => array(
95
  'title' => __( 'Payment Request Buttons', 'woocommerce-gateway-stripe' ),
96
  /* translators: 1) br tag 2) opening anchor tag 3) closing anchor tag */
includes/class-wc-gateway-stripe.php CHANGED
@@ -30,34 +30,6 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
30
  */
31
  public $statement_descriptor;
32
 
33
- /**
34
- * Checkout enabled
35
- *
36
- * @var bool
37
- */
38
- public $stripe_checkout;
39
-
40
- /**
41
- * Stripe Checkout description.
42
- *
43
- * @var string
44
- */
45
- public $stripe_checkout_description;
46
-
47
- /**
48
- * Require 3D Secure enabled
49
- *
50
- * @var bool
51
- */
52
- public $three_d_secure;
53
-
54
- /**
55
- * Credit card image
56
- *
57
- * @var string
58
- */
59
- public $stripe_checkout_image;
60
-
61
  /**
62
  * Should we store the users credit cards?
63
  *
@@ -142,25 +114,17 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
142
  $this->init_settings();
143
 
144
  // Get setting values.
145
- $this->title = $this->get_option( 'title' );
146
- $this->description = $this->get_option( 'description' );
147
- $this->enabled = $this->get_option( 'enabled' );
148
- $this->testmode = 'yes' === $this->get_option( 'testmode' );
149
- $this->inline_cc_form = 'yes' === $this->get_option( 'inline_cc_form' );
150
- $this->capture = 'yes' === $this->get_option( 'capture', 'yes' );
151
- $this->statement_descriptor = WC_Stripe_Helper::clean_statement_descriptor( $this->get_option( 'statement_descriptor' ) );
152
- $this->three_d_secure = 'yes' === $this->get_option( 'three_d_secure' );
153
- $this->stripe_checkout = 'yes' === $this->get_option( 'stripe_checkout' );
154
- $this->stripe_checkout_image = $this->get_option( 'stripe_checkout_image', '' );
155
- $this->stripe_checkout_description = $this->get_option( 'stripe_checkout_description' );
156
- $this->saved_cards = 'yes' === $this->get_option( 'saved_cards' );
157
- $this->secret_key = $this->testmode ? $this->get_option( 'test_secret_key' ) : $this->get_option( 'secret_key' );
158
- $this->publishable_key = $this->testmode ? $this->get_option( 'test_publishable_key' ) : $this->get_option( 'publishable_key' );
159
- $this->payment_request = 'yes' === $this->get_option( 'payment_request', 'yes' );
160
-
161
- if ( $this->stripe_checkout ) {
162
- $this->order_button_text = __( 'Continue to payment', 'woocommerce-gateway-stripe' );
163
- }
164
 
165
  WC_Stripe_API::set_secret_key( $this->secret_key );
166
 
@@ -171,8 +135,9 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
171
  add_action( 'woocommerce_admin_order_totals_after_total', array( $this, 'display_order_fee' ) );
172
  add_action( 'woocommerce_admin_order_totals_after_total', array( $this, 'display_order_payout' ), 20 );
173
  add_action( 'woocommerce_customer_save_address', array( $this, 'show_update_card_notice' ), 10, 2 );
174
- add_action( 'woocommerce_receipt_stripe', array( $this, 'stripe_checkout_receipt_page' ) );
175
- add_action( 'woocommerce_api_' . strtolower( get_class( $this ) ), array( $this, 'stripe_checkout_return_handler' ) );
 
176
 
177
  if ( WC_Stripe_Helper::is_pre_orders_exists() ) {
178
  $this->pre_orders = new WC_Stripe_Pre_Orders_Compat();
@@ -212,8 +177,8 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
212
  * Adds a notice for customer when they update their billing address.
213
  *
214
  * @since 4.1.0
215
- * @param int $user_id
216
- * @param array $load_address
217
  */
218
  public function show_update_card_notice( $user_id, $load_address ) {
219
  if ( ! $this->saved_cards || ! WC_Stripe_Payment_Tokens::customer_has_saved_methods( $user_id ) || 'billing' !== $load_address ) {
@@ -270,8 +235,8 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
270
  $lastname = '';
271
 
272
  // If paying from order, we need to get total from order not cart.
273
- if ( isset( $_GET['pay_for_order'] ) && ! empty( $_GET['key'] ) ) {
274
- $order = wc_get_order( wc_get_order_id_by_order_key( wc_clean( $_GET['key'] ) ) );
275
  $total = $order->get_total();
276
  $user_email = WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $order->billing_email : $order->get_billing_email();
277
  } else {
@@ -287,7 +252,7 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
287
  $firstname = $user->user_firstname;
288
  $lastname = $user->user_lastname;
289
 
290
- } elseif ( function_exists( 'wcs_order_contains_subscription' ) && isset( $_GET['change_payment_method'] ) ) {
291
  $pay_button_text = __( 'Change Payment Method', 'woocommerce-gateway-stripe' );
292
  $total = '';
293
  } else {
@@ -299,19 +264,13 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
299
  echo '<div
300
  id="stripe-payment-data"
301
  data-panel-label="' . esc_attr( $pay_button_text ) . '"
302
- data-description="' . esc_attr( wp_strip_all_tags( $this->stripe_checkout_description ) ) . '"
303
  data-email="' . esc_attr( $user_email ) . '"
304
- data-verify-zip="' . esc_attr( apply_filters( 'wc_stripe_checkout_verify_zip', false ) ? 'true' : 'false' ) . '"
305
- data-billing-address="' . esc_attr( apply_filters( 'wc_stripe_checkout_require_billing_address', false ) ? 'true' : 'false' ) . '"
306
- data-shipping-address="' . esc_attr( apply_filters( 'wc_stripe_checkout_require_shipping_address', false ) ? 'true' : 'false' ) . '"
307
  data-amount="' . esc_attr( WC_Stripe_Helper::get_stripe_amount( $total ) ) . '"
308
  data-name="' . esc_attr( $this->statement_descriptor ) . '"
309
  data-full-name="' . esc_attr( $firstname . ' ' . $lastname ) . '"
310
  data-currency="' . esc_attr( strtolower( get_woocommerce_currency() ) ) . '"
311
- data-image="' . esc_attr( $this->stripe_checkout_image ) . '"
312
- data-locale="' . esc_attr( apply_filters( 'wc_stripe_checkout_locale', $this->get_locale() ) ) . '"
313
- data-three-d-secure="' . esc_attr( $this->three_d_secure ? 'true' : 'false' ) . '"
314
- data-allow-remember-me="' . esc_attr( apply_filters( 'wc_stripe_allow_remember_me', true ) ? 'true' : 'false' ) . '">';
315
 
316
  if ( $this->testmode ) {
317
  /* translators: link to Stripe testing page */
@@ -320,24 +279,18 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
320
 
321
  $description = trim( $description );
322
 
323
- echo apply_filters( 'wc_stripe_description', wpautop( wp_kses_post( $description ) ), $this->id );
324
 
325
  if ( $display_tokenization ) {
326
  $this->tokenization_script();
327
  $this->saved_payment_methods();
328
  }
329
 
330
- if ( ! $this->stripe_checkout ) {
331
- $this->elements_form();
332
- }
333
 
334
- if ( apply_filters( 'wc_stripe_display_save_payment_method_checkbox', $display_tokenization ) && ! is_add_payment_method_page() && ! isset( $_GET['change_payment_method'] ) ) {
335
 
336
- if ( ! $this->stripe_checkout ) {
337
- $this->save_payment_method_checkbox();
338
- } elseif ( $this->stripe_checkout && isset( $_GET['pay_for_order'] ) && ! empty( $_GET['key'] ) ) {
339
- $this->save_payment_method_checkbox();
340
- }
341
  }
342
 
343
  do_action( 'wc_stripe_cards_payment_fields', $this->id );
@@ -429,7 +382,7 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
429
  * @version 4.0.0
430
  */
431
  public function payment_scripts() {
432
- if ( ! is_cart() && ! is_checkout() && ! isset( $_GET['pay_for_order'] ) && ! is_add_payment_method_page() && ! isset( $_GET['change_payment_method'] ) ) {
433
  return;
434
  }
435
 
@@ -455,9 +408,8 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
455
  $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
456
 
457
  wp_register_style( 'stripe_styles', plugins_url( 'assets/css/stripe-styles.css', WC_STRIPE_MAIN_FILE ), array(), WC_STRIPE_VERSION );
458
- wp_enqueue_style( 'stripe_styles' );
459
 
460
- wp_register_script( 'stripe_checkout', 'https://checkout.stripe.com/checkout.js', '', WC_STRIPE_VERSION, true );
461
  wp_register_script( 'stripe', 'https://js.stripe.com/v3/', '', '3.0', true );
462
  wp_register_script( 'woocommerce_stripe', plugins_url( 'assets/js/stripe' . $suffix . '.js', WC_STRIPE_MAIN_FILE ), array( 'jquery-payment', 'stripe' ), WC_STRIPE_VERSION, true );
463
 
@@ -468,8 +420,8 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
468
  );
469
 
470
  // If we're on the pay page we need to pass stripe.js the address of the order.
471
- if ( isset( $_GET['pay_for_order'] ) && 'true' === $_GET['pay_for_order'] ) {
472
- $order_id = wc_get_order_id_by_order_key( urldecode( $_GET['key'] ) );
473
  $order = wc_get_order( $order_id );
474
 
475
  if ( is_a( $order, 'WC_Order' ) ) {
@@ -484,20 +436,7 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
484
  }
485
  }
486
 
487
- $stripe_params['no_prepaid_card_msg'] = __( 'Sorry, we\'re not accepting prepaid cards at this time. Your credit card has not been charged. Please try with alternative payment method.', 'woocommerce-gateway-stripe' );
488
- $stripe_params['no_sepa_owner_msg'] = __( 'Please enter your IBAN account name.', 'woocommerce-gateway-stripe' );
489
- $stripe_params['no_sepa_iban_msg'] = __( 'Please enter your IBAN account number.', 'woocommerce-gateway-stripe' );
490
- $stripe_params['sepa_mandate_notification'] = apply_filters( 'wc_stripe_sepa_mandate_notification', 'email' );
491
- $stripe_params['allow_prepaid_card'] = apply_filters( 'wc_stripe_allow_prepaid_card', true ) ? 'yes' : 'no';
492
- $stripe_params['inline_cc_form'] = $this->inline_cc_form ? 'yes' : 'no';
493
- $stripe_params['stripe_checkout_require_billing_address'] = apply_filters( 'wc_stripe_checkout_require_billing_address', false ) ? 'yes' : 'no';
494
- $stripe_params['is_checkout'] = ( is_checkout() && empty( $_GET['pay_for_order'] ) ) ? 'yes' : 'no';
495
- $stripe_params['return_url'] = $this->get_stripe_return_url();
496
- $stripe_params['ajaxurl'] = WC_AJAX::get_endpoint( '%%endpoint%%' );
497
- $stripe_params['stripe_nonce'] = wp_create_nonce( '_wc_stripe_nonce' );
498