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
- $stripe_params['statement_descriptor'] = $this->statement_descriptor;
499
- $stripe_params['elements_options'] = apply_filters( 'wc_stripe_elements_options', array() );
500
- $stripe_params['sepa_elements_options'] = apply_filters(
501
  'wc_stripe_sepa_elements_options',
502
  array(
503
  'supportedCountries' => array( 'SEPA' ),
@@ -505,153 +444,128 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
505
  'style' => array( 'base' => array( 'fontSize' => '15px' ) ),
506
  )
507
  );
508
- $stripe_params['invalid_owner_name'] = __( 'Billing First Name and Last Name are required.', 'woocommerce-gateway-stripe' );
509
- $stripe_params['is_stripe_checkout'] = $this->stripe_checkout ? 'yes' : 'no';
510
- $stripe_params['is_change_payment_page'] = isset( $_GET['change_payment_method'] ) ? 'yes' : 'no';
511
- $stripe_params['is_add_payment_page'] = is_wc_endpoint_url( 'add-payment-method' ) ? 'yes' : 'no';
512
- $stripe_params['is_pay_for_order_page'] = is_wc_endpoint_url( 'order-pay' ) ? 'yes' : 'no';
513
- $stripe_params['elements_styling'] = apply_filters( 'wc_stripe_elements_styling', false );
514
- $stripe_params['elements_classes'] = apply_filters( 'wc_stripe_elements_classes', false );
515
-
516
- // merge localized messages to be use in JS
 
 
 
 
 
 
 
 
 
 
 
 
 
 
517
  $stripe_params = array_merge( $stripe_params, WC_Stripe_Helper::get_localized_messages() );
518
 
519
  wp_localize_script( 'woocommerce_stripe', 'wc_stripe_params', apply_filters( 'wc_stripe_params', $stripe_params ) );
520
- wp_localize_script( 'woocommerce_stripe_checkout', 'wc_stripe_params', apply_filters( 'wc_stripe_params', $stripe_params ) );
521
-
522
- if ( $this->stripe_checkout ) {
523
- wp_enqueue_script( 'stripe_checkout' );
524
- }
525
 
526
  $this->tokenization_script();
527
  wp_enqueue_script( 'woocommerce_stripe' );
528
  }
529
 
530
  /**
531
- * Add Stripe Checkout items to receipt page.
532
  *
533
- * @since 4.1.0
 
534
  */
535
- public function stripe_checkout_receipt_page( $order_id ) {
536
- if ( ! $this->stripe_checkout ) {
 
537
  return;
538
  }
539
 
540
- $user = wp_get_current_user();
541
- $total = WC()->cart->total;
542
- $user_email = '';
543
- $display_tokenization = $this->supports( 'tokenization' ) && $this->saved_cards;
544
-
545
- // If paying from order, we need to get total from order not cart.
546
- if ( ! empty( $_GET['key'] ) ) {
547
- $order = wc_get_order( wc_get_order_id_by_order_key( wc_clean( $_GET['key'] ) ) );
548
- $total = $order->get_total();
549
- $user_email = WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $order->billing_email : $order->get_billing_email();
550
- } else {
551
- if ( $user->ID ) {
552
- $user_email = get_user_meta( $user->ID, 'billing_email', true );
553
- $user_email = $user_email ? $user_email : $user->user_email;
554
- }
555
- }
556
-
557
- ob_start();
558
-
559
- do_action( 'wc_stripe_checkout_receipt_page_before_form' );
560
 
561
- echo '<form method="post" class="woocommerce-checkout" action="' . WC()->api_request_url( get_class( $this ) ) . '">';
562
- echo '<div
563
- id="stripe-payment-data"
564
- data-panel-label="' . esc_attr( apply_filters( 'wc_stripe_checkout_label', '' ) ) . '"
565
- data-description="' . esc_attr( wp_strip_all_tags( $this->stripe_checkout_description ) ) . '"
566
- data-email="' . esc_attr( $user_email ) . '"
567
- data-verify-zip="' . esc_attr( apply_filters( 'wc_stripe_checkout_verify_zip', false ) ? 'true' : 'false' ) . '"
568
- data-billing-address="' . esc_attr( apply_filters( 'wc_stripe_checkout_require_billing_address', false ) ? 'true' : 'false' ) . '"
569
- data-shipping-address="' . esc_attr( apply_filters( 'wc_stripe_checkout_require_shipping_address', false ) ? 'true' : 'false' ) . '"
570
- data-amount="' . esc_attr( WC_Stripe_Helper::get_stripe_amount( $total ) ) . '"
571
- data-name="' . esc_attr( $this->statement_descriptor ) . '"
572
- data-currency="' . esc_attr( strtolower( get_woocommerce_currency() ) ) . '"
573
- data-image="' . esc_attr( $this->stripe_checkout_image ) . '"
574
- data-locale="' . esc_attr( apply_filters( 'wc_stripe_checkout_locale', $this->get_locale() ) ) . '"
575
- data-three-d-secure="' . esc_attr( $this->three_d_secure ? 'true' : 'false' ) . '"
576
- data-allow-remember-me="' . esc_attr( apply_filters( 'wc_stripe_allow_remember_me', true ) ? 'true' : 'false' ) . '">';
577
- echo '<input type="hidden" name="order_id" value="' . esc_attr( $order_id ) . '" />';
578
- echo '<input type="hidden" name="stripe_checkout_order" value="yes" />';
579
-
580
- if (
581
- apply_filters( 'wc_stripe_display_save_payment_method_checkbox', $display_tokenization ) &&
582
- ( ! function_exists( 'wcs_order_contains_subscription' ) || ( function_exists( 'wcs_order_contains_subscription' ) && ! WC_Subscriptions_Cart::cart_contains_subscription() ) ) &&
583
- ( ! WC_Stripe_Helper::is_pre_orders_exists() || ( WC_Stripe_Helper::is_pre_orders_exists() && ! $this->pre_orders->is_pre_order( $order_id ) ) )
584
- ) {
585
- $this->save_payment_method_checkbox();
586
  }
587
 
588
- wp_nonce_field( 'stripe-checkout-process', 'stripe_checkout_process_nonce' );
589
-
590
- do_action( 'wc_stripe_checkout_receipt_page_before_form_submit' );
591
-
592
- echo '<button type="submit" class="wc-stripe-checkout-button">' . __( 'Place Order', 'woocommerce-gateway-stripe' ) . '</button>';
593
-
594
- do_action( 'wc_stripe_checkout_receipt_page_after_form_submit' );
595
-
596
- echo '</form>';
597
-
598
- do_action( 'wc_stripe_checkout_receipt_page_after_form' );
599
-
600
- echo '</div>';
601
-
602
- ob_end_flush();
603
  }
604
 
605
  /**
606
- * Handles the return from processing the payment.
607
  *
608
- * @since 4.1.0
 
 
609
  */
610
- public function stripe_checkout_return_handler() {
611
- if ( ! $this->stripe_checkout ) {
612
- return;
 
613
  }
 
614
 
615
- if ( ! wp_verify_nonce( $_POST['stripe_checkout_process_nonce'], 'stripe-checkout-process' ) ) {
616
- return;
 
 
 
 
 
 
 
 
 
617
  }
618
 
619
- $order_id = wc_clean( $_POST['order_id'] );
620
- $order = wc_get_order( $order_id );
621
-
622
- do_action( 'wc_stripe_checkout_return_handler', $order );
623
-
624
- if ( WC_Stripe_Helper::is_pre_orders_exists() && $this->pre_orders->is_pre_order( $order_id ) && WC_Pre_Orders_Order::order_requires_payment_tokenization( $order_id ) ) {
625
- $result = $this->pre_orders->process_pre_order( $order_id );
626
  } else {
627
- $result = $this->process_payment( $order_id );
 
 
628
  }
629
 
630
- if ( 'success' === $result['result'] ) {
631
- wp_redirect( $result['redirect'] );
632
- exit;
633
- }
634
-
635
- // Redirects back to pay order page.
636
- wp_safe_redirect( $order->get_checkout_payment_url( true ) );
637
- exit;
638
  }
639
 
640
  /**
641
- * Checks if we need to redirect for Stripe Checkout.
642
  *
643
- * @since 4.1.0
644
- * @return bool
 
645
  */
646
- public function maybe_redirect_stripe_checkout() {
647
- $is_payment_request = ( isset( $_POST ) && isset( $_POST['payment_request_type'] ) );
 
 
 
648
 
649
- return (
650
- $this->stripe_checkout &&
651
- ! isset( $_POST['stripe_checkout_order'] ) &&
652
- ! $this->is_using_saved_payment_method() &&
653
- ! is_wc_endpoint_url( 'order-pay' ) &&
654
- ! $is_payment_request
655
  );
656
  }
657
 
@@ -663,179 +577,89 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
663
  * @param int $order_id Reference.
664
  * @param bool $retry Should we retry on fail.
665
  * @param bool $force_save_source Force save the payment source.
666
- * @param mix $previous_error Any error message from previous request.
667
  *
668
  * @throws Exception If payment will not be accepted.
669
- *
670
  * @return array|void
671
  */
672
  public function process_payment( $order_id, $retry = true, $force_save_source = false, $previous_error = false ) {
673
  try {
674
  $order = wc_get_order( $order_id );
675
 
676
- if ( $this->maybe_redirect_stripe_checkout() ) {
677
- WC_Stripe_Logger::log( sprintf( 'Redirecting to Stripe Checkout page for order %s', $order_id ) );
678
-
679
- return array(
680
- 'result' => 'success',
681
- 'redirect' => $order->get_checkout_payment_url( true ),
682
- );
683
- }
684
-
685
  if ( $this->maybe_process_pre_orders( $order_id ) ) {
686
  return $this->pre_orders->process_pre_order( $order_id );
687
  }
688
 
689
- // This comes from the create account checkbox in the checkout page.
690
- $create_account = ! empty( $_POST['createaccount'] ) ? true : false;
691
-
692
- if ( $create_account ) {
693
- $new_customer_id = WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $order->customer_user : $order->get_customer_id();
694
- $new_stripe_customer = new WC_Stripe_Customer( $new_customer_id );
695
- $new_stripe_customer->create_customer();
696
- }
697
 
698
  $prepared_source = $this->prepare_source( get_current_user_id(), $force_save_source );
699
 
700
- // Check if we don't allow prepaid credit cards.
701
- if ( ! apply_filters( 'wc_stripe_allow_prepaid_card', true ) && $this->is_prepaid_card( $prepared_source->source_object ) ) {
702
- $localized_message = __( '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' );
703
- throw new WC_Stripe_Exception( print_r( $prepared_source->source_object, true ), $localized_message );
704
- }
705
 
706
- if ( empty( $prepared_source->source ) ) {
707
- $localized_message = __( 'Payment processing failed. Please retry.', 'woocommerce-gateway-stripe' );
708
- throw new WC_Stripe_Exception( print_r( $prepared_source, true ), $localized_message );
709
  }
710
 
711
- $this->save_source_to_order( $order, $prepared_source );
 
712
 
713
- // Result from Stripe API request.
714
- $response = null;
715
 
716
- if ( $order->get_total() > 0 ) {
717
- // This will throw exception if not valid.
718
- $this->validate_minimum_order_amount( $order );
 
 
 
 
719
 
720
- /*
721
- * Check if card 3DS is required or optional with 3DS setting.
722
- * Will need to first create 3DS source and require redirection
723
- * for customer to login to their credit card company.
724
- * Note that if we need to save source, the original source must be first
725
- * attached to a customer in Stripe before it can be charged.
726
- */
727
- if ( $this->is_3ds_required( $prepared_source->source_object ) ) {
728
- $response = $this->create_3ds_source( $order, $prepared_source->source_object );
729
 
730
- if ( ! empty( $response->error ) ) {
731
- $localized_message = $response->error->message;
 
 
732
 
733
- $order->add_order_note( $localized_message );
 
734
 
735
- throw new WC_Stripe_Exception( print_r( $response, true ), $localized_message );
736
- }
 
737
 
738
- // Update order meta with 3DS source.
739
- if ( WC_Stripe_Helper::is_wc_lt( '3.0' ) ) {
740
- update_post_meta( $order_id, '_stripe_source_id', $response->id );
741
- } else {
742
- $order->update_meta_data( '_stripe_source_id', $response->id );
743
- $order->save();
744
- }
745
-
746
- /*
747
- * Make sure after creating 3DS object it is in pending status
748
- * before redirecting.
749
- */
750
- if ( 'pending' === $response->redirect->status ) {
751
- WC_Stripe_Logger::log( 'Info: Redirecting to 3DS...' );
752
 
753
  return array(
754
  'result' => 'success',
755
- 'redirect' => esc_url_raw( $response->redirect->url ),
756
  );
757
- } elseif ( 'not_required' === $response->redirect->status && 'chargeable' === $response->status ) {
758
- // Override the original source object with 3DS.
759
- $prepared_source->source_object = $response;
760
- $prepared_source->source = $response->id;
761
- }
762
- }
763
-
764
- WC_Stripe_Logger::log( "Info: Begin processing payment for order $order_id for the amount of {$order->get_total()}" );
765
-
766
- /* If we're doing a retry and source is chargeable, we need to pass
767
- * a different idempotency key and retry for success.
768
- */
769
- if ( $this->need_update_idempotency_key( $prepared_source->source_object, $previous_error ) ) {
770
- add_filter( 'wc_stripe_idempotency_key', array( $this, 'change_idempotency_key' ), 10, 2 );
771
- }
772
-
773
- // Make the request.
774
- $response = WC_Stripe_API::request( $this->generate_payment_request( $order, $prepared_source ) );
775
-
776
- if ( ! empty( $response->error ) ) {
777
- // Customer param wrong? The user may have been deleted on stripe's end. Remove customer_id. Can be retried without.
778
- if ( $this->is_no_such_customer_error( $response->error ) ) {
779
- if ( WC_Stripe_Helper::is_wc_lt( '3.0' ) ) {
780
- delete_user_meta( $order->customer_user, '_stripe_customer_id' );
781
- delete_post_meta( $order_id, '_stripe_customer_id' );
782
- } else {
783
- delete_user_meta( $order->get_customer_id(), '_stripe_customer_id' );
784
- $order->delete_meta_data( '_stripe_customer_id' );
785
- $order->save();
786
- }
787
- }
788
-
789
- if ( $this->is_no_such_token_error( $response->error ) && $prepared_source->token_id ) {
790
- // Source param wrong? The CARD may have been deleted on stripe's end. Remove token and show message.
791
- $wc_token = WC_Payment_Tokens::get( $prepared_source->token_id );
792
- $wc_token->delete();
793
- $localized_message = __( 'This card is no longer available and has been removed.', 'woocommerce-gateway-stripe' );
794
- $order->add_order_note( $localized_message );
795
- throw new WC_Stripe_Exception( print_r( $response, true ), $localized_message );
796
- }
797
-
798
- // We want to retry.
799
- if ( $this->is_retryable_error( $response->error ) ) {
800
- if ( $retry ) {
801
- // Don't do anymore retries after this.
802
- if ( 5 <= $this->retry_interval ) {
803
- return $this->process_payment( $order_id, false, $force_save_source, $response->error );
804
- }
805
-
806
- sleep( $this->retry_interval );
807
-
808
- $this->retry_interval++;
809
-
810
- return $this->process_payment( $order_id, true, $force_save_source, $response->error );
811
- } else {
812
- $localized_message = __( 'Sorry, we are unable to process your payment at this time. Please retry later.', 'woocommerce-gateway-stripe' );
813
- $order->add_order_note( $localized_message );
814
- throw new WC_Stripe_Exception( print_r( $response, true ), $localized_message );
815
- }
816
- }
817
-
818
- $localized_messages = WC_Stripe_Helper::get_localized_messages();
819
-
820
- if ( 'card_error' === $response->error->type ) {
821
- $localized_message = isset( $localized_messages[ $response->error->code ] ) ? $localized_messages[ $response->error->code ] : $response->error->message;
822
  } else {
823
- $localized_message = isset( $localized_messages[ $response->error->type ] ) ? $localized_messages[ $response->error->type ] : $response->error->message;
824
- }
825
-
826
- $order->add_order_note( $localized_message );
 
827
 
828
- throw new WC_Stripe_Exception( print_r( $response, true ), $localized_message );
 
 
 
 
 
829
  }
830
-
831
- do_action( 'wc_gateway_stripe_process_payment', $response, $order );
832
-
833
- // Process valid response.
834
- $this->process_response( $response, $order );
835
- } else {
836
- $order->payment_complete();
837
  }
838
 
 
 
 
839
  // Remove cart.
840
  WC()->cart->empty_cart();
841
 
@@ -866,7 +690,7 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
866
  *
867
  * @since 4.1.0
868
  *
869
- * @param int $order_id
870
  */
871
  public function display_order_fee( $order_id ) {
872
  if ( apply_filters( 'wc_stripe_hide_display_order_fee', false, $order_id ) ) {
@@ -886,12 +710,12 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
886
 
887
  <tr>
888
  <td class="label stripe-fee">
889
- <?php echo wc_help_tip( __( 'This represents the fee Stripe collects for the transaction.', 'woocommerce-gateway-stripe' ) ); ?>
890
  <?php esc_html_e( 'Stripe Fee:', 'woocommerce-gateway-stripe' ); ?>
891
  </td>
892
  <td width="1%"></td>
893
  <td class="total">
894
- -&nbsp;<?php echo wc_price( $fee, array( 'currency' => $currency ) ); ?>
895
  </td>
896
  </tr>
897
 
@@ -903,7 +727,7 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
903
  *
904
  * @since 4.1.0
905
  *
906
- * @param int $order_id
907
  */
908
  public function display_order_payout( $order_id ) {
909
  if ( apply_filters( 'wc_stripe_hide_display_order_payout', false, $order_id ) ) {
@@ -923,15 +747,252 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
923
 
924
  <tr>
925
  <td class="label stripe-payout">
926
- <?php echo wc_help_tip( __( 'This represents the net total that will be credited to your Stripe bank account. This may be in the currency that is set in your Stripe account.', 'woocommerce-gateway-stripe' ) ); ?>
927
  <?php esc_html_e( 'Stripe Payout:', 'woocommerce-gateway-stripe' ); ?>
928
  </td>
929
  <td width="1%"></td>
930
  <td class="total">
931
- <?php echo wc_price( $net, array( 'currency' => $currency ) ); ?>
932
  </td>
933
  </tr>
934
 
935
  <?php
936
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
937
  }
30
  */
31
  public $statement_descriptor;
32
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  /**
34
  * Should we store the users credit cards?
35
  *
114
  $this->init_settings();
115
 
116
  // Get setting values.
117
+ $this->title = $this->get_option( 'title' );
118
+ $this->description = $this->get_option( 'description' );
119
+ $this->enabled = $this->get_option( 'enabled' );
120
+ $this->testmode = 'yes' === $this->get_option( 'testmode' );
121
+ $this->inline_cc_form = 'yes' === $this->get_option( 'inline_cc_form' );
122
+ $this->capture = 'yes' === $this->get_option( 'capture', 'yes' );
123
+ $this->statement_descriptor = WC_Stripe_Helper::clean_statement_descriptor( $this->get_option( 'statement_descriptor' ) );
124
+ $this->saved_cards = 'yes' === $this->get_option( 'saved_cards' );
125
+ $this->secret_key = $this->testmode ? $this->get_option( 'test_secret_key' ) : $this->get_option( 'secret_key' );
126
+ $this->publishable_key = $this->testmode ? $this->get_option( 'test_publishable_key' ) : $this->get_option( 'publishable_key' );
127
+ $this->payment_request = 'yes' === $this->get_option( 'payment_request', 'yes' );
 
 
 
 
 
 
 
 
128
 
129
  WC_Stripe_API::set_secret_key( $this->secret_key );
130
 
135
  add_action( 'woocommerce_admin_order_totals_after_total', array( $this, 'display_order_fee' ) );
136
  add_action( 'woocommerce_admin_order_totals_after_total', array( $this, 'display_order_payout' ), 20 );
137
  add_action( 'woocommerce_customer_save_address', array( $this, 'show_update_card_notice' ), 10, 2 );
138
+ add_filter( 'woocommerce_available_payment_gateways', array( $this, 'prepare_order_pay_page' ) );
139
+ add_action( 'woocommerce_account_view-order_endpoint', array( $this, 'check_intent_status_on_order_page' ), 1 );
140
+ add_filter( 'woocommerce_payment_successful_result', array( $this, 'modify_successful_payment_result' ), 99999, 2 );
141
 
142
  if ( WC_Stripe_Helper::is_pre_orders_exists() ) {
143
  $this->pre_orders = new WC_Stripe_Pre_Orders_Compat();
177
  * Adds a notice for customer when they update their billing address.
178
  *
179
  * @since 4.1.0
180
+ * @param int $user_id The ID of the current user.
181
+ * @param string $load_address The address to load.
182
  */
183
  public function show_update_card_notice( $user_id, $load_address ) {
184
  if ( ! $this->saved_cards || ! WC_Stripe_Payment_Tokens::customer_has_saved_methods( $user_id ) || 'billing' !== $load_address ) {
235
  $lastname = '';
236
 
237
  // If paying from order, we need to get total from order not cart.
238
+ if ( isset( $_GET['pay_for_order'] ) && ! empty( $_GET['key'] ) ) { // wpcs: csrf ok.
239
+ $order = wc_get_order( wc_get_order_id_by_order_key( wc_clean( $_GET['key'] ) ) ); // wpcs: csrf ok, sanitization ok.
240
  $total = $order->get_total();
241
  $user_email = WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $order->billing_email : $order->get_billing_email();
242
  } else {
252
  $firstname = $user->user_firstname;
253
  $lastname = $user->user_lastname;
254
 
255
+ } elseif ( function_exists( 'wcs_order_contains_subscription' ) && isset( $_GET['change_payment_method'] ) ) { // wpcs: csrf ok.
256
  $pay_button_text = __( 'Change Payment Method', 'woocommerce-gateway-stripe' );
257
  $total = '';
258
  } else {
264
  echo '<div
265
  id="stripe-payment-data"
266
  data-panel-label="' . esc_attr( $pay_button_text ) . '"
 
267
  data-email="' . esc_attr( $user_email ) . '"
 
 
 
268
  data-amount="' . esc_attr( WC_Stripe_Helper::get_stripe_amount( $total ) ) . '"
269
  data-name="' . esc_attr( $this->statement_descriptor ) . '"
270
  data-full-name="' . esc_attr( $firstname . ' ' . $lastname ) . '"
271
  data-currency="' . esc_attr( strtolower( get_woocommerce_currency() ) ) . '"
272
+ data-allow-remember-me="' . esc_attr( apply_filters( 'wc_stripe_allow_remember_me', true ) ? 'true' : 'false' ) . '"
273
+ >';
 
 
274
 
275
  if ( $this->testmode ) {
276
  /* translators: link to Stripe testing page */
279
 
280
  $description = trim( $description );
281
 
282
+ echo apply_filters( 'wc_stripe_description', wpautop( wp_kses_post( $description ) ), $this->id ); // wpcs: xss ok.
283
 
284
  if ( $display_tokenization ) {
285
  $this->tokenization_script();
286
  $this->saved_payment_methods();
287
  }
288
 
289
+ $this->elements_form();
 
 
290
 
291
+ if ( apply_filters( 'wc_stripe_display_save_payment_method_checkbox', $display_tokenization ) && ! is_add_payment_method_page() && ! isset( $_GET['change_payment_method'] ) ) { // wpcs: csrf ok.
292
 
293
+ $this->save_payment_method_checkbox();
 
 
 
 
294
  }
295
 
296
  do_action( 'wc_stripe_cards_payment_fields', $this->id );
382
  * @version 4.0.0
383
  */
384
  public function payment_scripts() {
385
+ if ( ! is_product() && ! is_cart() && ! is_checkout() && ! isset( $_GET['pay_for_order'] ) && ! is_add_payment_method_page() && ! isset( $_GET['change_payment_method'] ) ) { // wpcs: csrf ok.
386
  return;
387
  }
388
 
408
  $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
409
 
410
  wp_register_style( 'stripe_styles', plugins_url( 'assets/css/stripe-styles.css', WC_STRIPE_MAIN_FILE ), array(), WC_STRIPE_VERSION );
411
+ wp_enqueue_style( 'stripe_styles' );
412
 
 
413
  wp_register_script( 'stripe', 'https://js.stripe.com/v3/', '', '3.0', true );
414
  wp_register_script( 'woocommerce_stripe', plugins_url( 'assets/js/stripe' . $suffix . '.js', WC_STRIPE_MAIN_FILE ), array( 'jquery-payment', 'stripe' ), WC_STRIPE_VERSION, true );
415
 
420
  );
421
 
422
  // If we're on the pay page we need to pass stripe.js the address of the order.
423
+ if ( isset( $_GET['pay_for_order'] ) && 'true' === $_GET['pay_for_order'] ) { // wpcs: csrf ok.
424
+ $order_id = wc_get_order_id_by_order_key( urldecode( $_GET['key'] ) ); // wpcs: csrf ok, sanitization ok, xss ok.
425
  $order = wc_get_order( $order_id );
426
 
427
  if ( is_a( $order, 'WC_Order' ) ) {
436
  }
437
  }
438
 
439
+ $sepa_elements_options = apply_filters(
 
 
 
 
 
 
 
 
 
 
 
 
 
440
  'wc_stripe_sepa_elements_options',
441
  array(
442
  'supportedCountries' => array( 'SEPA' ),
444
  'style' => array( 'base' => array( 'fontSize' => '15px' ) ),
445
  )
446
  );
447
+
448
+ $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' );
449
+ $stripe_params['no_sepa_owner_msg'] = __( 'Please enter your IBAN account name.', 'woocommerce-gateway-stripe' );
450
+ $stripe_params['no_sepa_iban_msg'] = __( 'Please enter your IBAN account number.', 'woocommerce-gateway-stripe' );
451
+ $stripe_params['payment_intent_error'] = __( 'We couldn\'t initiate the payment. Please try again.', 'woocommerce-gateway-stripe' );
452
+ $stripe_params['sepa_mandate_notification'] = apply_filters( 'wc_stripe_sepa_mandate_notification', 'email' );
453
+ $stripe_params['allow_prepaid_card'] = apply_filters( 'wc_stripe_allow_prepaid_card', true ) ? 'yes' : 'no';
454
+ $stripe_params['inline_cc_form'] = $this->inline_cc_form ? 'yes' : 'no';
455
+ $stripe_params['is_checkout'] = ( is_checkout() && empty( $_GET['pay_for_order'] ) ) ? 'yes' : 'no'; // wpcs: csrf ok.
456
+ $stripe_params['return_url'] = $this->get_stripe_return_url();
457
+ $stripe_params['ajaxurl'] = WC_AJAX::get_endpoint( '%%endpoint%%' );
458
+ $stripe_params['stripe_nonce'] = wp_create_nonce( '_wc_stripe_nonce' );
459
+ $stripe_params['statement_descriptor'] = $this->statement_descriptor;
460
+ $stripe_params['elements_options'] = apply_filters( 'wc_stripe_elements_options', array() );
461
+ $stripe_params['sepa_elements_options'] = $sepa_elements_options;
462
+ $stripe_params['invalid_owner_name'] = __( 'Billing First Name and Last Name are required.', 'woocommerce-gateway-stripe' );
463
+ $stripe_params['is_change_payment_page'] = isset( $_GET['change_payment_method'] ) ? 'yes' : 'no'; // wpcs: csrf ok.
464
+ $stripe_params['is_add_payment_page'] = is_wc_endpoint_url( 'add-payment-method' ) ? 'yes' : 'no';
465
+ $stripe_params['is_pay_for_order_page'] = is_wc_endpoint_url( 'order-pay' ) ? 'yes' : 'no';
466
+ $stripe_params['elements_styling'] = apply_filters( 'wc_stripe_elements_styling', false );
467
+ $stripe_params['elements_classes'] = apply_filters( 'wc_stripe_elements_classes', false );
468
+
469
+ // Merge localized messages to be use in JS.
470
  $stripe_params = array_merge( $stripe_params, WC_Stripe_Helper::get_localized_messages() );
471
 
472
  wp_localize_script( 'woocommerce_stripe', 'wc_stripe_params', apply_filters( 'wc_stripe_params', $stripe_params ) );
 
 
 
 
 
473
 
474
  $this->tokenization_script();
475
  wp_enqueue_script( 'woocommerce_stripe' );
476
  }
477
 
478
  /**
479
+ * Creates a new WC_Stripe_Customer if the visitor chooses to.
480
  *
481
+ * @since 4.2.0
482
+ * @param WC_Order $order The order that is being created.
483
  */
484
+ public function maybe_create_customer( $order ) {
485
+ // This comes from the create account checkbox in the checkout page.
486
+ if ( empty( $_POST['createaccount'] ) ) { // wpcs: csrf ok.
487
  return;
488
  }
489
 
490
+ $new_customer_id = WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $order->customer_user : $order->get_customer_id();
491
+ $new_stripe_customer = new WC_Stripe_Customer( $new_customer_id );
492
+ $new_stripe_customer->create_customer();
493
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
494
 
495
+ /**
496
+ * Checks if a source object represents a prepaid credit card and
497
+ * throws an exception if it is one, but that is not allowed.
498
+ *
499
+ * @since 4.2.0
500
+ * @param object $prepared_source The object with source details.
501
+ * @throws WC_Stripe_Exception An exception if the card is prepaid, but prepaid cards are not allowed.
502
+ */
503
+ public function maybe_disallow_prepaid_card( $prepared_source ) {
504
+ // Check if we don't allow prepaid credit cards.
505
+ if ( apply_filters( 'wc_stripe_allow_prepaid_card', true ) || ! $this->is_prepaid_card( $prepared_source->source_object ) ) {
506
+ return;
 
 
 
 
 
 
 
 
 
 
 
 
 
507
  }
508
 
509
+ $localized_message = __( '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' );
510
+ throw new WC_Stripe_Exception( print_r( $prepared_source->source_object, true ), $localized_message );
 
 
 
 
 
 
 
 
 
 
 
 
 
511
  }
512
 
513
  /**
514
+ * Checks whether a source exists.
515
  *
516
+ * @since 4.2.0
517
+ * @param object $prepared_source The source that should be verified.
518
+ * @throws WC_Stripe_Exception An exception if the source ID is missing.
519
  */
520
+ public function check_source( $prepared_source ) {
521
+ if ( empty( $prepared_source->source ) ) {
522
+ $localized_message = __( 'Payment processing failed. Please retry.', 'woocommerce-gateway-stripe' );
523
+ throw new WC_Stripe_Exception( print_r( $prepared_source, true ), $localized_message );
524
  }
525
+ }
526
 
527
+ /**
528
+ * Customer param wrong? The user may have been deleted on stripe's end. Remove customer_id. Can be retried without.
529
+ *
530
+ * @since 4.2.0
531
+ * @param object $error The error that was returned from Stripe's API.
532
+ * @param WC_Order $order The order those payment is being processed.
533
+ * @return bool A flag that indicates that the customer does not exist and should be removed.
534
+ */
535
+ public function maybe_remove_non_existent_customer( $error, $order ) {
536
+ if ( ! $this->is_no_such_customer_error( $error ) ) {
537
+ return false;
538
  }
539
 
540
+ if ( WC_Stripe_Helper::is_wc_lt( '3.0' ) ) {
541
+ delete_user_meta( $order->customer_user, '_stripe_customer_id' );
542
+ delete_post_meta( $order->get_id(), '_stripe_customer_id' );
 
 
 
 
543
  } else {
544
+ delete_user_meta( $order->get_customer_id(), '_stripe_customer_id' );
545
+ $order->delete_meta_data( '_stripe_customer_id' );
546
+ $order->save();
547
  }
548
 
549
+ return true;
 
 
 
 
 
 
 
550
  }
551
 
552
  /**
553
+ * Completes an order without a positive value.
554
  *
555
+ * @since 4.2.0
556
+ * @param WC_Order $order The order to complete.
557
+ * @return array Redirection data for `process_payment`.
558
  */
559
+ public function complete_free_order( $order ) {
560
+ $order->payment_complete();
561
+
562
+ // Remove cart.
563
+ WC()->cart->empty_cart();
564
 
565
+ // Return thank you page redirect.
566
+ return array(
567
+ 'result' => 'success',
568
+ 'redirect' => $this->get_return_url( $order ),
 
 
569
  );
570
  }
571
 
577
  * @param int $order_id Reference.
578
  * @param bool $retry Should we retry on fail.
579
  * @param bool $force_save_source Force save the payment source.
580
+ * @param mix $previous_error Any error message from previous request.
581
  *
582
  * @throws Exception If payment will not be accepted.
 
583
  * @return array|void
584
  */
585
  public function process_payment( $order_id, $retry = true, $force_save_source = false, $previous_error = false ) {
586
  try {
587
  $order = wc_get_order( $order_id );
588
 
589
+ // ToDo: `process_pre_order` saves the source to the order for a later payment.
590
+ // This might not work well with PaymentIntents.
 
 
 
 
 
 
 
591
  if ( $this->maybe_process_pre_orders( $order_id ) ) {
592
  return $this->pre_orders->process_pre_order( $order_id );
593
  }
594
 
595
+ $this->maybe_create_customer( $order );
 
 
 
 
 
 
 
596
 
597
  $prepared_source = $this->prepare_source( get_current_user_id(), $force_save_source );
598
 
599
+ $this->maybe_disallow_prepaid_card( $prepared_source );
600
+ $this->check_source( $prepared_source );
601
+ $this->save_source_to_order( $order, $prepared_source );
 
 
602
 
603
+ if ( 0 >= $order->get_total() ) {
604
+ return $this->complete_free_order( $order );
 
605
  }
606
 
607
+ // This will throw exception if not valid.
608
+ $this->validate_minimum_order_amount( $order );
609
 
610
+ WC_Stripe_Logger::log( "Info: Begin processing payment for order $order_id for the amount of {$order->get_total()}" );
 
611
 
612
+ $intent = $this->get_intent_from_order( $order );
613
+ if ( $intent ) {
614
+ $intent = $this->update_existing_intent( $intent, $order, $prepared_source );
615
+ } else {
616
+ $intent = $this->create_and_confirm_intent( $order, $prepared_source );
617
+ $response = $intent;
618
+ }
619
 
620
+ if ( ! empty( $response->error ) ) {
621
+ $this->maybe_remove_non_existent_customer( $response->error, $order );
 
 
 
 
 
 
 
622
 
623
+ // We want to retry.
624
+ if ( $this->is_retryable_error( $response->error ) ) {
625
+ return $this->retry_after_error( $response, $order, $retry, $force_save_source, $previous_error );
626
+ }
627
 
628
+ $this->throw_localized_message( $response, $order );
629
+ }
630
 
631
+ if ( ! empty( $intent ) ) {
632
+ // Use the last charge within the intent to proceed.
633
+ $response = end( $intent->charges->data );
634
 
635
+ // If the intent requires a 3DS flow, redirect to it.
636
+ if ( 'requires_action' === $intent->status ) {
637
+ if ( is_wc_endpoint_url( 'order-pay' ) ) {
638
+ $redirect_url = add_query_arg( 'wc-stripe-confirmation', 1, $order->get_checkout_payment_url( false ) );
 
 
 
 
 
 
 
 
 
 
639
 
640
  return array(
641
  'result' => 'success',
642
+ 'redirect' => $redirect_url,
643
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
644
  } else {
645
+ /**
646
+ * This URL contains only a hash, which will be sent to `checkout.js` where it will be set like this:
647
+ * `window.location = result.redirect`
648
+ * Once this redirect is sent to JS, the `onHashChange` function will execute `handleCardPayment`.
649
+ */
650
 
651
+ return array(
652
+ 'result' => 'success',
653
+ 'redirect' => $this->get_return_url( $order ),
654
+ 'intent_secret' => $intent->client_secret,
655
+ );
656
+ }
657
  }
 
 
 
 
 
 
 
658
  }
659
 
660
+ // Process valid response.
661
+ $this->process_response( $response, $order );
662
+
663
  // Remove cart.
664
  WC()->cart->empty_cart();
665
 
690
  *
691
  * @since 4.1.0
692
  *
693
+ * @param int $order_id The ID of the order.
694
  */
695
  public function display_order_fee( $order_id ) {
696
  if ( apply_filters( 'wc_stripe_hide_display_order_fee', false, $order_id ) ) {
710
 
711
  <tr>
712
  <td class="label stripe-fee">
713
+ <?php echo wc_help_tip( __( 'This represents the fee Stripe collects for the transaction.', 'woocommerce-gateway-stripe' ) ); // wpcs: xss ok. ?>
714
  <?php esc_html_e( 'Stripe Fee:', 'woocommerce-gateway-stripe' ); ?>
715
  </td>
716
  <td width="1%"></td>
717
  <td class="total">
718
+ -&nbsp;<?php echo wc_price( $fee, array( 'currency' => $currency ) ); // wpcs: xss ok. ?>
719
  </td>
720
  </tr>
721
 
727
  *
728
  * @since 4.1.0
729
  *
730
+ * @param int $order_id The ID of the order.
731
  */
732
  public function display_order_payout( $order_id ) {
733
  if ( apply_filters( 'wc_stripe_hide_display_order_payout', false, $order_id ) ) {
747
 
748
  <tr>
749
  <td class="label stripe-payout">
750
+ <?php echo wc_help_tip( __( 'This represents the net total that will be credited to your Stripe bank account. This may be in the currency that is set in your Stripe account.', 'woocommerce-gateway-stripe' ) ); // wpcs: xss ok. ?>
751
  <?php esc_html_e( 'Stripe Payout:', 'woocommerce-gateway-stripe' ); ?>
752
  </td>
753
  <td width="1%"></td>
754
  <td class="total">
755
+ <?php echo wc_price( $net, array( 'currency' => $currency ) ); // wpcs: xss ok. ?>
756
  </td>
757
  </tr>
758
 
759
  <?php
760
  }
761
+
762
+ /**
763
+ * Generates a localized message for an error, adds it as a note and throws it.
764
+ *
765
+ * @since 4.2.0
766
+ * @param stdClass $response The response from the Stripe API.
767
+ * @param WC_Order $order The order to add a note to.
768
+ * @throws WC_Stripe_Exception An exception with the right message.
769
+ */
770
+ public function throw_localized_message( $response, $order ) {
771
+ $localized_messages = WC_Stripe_Helper::get_localized_messages();
772
+
773
+ if ( 'card_error' === $response->error->type ) {
774
+ $localized_message = isset( $localized_messages[ $response->error->code ] ) ? $localized_messages[ $response->error->code ] : $response->error->message;
775
+ } else {
776
+ $localized_message = isset( $localized_messages[ $response->error->type ] ) ? $localized_messages[ $response->error->type ] : $response->error->message;
777
+ }
778
+
779
+ $order->add_order_note( $localized_message );
780
+
781
+ throw new WC_Stripe_Exception( print_r( $response, true ), $localized_message );
782
+ }
783
+
784
+ /**
785
+ * Retries the payment process once an error occured.
786
+ *
787
+ * @since 4.2.0
788
+ * @param object $response The response from the Stripe API.
789
+ * @param WC_Order $order An order that is being paid for.
790
+ * @param bool $retry A flag that indicates whether another retry should be attempted.
791
+ * @param bool $force_save_source Force save the payment source.
792
+ * @param mixed $previous_error Any error message from previous request.
793
+ * @throws WC_Stripe_Exception If the payment is not accepted.
794
+ * @return array|void
795
+ */
796
+ public function retry_after_error( $response, $order, $retry, $force_save_source, $previous_error ) {
797
+ if ( ! $retry ) {
798
+ $localized_message = __( 'Sorry, we are unable to process your payment at this time. Please retry later.', 'woocommerce-gateway-stripe' );
799
+ $order->add_order_note( $localized_message );
800
+ throw new WC_Stripe_Exception( print_r( $response, true ), $localized_message ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.
801
+ }
802
+
803
+ // Don't do anymore retries after this.
804
+ if ( 5 <= $this->retry_interval ) {
805
+ return $this->process_payment( $order->get_id(), false, $force_save_source, $response->error, $previous_error );
806
+ }
807
+
808
+ sleep( $this->retry_interval );
809
+ $this->retry_interval++;
810
+
811
+ return $this->process_payment( $order->get_id(), true, $force_save_source, $response->error, $previous_error );
812
+ }
813
+
814
+ /**
815
+ * Adds the necessary hooks to modify the "Pay for order" page in order to clean
816
+ * it up and prepare it for the Stripe PaymentIntents modal to confirm a payment.
817
+ *
818
+ * @since 4.2
819
+ * @param WC_Payment_Gateway[] $gateways A list of all available gateways.
820
+ * @return WC_Payment_Gateway[] Either the same list or an empty one in the right conditions.
821
+ */
822
+ public function prepare_order_pay_page( $gateways ) {
823
+ if ( ! is_wc_endpoint_url( 'order-pay' ) || ! isset( $_GET['wc-stripe-confirmation'] ) ) { // wpcs: csrf ok.
824
+ return $gateways;
825
+ }
826
+
827
+ add_filter( 'woocommerce_checkout_show_terms', '__return_false' );
828
+ add_filter( 'woocommerce_pay_order_button_html', '__return_false' );
829
+ add_filter( 'woocommerce_available_payment_gateways', array( $this, '__return_empty_array' ) );
830
+ add_filter( 'woocommerce_no_available_payment_methods_message', array( $this, 'change_no_available_methods_message' ) );
831
+ add_action( 'woocommerce_pay_order_after_submit', array( $this, 'render_payment_intent_inputs' ) );
832
+
833
+ return array();
834
+ }
835
+
836
+ /**
837
+ * Changes the text of the "No available methods" message to one that indicates
838
+ * the need for a PaymentIntent to be confirmed.
839
+ *
840
+ * @since 4.2
841
+ * @return string the new message.
842
+ */
843
+ public function change_no_available_methods_message() {
844
+ return wpautop( __( "Almost there!\n\nYour order has already been created, the only thing that still needs to be done is for you to authorize the payment with your bank.", 'woocommerce-gateway-stripe' ) );
845
+ }
846
+
847
+ /**
848
+ * Renders hidden inputs on the "Pay for Order" page in order to let Stripe handle PaymentIntents.
849
+ *
850
+ * @since 4.2
851
+ */
852
+ public function render_payment_intent_inputs() {
853
+ $order = wc_get_order( absint( get_query_var( 'order-pay' ) ) );
854
+ $intent = $this->get_intent_from_order( $order );
855
+
856
+ $verification_url = add_query_arg(
857
+ array(
858
+ 'order' => $order->get_id(),
859
+ 'nonce' => wp_create_nonce( 'wc_stripe_confirm_pi' ),
860
+ 'redirect_to' => rawurlencode( $this->get_return_url( $order ) ),
861
+ 'is_pay_for_order' => true,
862
+ ),
863
+ WC_AJAX::get_endpoint( 'wc_stripe_verify_intent' )
864
+ );
865
+
866
+ echo '<input type="hidden" id="stripe-intent-id" value="' . esc_attr( $intent->client_secret ) . '" />';
867
+ echo '<input type="hidden" id="stripe-intent-return" value="' . esc_attr( $verification_url ) . '" />';
868
+ }
869
+
870
+ /**
871
+ * Adds an error message wrapper to each saved method.
872
+ *
873
+ * @since 4.2.0
874
+ * @param WC_Payment_Token $token Payment Token.
875
+ * @return string Generated payment method HTML
876
+ */
877
+ public function get_saved_payment_method_option_html( $token ) {
878
+ $html = parent::get_saved_payment_method_option_html( $token );
879
+ $error_wrapper = '<div class="stripe-source-errors" role="alert"></div>';
880
+
881
+ return preg_replace( '~</(\w+)>\s*$~', "$error_wrapper</$1>", $html );
882
+ }
883
+
884
+ /**
885
+ * Attempt to manually complete the payment process for orders, which are still pending
886
+ * before displaying the View Order page. This is useful in case webhooks have not been set up.
887
+ *
888
+ * @since 4.2.0
889
+ * @param int $order_id The ID that will be used for the thank you page.
890
+ */
891
+ public function check_intent_status_on_order_page( $order_id ) {
892
+ if ( empty( $order_id ) || absint( $order_id ) <= 0 ) {
893
+ return;
894
+ }
895
+
896
+ $order = wc_get_order( absint( $order_id ) );
897
+ $this->verify_intent_after_checkout( $order );
898
+ }
899
+
900
+ /**
901
+ * Attached to `woocommerce_payment_successful_result` with a late priority,
902
+ * this method will combine the "naturally" generated redirect URL from
903
+ * WooCommerce and a payment intent secret into a hash, which contains both
904
+ * the secret, and a proper URL, which will confirm whether the intent succeeded.
905
+ *
906
+ * @since 4.2.0
907
+ * @param array $result The result from `process_payment`.
908
+ * @param int $order_id The ID of the order which is being paid for.
909
+ * @return array
910
+ */
911
+ public function modify_successful_payment_result( $result, $order_id ) {
912
+ // Only redirects with intents need to be modified.
913
+ if ( ! isset( $result['intent_secret'] ) ) {
914
+ return $result;
915
+ }
916
+
917
+ // Put the final thank you page redirect into the verification URL.
918
+ $verification_url = add_query_arg(
919
+ array(
920
+ 'order' => $order_id,
921
+ 'nonce' => wp_create_nonce( 'wc_stripe_confirm_pi' ),
922
+ 'redirect_to' => rawurlencode( $result['redirect'] ),
923
+ ),
924
+ WC_AJAX::get_endpoint( 'wc_stripe_verify_intent' )
925
+ );
926
+
927
+ // Combine into a hash.
928
+ $redirect = sprintf( '#confirm-pi-%s:%s', $result['intent_secret'], rawurlencode( $verification_url ) );
929
+
930
+ return array(
931
+ 'result' => 'success',
932
+ 'redirect' => $redirect,
933
+ );
934
+ }
935
+
936
+ /**
937
+ * Executed between the "Checkout" and "Thank you" pages, this
938
+ * method updates orders based on the status of associated PaymentIntents.
939
+ *
940
+ * @since 4.2.0
941
+ * @param WC_Order $order The order which is in a transitional state.
942
+ */
943
+ public function verify_intent_after_checkout( $order ) {
944
+ if ( 'pending' !== $order->get_status() && 'failed' !== $order->get_status() ) {
945
+ // If payment has already been completed, this function is redundant.
946
+ return;
947
+ }
948
+
949
+ $payment_method = WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $order->payment_method : $order->get_payment_method();
950
+ if ( $payment_method !== $this->id ) {
951
+ // If this is not the payment method, an intent would not be available.
952
+ return;
953
+ }
954
+
955
+ $intent = $this->get_intent_from_order( $order );
956
+ if ( ! $intent ) {
957
+ // No intent, redirect to the order received page for further actions.
958
+ return;
959
+ }
960
+
961
+ if ( $this->lock_order_payment( $order, $intent ) ) {
962
+ return;
963
+ }
964
+
965
+ if ( 'succeeded' === $intent->status ) {
966
+ // Proceed with the payment completion.
967
+ $this->process_response( end( $intent->charges->data ), $order );
968
+ } else if ( 'requires_payment_method' === $intent->status ) {
969
+ // `requires_payment_method` means that SCA got denied for the current payment method.
970
+ $this->failed_sca_auth( $order, $intent );
971
+ }
972
+
973
+ $this->unlock_order_payment( $order );
974
+ }
975
+
976
+ /**
977
+ * Checks if the payment intent associated with an order failed and records the event.
978
+ *
979
+ * @since 4.2.0
980
+ * @param WC_Order $order The order which should be checked.
981
+ * @param object $intent The intent, associated with the order.
982
+ */
983
+ public function failed_sca_auth( $order, $intent ) {
984
+ // If the order has already failed, do not repeat the same message.
985
+ if ( 'failed' === $order->get_status() ) {
986
+ return;
987
+ }
988
+
989
+ // Load the right message and update the status.
990
+ $status_message = ( $intent->last_payment_error )
991
+ /* translators: 1) The error message that was received from Stripe. */
992
+ ? sprintf( __( 'Stripe SCA authentication failed. Reason: %s', 'woocommerce-gateway-stripe' ), $intent->last_payment_error->message )
993
+ : __( 'Stripe SCA authentication failed.', 'woocommerce-gateway-stripe' );
994
+ $order->update_status( 'failed', $status_message );
995
+
996
+ $this->send_failed_order_email( $order->get_id() );
997
+ }
998
  }
includes/class-wc-stripe-helper.php CHANGED
@@ -431,6 +431,25 @@ class WC_Stripe_Helper {
431
  return false;
432
  }
433
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
434
  /**
435
  * Sanitize statement descriptor text.
436
  *
431
  return false;
432
  }
433
 
434
+ /**
435
+ * Gets the order by Stripe PaymentIntent ID.
436
+ *
437
+ * @since 4.2
438
+ * @param string $intent_id The ID of the intent.
439
+ * @return WC_Order|bool Either an order or false when not found.
440
+ */
441
+ public static function get_order_by_intent_id( $intent_id ) {
442
+ global $wpdb;
443
+
444
+ $order_id = $wpdb->get_var( $wpdb->prepare( "SELECT DISTINCT ID FROM $wpdb->posts as posts LEFT JOIN $wpdb->postmeta as meta ON posts.ID = meta.post_id WHERE meta.meta_value = %s AND meta.meta_key = %s", $intent_id, '_stripe_intent_id' ) );
445
+
446
+ if ( ! empty( $order_id ) ) {
447
+ return wc_get_order( $order_id );
448
+ }
449
+
450
+ return false;
451
+ }
452
+
453
  /**
454
  * Sanitize statement descriptor text.
455
  *
includes/class-wc-stripe-intent-controller.php ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) {
3
+ exit;
4
+ }
5
+
6
+ /**
7
+ * WC_Stripe_Intent_Controller class.
8
+ *
9
+ * Handles in-checkout AJAX calls, related to Payment Intents.
10
+ */
11
+ class WC_Stripe_Intent_Controller {
12
+ /**
13
+ * Holds an instance of the gateway class.
14
+ *
15
+ * @since 4.2.0
16
+ * @var WC_Gateway_Stripe
17
+ */
18
+ protected $gateway;
19
+
20
+ /**
21
+ * Class constructor, adds the necessary hooks.
22
+ *
23
+ * @since 4.2.0
24
+ */
25
+ public function __construct() {
26
+ add_action( 'wc_ajax_wc_stripe_verify_intent', array( $this, 'verify_intent' ) );
27
+ }
28
+
29
+ /**
30
+ * Returns an instantiated gateway.
31
+ *
32
+ * @since 4.2.0
33
+ * @return WC_Gateway_Stripe
34
+ */
35
+ protected function get_gateway() {
36
+ if ( ! isset( $this->gateway ) ) {
37
+ if ( class_exists( 'WC_Subscriptions_Order' ) && function_exists( 'wcs_create_renewal_order' ) ) {
38
+ $class_name = 'WC_Stripe_Subs_Compat';
39
+ } else {
40
+ $class_name = 'WC_Gateway_Stripe';
41
+ }
42
+
43
+ $this->gateway = new $class_name();
44
+ }
45
+
46
+ return $this->gateway;
47
+ }
48
+
49
+ /**
50
+ * Loads the order from the current request.
51
+ *
52
+ * @since 4.2.0
53
+ * @throws WC_Stripe_Exception An exception if there is no order ID or the order does not exist.
54
+ * @return WC_Order
55
+ */
56
+ protected function get_order_from_request() {
57
+ if ( ! isset( $_GET['nonce'] ) || ! wp_verify_nonce( sanitize_key( $_GET['nonce'] ), 'wc_stripe_confirm_pi' ) ) {
58
+ throw new WC_Stripe_Exception( 'missing-nonce', __( 'CSRF verification failed.', 'woocommerce-gateway-stripe' ) );
59
+ }
60
+
61
+ // Load the order ID.
62
+ $order_id = null;
63
+ if ( isset( $_GET['order'] ) && absint( $_GET['order'] ) ) {
64
+ $order_id = absint( $_GET['order'] );
65
+ }
66
+
67
+ // Retrieve the order.
68
+ $order = wc_get_order( $order_id );
69
+
70
+ if ( ! $order ) {
71
+ throw new WC_Stripe_Exception( 'missing-order', __( 'Missing order ID for payment confirmation', 'woocommerce-gateway-stripe' ) );
72
+ }
73
+
74
+ return $order;
75
+ }
76
+
77
+ /**
78
+ * Handles successful PaymentIntent authentications.
79
+ *
80
+ * @since 4.2.0
81
+ */
82
+ public function verify_intent() {
83
+ global $woocommerce;
84
+
85
+ $gateway = $this->get_gateway();
86
+
87
+ try {
88
+ $order = $this->get_order_from_request();
89
+ } catch ( WC_Stripe_Exception $e ) {
90
+ /* translators: Error message text */
91
+ $message = sprintf( __( 'Payment verification error: %s', 'woocommerce-gateway-stripe' ), $e->getLocalizedMessage() );
92
+ wc_add_notice( esc_html( $message ), 'error' );
93
+
94
+ $redirect_url = $woocommerce->cart->is_empty()
95
+ ? get_permalink( woocommerce_get_page_id( 'shop' ) )
96
+ : wc_get_checkout_url();
97
+
98
+ $this->handle_error( $e, $redirect_url );
99
+ }
100
+
101
+ try {
102
+ $gateway->verify_intent_after_checkout( $order );
103
+
104
+ if ( ! isset( $_GET['is_ajax'] ) ) {
105
+ $redirect_url = isset( $_GET['redirect_to'] ) // wpcs: csrf ok.
106
+ ? esc_url_raw( wp_unslash( $_GET['redirect_to'] ) ) // wpcs: csrf ok.
107
+ : $gateway->get_return_url( $order );
108
+
109
+ wp_safe_redirect( $redirect_url );
110
+ }
111
+
112
+ exit;
113
+ } catch ( WC_Stripe_Exception $e ) {
114
+ $this->handle_error( $e, $gateway->get_return_url( $order ) );
115
+ }
116
+ }
117
+
118
+ /**
119
+ * Handles exceptions during intent verification.
120
+ *
121
+ * @since 4.2.0
122
+ * @param WC_Stripe_Exception $e The exception that was thrown.
123
+ * @param string $redirect_url An URL to use if a redirect is needed.
124
+ */
125
+ protected function handle_error( $e, $redirect_url ) {
126
+ // Log the exception before redirecting.
127
+ $message = sprintf( 'PaymentIntent verification exception: %s', $e->getLocalizedMessage() );
128
+ WC_Stripe_Logger::log( $message );
129
+
130
+ // `is_ajax` is only used for PI error reporting, a response is not expected.
131
+ if ( isset( $_GET['is_ajax'] ) ) {
132
+ exit;
133
+ }
134
+
135
+ wp_safe_redirect( $redirect_url );
136
+ exit;
137
+ }
138
+ }
139
+
140
+ new WC_Stripe_Intent_Controller();
includes/class-wc-stripe-order-handler.php CHANGED
@@ -237,29 +237,58 @@ class WC_Stripe_Order_Handler extends WC_Stripe_Payment_Gateway {
237
  $order_total = $order_total - $order->get_total_refunded();
238
  }
239
 
240
- // First retrieve charge to see if it has been captured.
241
- $result = WC_Stripe_API::retrieve( 'charges/' . $charge );
242
-
243
- if ( ! empty( $result->error ) ) {
244
- /* translators: error message */
245
- $order->add_order_note( sprintf( __( 'Unable to capture charge! %s', 'woocommerce-gateway-stripe' ), $result->error->message ) );
246
- } elseif ( false === $result->captured ) {
247
- $result = WC_Stripe_API::request(
248
- array(
249
- 'amount' => WC_Stripe_Helper::get_stripe_amount( $order_total ),
250
- 'expand[]' => 'balance_transaction',
251
- ),
252
- 'charges/' . $charge . '/capture'
253
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
254
 
255
  if ( ! empty( $result->error ) ) {
256
  /* translators: error message */
257
- $order->update_status( 'failed', sprintf( __( 'Unable to capture charge! %s', 'woocommerce-gateway-stripe' ), $result->error->message ) );
258
- } else {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
259
  $is_stripe_captured = true;
260
  }
261
- } elseif ( true === $result->captured ) {
262
- $is_stripe_captured = true;
263
  }
264
 
265
  if ( $is_stripe_captured ) {
237
  $order_total = $order_total - $order->get_total_refunded();
238
  }
239
 
240
+ $intent = $this->get_intent_from_order( $order );
241
+ if ( $intent ) {
242
+ // If the order has a Payment Intent, then the Intent itself must be captured, not the Charge
243
+ if ( ! empty( $intent->error ) ) {
244
+ /* translators: error message */
245
+ $order->add_order_note( sprintf( __( 'Unable to capture charge! %s', 'woocommerce-gateway-stripe' ), $intent->error->message ) );
246
+ } elseif ( 'requires_capture' === $intent->status ) {
247
+ $result = WC_Stripe_API::request(
248
+ array(
249
+ 'amount' => WC_Stripe_Helper::get_stripe_amount( $order_total ),
250
+ 'expand[]' => 'charges.data.balance_transaction',
251
+ ),
252
+ 'payment_intents/' . $intent->id . '/capture'
253
+ );
254
+
255
+ if ( ! empty( $result->error ) ) {
256
+ /* translators: error message */
257
+ $order->update_status( 'failed', sprintf( __( 'Unable to capture charge! %s', 'woocommerce-gateway-stripe' ), $result->error->message ) );
258
+ } else {
259
+ $is_stripe_captured = true;
260
+ $result = end( $result->charges->data );
261
+ }
262
+ } elseif ( 'succeeded' === $intent->status ) {
263
+ $is_stripe_captured = true;
264
+ }
265
+ } else {
266
+ // The order doesn't have a Payment Intent, fall back to capturing the Charge directly
267
+
268
+ // First retrieve charge to see if it has been captured.
269
+ $result = WC_Stripe_API::retrieve( 'charges/' . $charge );
270
 
271
  if ( ! empty( $result->error ) ) {
272
  /* translators: error message */
273
+ $order->add_order_note( sprintf( __( 'Unable to capture charge! %s', 'woocommerce-gateway-stripe' ), $result->error->message ) );
274
+ } elseif ( false === $result->captured ) {
275
+ $result = WC_Stripe_API::request(
276
+ array(
277
+ 'amount' => WC_Stripe_Helper::get_stripe_amount( $order_total ),
278
+ 'expand[]' => 'balance_transaction',
279
+ ),
280
+ 'charges/' . $charge . '/capture'
281
+ );
282
+
283
+ if ( ! empty( $result->error ) ) {
284
+ /* translators: error message */
285
+ $order->update_status( 'failed', sprintf( __( 'Unable to capture charge! %s', 'woocommerce-gateway-stripe' ), $result->error->message ) );
286
+ } else {
287
+ $is_stripe_captured = true;
288
+ }
289
+ } elseif ( true === $result->captured ) {
290
  $is_stripe_captured = true;
291
  }
 
 
292
  }
293
 
294
  if ( $is_stripe_captured ) {
includes/class-wc-stripe-webhook-handler.php CHANGED
@@ -305,6 +305,7 @@ class WC_Stripe_Webhook_Handler extends WC_Stripe_Payment_Gateway {
305
  if ( $this->is_partial_capture( $notification ) ) {
306
  $partial_amount = $this->get_partial_amount_to_charge( $notification );
307
  $order->set_total( $partial_amount );
 
308
  /* translators: partial captured amount */
309
  $order->add_order_note( sprintf( __( 'This charge was partially captured via Stripe Dashboard in the amount of: %s', 'woocommerce-gateway-stripe' ), $partial_amount ) );
310
  } else {
@@ -330,6 +331,11 @@ class WC_Stripe_Webhook_Handler extends WC_Stripe_Payment_Gateway {
330
  * @param object $notification
331
  */
332
  public function process_webhook_charge_succeeded( $notification ) {
 
 
 
 
 
333
  // The following payment methods are synchronous so does not need to be handle via webhook.
334
  if ( ( isset( $notification->data->object->source->type ) && 'card' === $notification->data->object->source->type ) || ( isset( $notification->data->object->source->type ) && 'three_d_secure' === $notification->data->object->source->type ) ) {
335
  return;
@@ -595,6 +601,47 @@ class WC_Stripe_Webhook_Handler extends WC_Stripe_Payment_Gateway {
595
  return false;
596
  }
597
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
598
  /**
599
  * Processes the incoming webhook.
600
  *
@@ -642,6 +689,11 @@ class WC_Stripe_Webhook_Handler extends WC_Stripe_Payment_Gateway {
642
  $this->process_review_closed( $notification );
643
  break;
644
 
 
 
 
 
 
645
  }
646
  }
647
  }
305
  if ( $this->is_partial_capture( $notification ) ) {
306
  $partial_amount = $this->get_partial_amount_to_charge( $notification );
307
  $order->set_total( $partial_amount );
308
+ $this->update_fees( $order, $notification->data->object->refunds->data[0]->balance_transaction );
309
  /* translators: partial captured amount */
310
  $order->add_order_note( sprintf( __( 'This charge was partially captured via Stripe Dashboard in the amount of: %s', 'woocommerce-gateway-stripe' ), $partial_amount ) );
311
  } else {
331
  * @param object $notification
332
  */
333
  public function process_webhook_charge_succeeded( $notification ) {
334
+ // Ignore the notification for charges, created through PaymentIntents.
335
+ if ( isset( $notification->data->object->payment_intent ) && $notification->data->object->payment_intent ) {
336
+ return;
337
+ }
338
+
339
  // The following payment methods are synchronous so does not need to be handle via webhook.
340
  if ( ( isset( $notification->data->object->source->type ) && 'card' === $notification->data->object->source->type ) || ( isset( $notification->data->object->source->type ) && 'three_d_secure' === $notification->data->object->source->type ) ) {
341
  return;
601
  return false;
602
  }
603
 
604
+ public function process_payment_intent_success( $notification ) {
605
+ $intent = $notification->data->object;
606
+ $order = WC_Stripe_Helper::get_order_by_intent_id( $intent->id );
607
+
608
+ if ( ! $order ) {
609
+ WC_Stripe_Logger::log( 'Could not find order via intent ID: ' . $intent->id );
610
+ return;
611
+ }
612
+
613
+ if ( $this->lock_order_payment( $order, $intent ) ) {
614
+ return;
615
+ }
616
+
617
+ $order_id = WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $order->id : $order->get_id();
618
+ if ( 'payment_intent.succeeded' === $notification->type || 'payment_intent.amount_capturable_updated' === $notification->type ) {
619
+ if ( 'pending' !== $order->get_status() && 'failed' !== $order->get_status() ) {
620
+ return;
621
+ }
622
+
623
+ $charge = end( $intent->charges->data );
624
+ WC_Stripe_Logger::log( "Stripe PaymentIntent $intent->id succeeded for order $order_id" );
625
+
626
+ do_action( 'wc_gateway_stripe_process_payment', $charge, $order );
627
+
628
+ // Process valid response.
629
+ $this->process_response( $charge, $order );
630
+
631
+ } else {
632
+ $error_message = $intent->last_payment_error ? $intent->last_payment_error->message : "";
633
+
634
+ /* translators: 1) The error message that was received from Stripe. */
635
+ $order->update_status( 'failed', sprintf( __( 'Stripe SCA authentication failed. Reason: %s', 'woocommerce-gateway-stripe' ), $error_message ) );
636
+
637
+ do_action( 'wc_gateway_stripe_process_webhook_payment_error', $order, $notification );
638
+
639
+ $this->send_failed_order_email( $order_id );
640
+ }
641
+
642
+ $this->unlock_order_payment( $order );
643
+ }
644
+
645
  /**
646
  * Processes the incoming webhook.
647
  *
689
  $this->process_review_closed( $notification );
690
  break;
691
 
692
+ case 'payment_intent.succeeded':
693
+ case 'payment_intent.payment_failed':
694
+ case 'payment_intent.amount_capturable_updated':
695
+ $this->process_payment_intent_success( $notification );
696
+
697
  }
698
  }
699
  }
includes/compat/class-wc-stripe-sepa-subs-compat.php CHANGED
@@ -33,15 +33,6 @@ class WC_Stripe_Sepa_Subs_Compat extends WC_Gateway_Stripe_Sepa {
33
  }
34
  }
35
 
36
- /**
37
- * Handles the return from processing the payment for Stripe Checkout.
38
- *
39
- * @since 4.1.0
40
- */
41
- public function stripe_checkout_return_handler() {
42
- return parent::stripe_checkout_return_handler();
43
- }
44
-
45
  /**
46
  * Checks to see if we need to hide the save checkbox field.
47
  * Because when cart contains a subs product, it will save regardless.
33
  }
34
  }
35
 
 
 
 
 
 
 
 
 
 
36
  /**
37
  * Checks to see if we need to hide the save checkbox field.
38
  * Because when cart contains a subs product, it will save regardless.
includes/compat/class-wc-stripe-subs-compat.php CHANGED
@@ -33,15 +33,6 @@ class WC_Stripe_Subs_Compat extends WC_Gateway_Stripe {
33
  }
34
  }
35
 
36
- /**
37
- * Handles the return from processing the payment for Stripe Checkout.
38
- *
39
- * @since 4.1.0
40
- */
41
- public function stripe_checkout_return_handler() {
42
- return parent::stripe_checkout_return_handler();
43
- }
44
-
45
  /**
46
  * Checks to see if we need to hide the save checkbox field.
47
  * Because when cart contains a subs product, it will save regardless.
33
  }
34
  }
35
 
 
 
 
 
 
 
 
 
 
36
  /**
37
  * Checks to see if we need to hide the save checkbox field.
38
  * Because when cart contains a subs product, it will save regardless.
includes/payment-methods/class-wc-stripe-payment-request.php CHANGED
@@ -21,13 +21,6 @@ class WC_Stripe_Payment_Request {
21
  */
22
  public $stripe_settings;
23
 
24
- /**
25
- * Stripe Checkout enabled.
26
- *
27
- * @var
28
- */
29
- public $stripe_checkout_enabled;
30
-
31
  /**
32
  * Total label
33
  *
@@ -70,13 +63,12 @@ class WC_Stripe_Payment_Request {
70
  * @version 4.0.0
71
  */
72
  public function __construct() {
73
- self::$_this = $this;
74
- $this->stripe_settings = get_option( 'woocommerce_stripe_settings', array() );
75
- $this->testmode = ( ! empty( $this->stripe_settings['testmode'] ) && 'yes' === $this->stripe_settings['testmode'] ) ? true : false;
76
- $this->publishable_key = ! empty( $this->stripe_settings['publishable_key'] ) ? $this->stripe_settings['publishable_key'] : '';
77
- $this->secret_key = ! empty( $this->stripe_settings['secret_key'] ) ? $this->stripe_settings['secret_key'] : '';
78
- $this->stripe_checkout_enabled = isset( $this->stripe_settings['stripe_checkout'] ) && 'yes' === $this->stripe_settings['stripe_checkout'];
79
- $this->total_label = ! empty( $this->stripe_settings['statement_descriptor'] ) ? WC_Stripe_Helper::clean_statement_descriptor( $this->stripe_settings['statement_descriptor'] ) : '';
80
 
81
  if ( $this->testmode ) {
82
  $this->publishable_key = ! empty( $this->stripe_settings['test_publishable_key'] ) ? $this->stripe_settings['test_publishable_key'] : '';
@@ -117,7 +109,7 @@ class WC_Stripe_Payment_Request {
117
  * @return array The list of countries.
118
  */
119
  public function get_stripe_supported_countries() {
120
- return apply_filters( 'wc_stripe_supported_countries', array( 'AT', 'AU', 'BE', 'BR', 'CA', 'CH', 'DE', 'DK', 'EE', 'ES', 'FI', 'FR', 'GB', 'HK', 'IE', 'IN', 'IT', 'JP', 'LT', 'LU', 'LV', 'MX', 'NL', 'NZ', 'NO', 'PH', 'PL', 'PT', 'RO', 'SE', 'SG', 'SK', 'US' ) );
121
  }
122
 
123
  /**
@@ -527,6 +519,11 @@ class WC_Stripe_Payment_Request {
527
  wp_localize_script( 'wc_stripe_payment_request', 'wc_stripe_payment_request_params', apply_filters( 'wc_stripe_payment_request_params', $stripe_params ) );
528
 
529
  wp_enqueue_script( 'wc_stripe_payment_request' );
 
 
 
 
 
530
  }
531
 
532
  /**
21
  */
22
  public $stripe_settings;
23
 
 
 
 
 
 
 
 
24
  /**
25
  * Total label
26
  *
63
  * @version 4.0.0
64
  */
65
  public function __construct() {
66
+ self::$_this = $this;
67
+ $this->stripe_settings = get_option( 'woocommerce_stripe_settings', array() );
68
+ $this->testmode = ( ! empty( $this->stripe_settings['testmode'] ) && 'yes' === $this->stripe_settings['testmode'] ) ? true : false;
69
+ $this->publishable_key = ! empty( $this->stripe_settings['publishable_key'] ) ? $this->stripe_settings['publishable_key'] : '';
70
+ $this->secret_key = ! empty( $this->stripe_settings['secret_key'] ) ? $this->stripe_settings['secret_key'] : '';
71
+ $this->total_label = ! empty( $this->stripe_settings['statement_descriptor'] ) ? WC_Stripe_Helper::clean_statement_descriptor( $this->stripe_settings['statement_descriptor'] ) : '';
 
72
 
73
  if ( $this->testmode ) {
74
  $this->publishable_key = ! empty( $this->stripe_settings['test_publishable_key'] ) ? $this->stripe_settings['test_publishable_key'] : '';
109
  * @return array The list of countries.
110
  */
111
  public function get_stripe_supported_countries() {
112
+ return apply_filters( 'wc_stripe_supported_countries', array( 'AT', 'AU', 'BE', 'BR', 'CA', 'CH', 'DE', 'DK', 'EE', 'ES', 'FI', 'FR', 'GB', 'HK', 'IE', 'IN', 'IT', 'JP', 'LT', 'LU', 'LV', 'MX', 'NL', 'NZ', 'NO', 'PH', 'PL', 'PR', 'PT', 'RO', 'SE', 'SG', 'SK', 'US' ) );
113
  }
114
 
115
  /**
519
  wp_localize_script( 'wc_stripe_payment_request', 'wc_stripe_payment_request_params', apply_filters( 'wc_stripe_payment_request_params', $stripe_params ) );
520
 
521
  wp_enqueue_script( 'wc_stripe_payment_request' );
522
+
523
+ $gateways = WC()->payment_gateways->get_available_payment_gateways();
524
+ if ( isset( $gateways['stripe'] ) ) {
525
+ $gateways['stripe']->payment_scripts();
526
+ }
527
  }
528
 
529
  /**
languages/woocommerce-gateway-stripe.pot CHANGED
@@ -2,10 +2,10 @@
2
  # This file is distributed under the same license as the WooCommerce Stripe Gateway package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: WooCommerce Stripe Gateway 4.1.16\n"
6
  "Report-Msgid-Bugs-To: "
7
  "https://wordpress.org/support/plugin/woocommerce-gateway-stripe\n"
8
- "POT-Creation-Date: 2019-04-18 15:59:41+00:00\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=utf-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
@@ -29,8 +29,8 @@ msgid "Save payment information to my account for future purchases."
29
  msgstr ""
30
 
31
  #: includes/abstracts/abstract-wc-stripe-payment-gateway.php:245
32
- #: includes/compat/class-wc-stripe-sepa-subs-compat.php:225
33
- #: includes/compat/class-wc-stripe-subs-compat.php:206
34
  #. translators: 1) dollar amount
35
  #. translators: minimum amount
36
  msgid "Sorry, the minimum allowed order total is %1$s to use this payment method."
@@ -49,58 +49,60 @@ msgstr ""
49
  msgid "customer_email"
50
  msgstr ""
51
 
52
- #: includes/abstracts/abstract-wc-stripe-payment-gateway.php:443
53
  #. translators: transaction id
54
  msgid "Stripe charge awaiting payment: %s."
55
  msgstr ""
56
 
57
- #: includes/abstracts/abstract-wc-stripe-payment-gateway.php:450
58
- #: includes/class-wc-stripe-order-handler.php:267
59
- #: includes/class-wc-stripe-webhook-handler.php:314
60
- #: includes/class-wc-stripe-webhook-handler.php:361
61
  #. translators: transaction id
62
  msgid "Stripe charge complete (Charge ID: %s)"
63
  msgstr ""
64
 
65
- #: includes/abstracts/abstract-wc-stripe-payment-gateway.php:455
66
- #: includes/class-wc-gateway-stripe.php:707
67
- #: includes/compat/class-wc-stripe-sepa-subs-compat.php:182
68
- #: includes/compat/class-wc-stripe-subs-compat.php:145
69
  msgid "Payment processing failed. Please retry."
70
  msgstr ""
71
 
72
- #: includes/abstracts/abstract-wc-stripe-payment-gateway.php:467
73
  #. translators: transaction id
74
  msgid ""
75
  "Stripe charge authorized (Charge ID: %s). Process order to take payment, or "
76
  "cancel to remove the pre-authorization."
77
  msgstr ""
78
 
79
- #: includes/abstracts/abstract-wc-stripe-payment-gateway.php:698
80
  msgid "Invalid payment method. Please input a new card number."
81
  msgstr ""
82
 
83
- #: includes/abstracts/abstract-wc-stripe-payment-gateway.php:949
84
  #. translators: 1) dollar amount 2) transaction id 3) refund message
85
  msgid "Refunded %1$s - Refund ID: %2$s - Reason: %3$s"
86
  msgstr ""
87
 
88
- #: includes/abstracts/abstract-wc-stripe-payment-gateway.php:949
89
  msgid "Pre-Authorization Released"
90
  msgstr ""
91
 
92
- #: includes/abstracts/abstract-wc-stripe-payment-gateway.php:967
93
  msgid "There was a problem adding the payment method."
94
  msgstr ""
95
 
96
- #: includes/admin/class-wc-stripe-admin-notices.php:119
 
97
  msgid ""
98
- "WooCommerce Stripe - Support for Stripe Modal Checkout will be ending soon. "
99
- "This will impact the appearance of your checkout. <a href=\"%1$s\" "
100
- "target=\"_blank\">Click here to learn more.</a>"
 
101
  msgstr ""
102
 
103
- #: includes/admin/class-wc-stripe-admin-notices.php:125
104
  #. translators: 1) int version 2) int version
105
  msgid ""
106
  "WooCommerce Stripe - We recently made changes to Stripe that may impact the "
@@ -110,32 +112,32 @@ msgid ""
110
  "target=\"_blank\">instructions</a> to fix."
111
  msgstr ""
112
 
113
- #: includes/admin/class-wc-stripe-admin-notices.php:135
114
  #. translators: 1) int version 2) int version
115
  msgid ""
116
  "WooCommerce Stripe - The minimum PHP version required for this plugin is "
117
  "%1$s. You are running %2$s."
118
  msgstr ""
119
 
120
- #: includes/admin/class-wc-stripe-admin-notices.php:146
121
  #. translators: 1) int version 2) int version
122
  msgid ""
123
  "WooCommerce Stripe - The minimum WooCommerce version required for this "
124
  "plugin is %1$s. You are running %2$s."
125
  msgstr ""
126
 
127
- #: includes/admin/class-wc-stripe-admin-notices.php:156
128
  msgid "WooCommerce Stripe - cURL is not installed."
129
  msgstr ""
130
 
131
- #: includes/admin/class-wc-stripe-admin-notices.php:166
132
  #. translators: 1) link
133
  msgid ""
134
  "Stripe is almost ready. To get started, <a href=\"%s\">set your Stripe "
135
  "account keys</a>."
136
  msgstr ""
137
 
138
- #: includes/admin/class-wc-stripe-admin-notices.php:177
139
  #. translators: 1) link
140
  msgid ""
141
  "Stripe is in test mode however your test keys may not be valid. Test keys "
@@ -143,7 +145,7 @@ msgid ""
143
  "<a href=\"%s\">set your Stripe account keys</a>."
144
  msgstr ""
145
 
146
- #: includes/admin/class-wc-stripe-admin-notices.php:186
147
  #. translators: 1) link
148
  msgid ""
149
  "Stripe is in live mode however your test keys may not be valid. Live keys "
@@ -151,7 +153,7 @@ msgid ""
151
  "<a href=\"%s\">set your Stripe account keys</a>."
152
  msgstr ""
153
 
154
- #: includes/admin/class-wc-stripe-admin-notices.php:195
155
  #. translators: 1) link
156
  msgid ""
157
  "Stripe is enabled, but a SSL certificate is not detected. Your checkout may "
@@ -159,21 +161,21 @@ msgid ""
159
  "target=\"_blank\">SSL certificate</a>"
160
  msgstr ""
161
 
162
- #: includes/admin/class-wc-stripe-admin-notices.php:219
163
  #. translators: %1$s Payment method, %2$s List of supported currencies
164
  msgid "%1$s is enabled - it requires store currency to be set to %2$s"
165
  msgstr ""
166
 
167
- #: includes/admin/class-wc-stripe-admin-notices.php:233
168
  msgid "Action failed. Please refresh the page and retry."
169
  msgstr ""
170
 
171
- #: includes/admin/class-wc-stripe-admin-notices.php:237
172
  msgid "Cheatin&#8217; huh?"
173
  msgstr ""
174
 
175
  #: includes/admin/class-wc-stripe-privacy.php:12
176
- #: includes/class-wc-gateway-stripe.php:116
177
  msgid "Stripe"
178
  msgstr ""
179
 
@@ -203,9 +205,9 @@ msgid "Retains any Stripe data such as Stripe customer ID, source ID."
203
  msgstr ""
204
 
205
  #: includes/admin/class-wc-stripe-privacy.php:41
206
- #: includes/compat/class-wc-stripe-sepa-subs-compat.php:472
207
- #: includes/compat/class-wc-stripe-subs-compat.php:484
208
- #: includes/compat/class-wc-stripe-subs-compat.php:499
209
  msgid "N/A"
210
  msgstr ""
211
 
@@ -610,158 +612,107 @@ msgid ""
610
  msgstr ""
611
 
612
  #: includes/admin/stripe-settings.php:95
613
- msgid "3D Secure"
614
- msgstr ""
615
-
616
- #: includes/admin/stripe-settings.php:96
617
- msgid "Require 3D Secure when applicable"
618
- msgstr ""
619
-
620
- #: includes/admin/stripe-settings.php:98
621
- msgid ""
622
- "Some payment methods have 3D Secure feature. This is an extra security "
623
- "layer for your store. Choose how to handle payments when 3D Secure is "
624
- "recommended. Enabling would require customers to use 3D Secure when "
625
- "recommended."
626
- msgstr ""
627
-
628
- #: includes/admin/stripe-settings.php:103
629
- msgid "Stripe Modal Checkout"
630
- msgstr ""
631
-
632
- #: includes/admin/stripe-settings.php:104
633
- msgid "Enable Stripe Checkout"
634
- msgstr ""
635
-
636
- #: includes/admin/stripe-settings.php:106
637
- msgid ""
638
- "If enabled, this option shows a \"pay\" button and modal credit card form "
639
- "on the checkout, instead of credit card fields directly on the page. We "
640
- "recommend you leave this disabled and use the embedded form as that is the "
641
- "preferred method."
642
- msgstr ""
643
-
644
- #: includes/admin/stripe-settings.php:111
645
- msgid "Stripe Checkout Image"
646
- msgstr ""
647
-
648
- #: includes/admin/stripe-settings.php:112
649
- msgid ""
650
- "Optionally enter the URL to a 128x128px image of your brand or product. "
651
- "e.g. "
652
- "<code>https://yoursite.com/wp-content/uploads/2013/09/yourimage.jpg</code>"
653
- msgstr ""
654
-
655
- #: includes/admin/stripe-settings.php:118
656
- msgid "Stripe Checkout Description"
657
- msgstr ""
658
-
659
- #: includes/admin/stripe-settings.php:120
660
- msgid "Shows a description of your store on Stripe Modal Checkout."
661
- msgstr ""
662
-
663
- #: includes/admin/stripe-settings.php:125
664
  msgid "Payment Request Buttons"
665
  msgstr ""
666
 
667
- #: includes/admin/stripe-settings.php:127
668
  #. translators: 1) br tag 2) opening anchor tag 3) closing anchor tag
669
  msgid ""
670
  "Enable Payment Request Buttons. (Apple Pay/Chrome Payment Request API) "
671
  "%1$sBy using Apple Pay, you agree to %2$s and %3$s's terms of service."
672
  msgstr ""
673
 
674
- #: includes/admin/stripe-settings.php:129
675
  msgid ""
676
  "If enabled, users will be able to pay using Apple Pay or Chrome Payment "
677
  "Request if supported by the browser."
678
  msgstr ""
679
 
680
- #: includes/admin/stripe-settings.php:134
681
  msgid "Payment Request Button Type"
682
  msgstr ""
683
 
684
- #: includes/admin/stripe-settings.php:135
685
  msgid "Button Type"
686
  msgstr ""
687
 
688
- #: includes/admin/stripe-settings.php:137
689
  msgid "Select the button type you would like to show."
690
  msgstr ""
691
 
692
- #: includes/admin/stripe-settings.php:141
693
  msgid "Default"
694
  msgstr ""
695
 
696
- #: includes/admin/stripe-settings.php:142
697
  msgid "Buy"
698
  msgstr ""
699
 
700
- #: includes/admin/stripe-settings.php:143
701
  msgid "Donate"
702
  msgstr ""
703
 
704
- #: includes/admin/stripe-settings.php:147
705
  msgid "Payment Request Button Theme"
706
  msgstr ""
707
 
708
- #: includes/admin/stripe-settings.php:148
709
  msgid "Button Theme"
710
  msgstr ""
711
 
712
- #: includes/admin/stripe-settings.php:150
713
  msgid "Select the button theme you would like to show."
714
  msgstr ""
715
 
716
- #: includes/admin/stripe-settings.php:154
717
  msgid "Dark"
718
  msgstr ""
719
 
720
- #: includes/admin/stripe-settings.php:155
721
  msgid "Light"
722
  msgstr ""
723
 
724
- #: includes/admin/stripe-settings.php:156
725
  msgid "Light-Outline"
726
  msgstr ""
727
 
728
- #: includes/admin/stripe-settings.php:160
729
  msgid "Payment Request Button Height"
730
  msgstr ""
731
 
732
- #: includes/admin/stripe-settings.php:161
733
  msgid "Button Height"
734
  msgstr ""
735
 
736
- #: includes/admin/stripe-settings.php:163
737
  msgid ""
738
  "Enter the height you would like the button to be in pixels. Width will "
739
  "always be 100%."
740
  msgstr ""
741
 
742
- #: includes/admin/stripe-settings.php:168
743
  msgid "Saved Cards"
744
  msgstr ""
745
 
746
- #: includes/admin/stripe-settings.php:169
747
  msgid "Enable Payment via Saved Cards"
748
  msgstr ""
749
 
750
- #: includes/admin/stripe-settings.php:171
751
  msgid ""
752
  "If enabled, users will be able to pay with a saved card during checkout. "
753
  "Card details are saved on Stripe servers, not on your store."
754
  msgstr ""
755
 
756
- #: includes/admin/stripe-settings.php:176
757
  msgid "Logging"
758
  msgstr ""
759
 
760
- #: includes/admin/stripe-settings.php:177
761
  msgid "Log debug messages"
762
  msgstr ""
763
 
764
- #: includes/admin/stripe-settings.php:179
765
  msgid "Save debug messages to the WooCommerce System Status log."
766
  msgstr ""
767
 
@@ -787,7 +738,7 @@ msgstr ""
787
  msgid "You will be redirected to SOFORT."
788
  msgstr ""
789
 
790
- #: includes/class-wc-gateway-stripe.php:118
791
  #. translators: 1) link to Stripe register page 2) link to Stripe api keys page
792
  msgid ""
793
  "Stripe works by adding payment fields on the checkout and then sending the "
@@ -796,26 +747,22 @@ msgid ""
796
  "your Stripe account keys</a>."
797
  msgstr ""
798
 
799
- #: includes/class-wc-gateway-stripe.php:162
800
- msgid "Continue to payment"
801
- msgstr ""
802
-
803
- #: includes/class-wc-gateway-stripe.php:224
804
  #. translators: 1) Opening anchor tag 2) closing anchor tag
805
  msgid ""
806
  "If your billing address has been changed for saved payment methods, be sure "
807
  "to remove any %1$ssaved payment methods%2$s on file and re-add them."
808
  msgstr ""
809
 
810
- #: includes/class-wc-gateway-stripe.php:285
811
  msgid "Add Card"
812
  msgstr ""
813
 
814
- #: includes/class-wc-gateway-stripe.php:291
815
  msgid "Change Payment Method"
816
  msgstr ""
817
 
818
- #: includes/class-wc-gateway-stripe.php:318
819
  #. translators: link to Stripe testing page
820
  msgid ""
821
  "TEST MODE ENABLED. In test mode, you can use the card number "
@@ -824,88 +771,99 @@ msgid ""
824
  "card numbers."
825
  msgstr ""
826
 
827
- #: includes/class-wc-gateway-stripe.php:363
828
  msgid "Credit or debit card"
829
  msgstr ""
830
 
831
- #: includes/class-wc-gateway-stripe.php:371
832
  msgid "Card Number"
833
  msgstr ""
834
 
835
- #: includes/class-wc-gateway-stripe.php:382
836
  msgid "Expiry Date"
837
  msgstr ""
838
 
839
- #: includes/class-wc-gateway-stripe.php:390
840
  msgid "Card Code (CVC)"
841
  msgstr ""
842
 
843
- #: includes/class-wc-gateway-stripe.php:466
844
  msgid "Please accept the terms and conditions first"
845
  msgstr ""
846
 
847
- #: includes/class-wc-gateway-stripe.php:467
848
  msgid "Please fill in required checkout fields first"
849
  msgstr ""
850
 
851
- #: includes/class-wc-gateway-stripe.php:487
852
- #: includes/class-wc-gateway-stripe.php:702
853
  msgid ""
854
  "Sorry, we're not accepting prepaid cards at this time. Your credit card has "
855
  "not been charged. Please try with alternative payment method."
856
  msgstr ""
857
 
858
- #: includes/class-wc-gateway-stripe.php:488
859
  msgid "Please enter your IBAN account name."
860
  msgstr ""
861
 
862
- #: includes/class-wc-gateway-stripe.php:489
863
  msgid "Please enter your IBAN account number."
864
  msgstr ""
865
 
866
- #: includes/class-wc-gateway-stripe.php:508
 
 
 
 
867
  msgid "Billing First Name and Last Name are required."
868
  msgstr ""
869
 
870
- #: includes/class-wc-gateway-stripe.php:592
871
- msgid "Place Order"
 
872
  msgstr ""
873
 
874
- #: includes/class-wc-gateway-stripe.php:793
875
- #: includes/class-wc-stripe-order-handler.php:144
876
- #: includes/class-wc-stripe-webhook-handler.php:187
877
- #: includes/payment-methods/class-wc-gateway-stripe-sepa.php:353
878
- msgid "This card is no longer available and has been removed."
 
 
 
879
  msgstr ""
880
 
881
- #: includes/class-wc-gateway-stripe.php:812
 
 
 
 
882
  #: includes/class-wc-stripe-order-handler.php:162
883
  #: includes/class-wc-stripe-webhook-handler.php:206
884
- #: includes/compat/class-wc-stripe-sepa-subs-compat.php:272
885
- #: includes/compat/class-wc-stripe-subs-compat.php:253
886
  #: includes/payment-methods/class-wc-gateway-stripe-sepa.php:373
887
  msgid ""
888
  "Sorry, we are unable to process your payment at this time. Please retry "
889
  "later."
890
  msgstr ""
891
 
892
- #: includes/class-wc-gateway-stripe.php:889
893
- #. translators: error message
894
- msgid "This represents the fee Stripe collects for the transaction."
 
 
 
895
  msgstr ""
896
 
897
- #: includes/class-wc-gateway-stripe.php:890
898
- msgid "Stripe Fee:"
 
 
899
  msgstr ""
900
 
901
- #: includes/class-wc-gateway-stripe.php:926
902
- msgid ""
903
- "This represents the net total that will be credited to your Stripe bank "
904
- "account. This may be in the currency that is set in your Stripe account."
905
- msgstr ""
906
-
907
- #: includes/class-wc-gateway-stripe.php:927
908
- msgid "Stripe Payout:"
909
  msgstr ""
910
 
911
  #: includes/class-wc-stripe-api.php:138 includes/class-wc-stripe-api.php:172
@@ -1018,6 +976,25 @@ msgstr ""
1018
  msgid "The billing country is not accepted by SOFORT. Please try another country."
1019
  msgstr ""
1020
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1021
  #: includes/class-wc-stripe-order-handler.php:194
1022
  #. translators: error message
1023
  msgid "Stripe payment failed: %s"
@@ -1025,6 +1002,8 @@ msgstr ""
1025
 
1026
  #: includes/class-wc-stripe-order-handler.php:245
1027
  #: includes/class-wc-stripe-order-handler.php:257
 
 
1028
  #. translators: error message
1029
  msgid "Unable to capture charge! %s"
1030
  msgstr ""
@@ -1046,34 +1025,34 @@ msgid ""
1046
  "Dashboard</a> to review this dispute."
1047
  msgstr ""
1048
 
1049
- #: includes/class-wc-stripe-webhook-handler.php:309
1050
  #. translators: partial captured amount
1051
  msgid "This charge was partially captured via Stripe Dashboard in the amount of: %s"
1052
  msgstr ""
1053
 
1054
- #: includes/class-wc-stripe-webhook-handler.php:390
1055
  msgid "This payment failed to clear."
1056
  msgstr ""
1057
 
1058
- #: includes/class-wc-stripe-webhook-handler.php:423
1059
  msgid "This payment has cancelled."
1060
  msgstr ""
1061
 
1062
- #: includes/class-wc-stripe-webhook-handler.php:458
1063
  msgid "Refunded via Stripe Dashboard"
1064
  msgstr ""
1065
 
1066
- #: includes/class-wc-stripe-webhook-handler.php:458
1067
- #: includes/class-wc-stripe-webhook-handler.php:486
1068
  msgid "Pre-Authorization Released via Stripe Dashboard"
1069
  msgstr ""
1070
 
1071
- #: includes/class-wc-stripe-webhook-handler.php:486
1072
  #. translators: 1) dollar amount 2) transaction id 3) refund message
1073
  msgid "Refunded %1$s - Refund ID: %2$s - %3$s"
1074
  msgstr ""
1075
 
1076
- #: includes/class-wc-stripe-webhook-handler.php:508
1077
  #. translators: 1) The URL to the order. 2) The reason type.
1078
  msgid ""
1079
  "A review has been opened for this order. Action is needed. Please go to "
@@ -1081,7 +1060,7 @@ msgid ""
1081
  "Dashboard</a> to review the issue. Reason: (%2$s)"
1082
  msgstr ""
1083
 
1084
- #: includes/class-wc-stripe-webhook-handler.php:532
1085
  #. translators: 1) The reason type.
1086
  msgid "The opened review for this order is now closed. Reason: (%s)"
1087
  msgstr ""
@@ -1095,56 +1074,56 @@ msgstr ""
1095
  msgid "Stripe Transaction Failed (%s)"
1096
  msgstr ""
1097
 
1098
- #: includes/compat/class-wc-stripe-sepa-subs-compat.php:97
1099
- #: includes/compat/class-wc-stripe-subs-compat.php:97
1100
  msgid ""
1101
  "Update the Payment Method used for all of my active subscriptions "
1102
  "(optional)."
1103
  msgstr ""
1104
 
1105
- #: includes/compat/class-wc-stripe-sepa-subs-compat.php:235
1106
- #: includes/compat/class-wc-stripe-subs-compat.php:216
1107
  msgid "Customer not found"
1108
  msgstr ""
1109
 
1110
- #: includes/compat/class-wc-stripe-sepa-subs-compat.php:395
1111
- #: includes/compat/class-wc-stripe-subs-compat.php:407
1112
  #. translators: error message
1113
  msgid "A \"Stripe Customer ID\" value is required."
1114
  msgstr ""
1115
 
1116
- #: includes/compat/class-wc-stripe-sepa-subs-compat.php:397
1117
- #: includes/compat/class-wc-stripe-subs-compat.php:409
1118
  msgid ""
1119
  "Invalid customer ID. A valid \"Stripe Customer ID\" must begin with "
1120
  "\"cus_\"."
1121
  msgstr ""
1122
 
1123
- #: includes/compat/class-wc-stripe-sepa-subs-compat.php:406
1124
- #: includes/compat/class-wc-stripe-subs-compat.php:418
1125
  msgid ""
1126
  "Invalid source ID. A valid source \"Stripe Source ID\" must begin with "
1127
  "\"src_\" or \"card_\"."
1128
  msgstr ""
1129
 
1130
- #: includes/compat/class-wc-stripe-sepa-subs-compat.php:479
1131
  #. translators: 1) last 4 digits of SEPA Direct Debit
1132
  msgid "Via SEPA Direct Debit ending in %1$s"
1133
  msgstr ""
1134
 
1135
- #: includes/compat/class-wc-stripe-subs-compat.php:140
1136
  msgid ""
1137
  "Sorry, we're not accepting prepaid cards at this time. Your credit card has "
1138
  "not been charge. Please try with alternative payment method."
1139
  msgstr ""
1140
 
1141
- #: includes/compat/class-wc-stripe-subs-compat.php:499
1142
  #. translators: 1) card brand 2) last 4 digits
1143
  msgid "Via %1$s card ending in %2$s"
1144
  msgstr ""
1145
 
1146
  #: includes/payment-methods/class-wc-gateway-stripe-alipay.php:60
1147
- #: woocommerce-gateway-stripe.php:252
1148
  msgid "Stripe Alipay"
1149
  msgstr ""
1150
 
@@ -1173,27 +1152,27 @@ msgid "Add Payment"
1173
  msgstr ""
1174
 
1175
  #: includes/payment-methods/class-wc-gateway-stripe-bancontact.php:60
1176
- #: woocommerce-gateway-stripe.php:246
1177
  msgid "Stripe Bancontact"
1178
  msgstr ""
1179
 
1180
  #: includes/payment-methods/class-wc-gateway-stripe-eps.php:60
1181
- #: woocommerce-gateway-stripe.php:249
1182
  msgid "Stripe EPS"
1183
  msgstr ""
1184
 
1185
  #: includes/payment-methods/class-wc-gateway-stripe-giropay.php:60
1186
- #: woocommerce-gateway-stripe.php:248
1187
  msgid "Stripe Giropay"
1188
  msgstr ""
1189
 
1190
  #: includes/payment-methods/class-wc-gateway-stripe-ideal.php:60
1191
- #: woocommerce-gateway-stripe.php:250
1192
  msgid "Stripe iDeal"
1193
  msgstr ""
1194
 
1195
  #: includes/payment-methods/class-wc-gateway-stripe-multibanco.php:60
1196
- #: woocommerce-gateway-stripe.php:254
1197
  msgid "Stripe Multibanco"
1198
  msgstr ""
1199
 
@@ -1222,12 +1201,12 @@ msgid "Awaiting Multibanco payment"
1222
  msgstr ""
1223
 
1224
  #: includes/payment-methods/class-wc-gateway-stripe-p24.php:60
1225
- #: woocommerce-gateway-stripe.php:251
1226
  msgid "Stripe P24"
1227
  msgstr ""
1228
 
1229
  #: includes/payment-methods/class-wc-gateway-stripe-sepa.php:75
1230
- #: woocommerce-gateway-stripe.php:253
1231
  msgid "Stripe SEPA Direct Debit"
1232
  msgstr ""
1233
 
@@ -1254,61 +1233,61 @@ msgid ""
1254
  msgstr ""
1255
 
1256
  #: includes/payment-methods/class-wc-gateway-stripe-sofort.php:60
1257
- #: woocommerce-gateway-stripe.php:247
1258
  msgid "Stripe SOFORT"
1259
  msgstr ""
1260
 
1261
- #: includes/payment-methods/class-wc-stripe-payment-request.php:269
1262
- #: includes/payment-methods/class-wc-stripe-payment-request.php:852
1263
- #: includes/payment-methods/class-wc-stripe-payment-request.php:1150
1264
  msgid "Tax"
1265
  msgstr ""
1266
 
1267
- #: includes/payment-methods/class-wc-stripe-payment-request.php:277
1268
- #: includes/payment-methods/class-wc-stripe-payment-request.php:860
1269
- #: includes/payment-methods/class-wc-stripe-payment-request.php:1157
1270
  msgid "Shipping"
1271
  msgstr ""
1272
 
1273
- #: includes/payment-methods/class-wc-stripe-payment-request.php:284
1274
- #: includes/payment-methods/class-wc-stripe-payment-request.php:867
1275
  msgid "Pending"
1276
  msgstr ""
1277
 
1278
- #: includes/payment-methods/class-wc-stripe-payment-request.php:504
1279
  msgid "Sorry, we're not accepting prepaid cards at this time."
1280
  msgstr ""
1281
 
1282
- #: includes/payment-methods/class-wc-stripe-payment-request.php:506
1283
  #. translators: Do not translate the [option] placeholder
1284
  msgid "Unknown shipping option \"[option]\"."
1285
  msgstr ""
1286
 
1287
- #: includes/payment-methods/class-wc-stripe-payment-request.php:632
1288
  msgid "OR"
1289
  msgstr ""
1290
 
1291
- #: includes/payment-methods/class-wc-stripe-payment-request.php:726
1292
- #: includes/payment-methods/class-wc-stripe-payment-request.php:739
1293
  msgid "Unable to find shipping method for address."
1294
  msgstr ""
1295
 
1296
- #: includes/payment-methods/class-wc-stripe-payment-request.php:808
1297
  msgid "Product with the ID (%d) cannot be found."
1298
  msgstr ""
1299
 
1300
- #: includes/payment-methods/class-wc-stripe-payment-request.php:835
1301
  #. translators: 1: product name 2: quantity in stock
1302
  msgid ""
1303
  "You cannot add that amount of \"%1$s\"; to the cart because there is not "
1304
  "enough stock (%2$s remaining)."
1305
  msgstr ""
1306
 
1307
- #: includes/payment-methods/class-wc-stripe-payment-request.php:989
1308
  msgid "Empty cart"
1309
  msgstr ""
1310
 
1311
- #: includes/payment-methods/class-wc-stripe-payment-request.php:1164
1312
  msgid "Discount"
1313
  msgstr ""
1314
 
@@ -1319,15 +1298,15 @@ msgid ""
1319
  "here."
1320
  msgstr ""
1321
 
1322
- #: woocommerce-gateway-stripe.php:193
1323
  msgid "Settings"
1324
  msgstr ""
1325
 
1326
- #: woocommerce-gateway-stripe.php:194
1327
  msgid "Docs"
1328
  msgstr ""
1329
 
1330
- #: woocommerce-gateway-stripe.php:195
1331
  msgid "Support"
1332
  msgstr ""
1333
 
2
  # This file is distributed under the same license as the WooCommerce Stripe Gateway package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: WooCommerce Stripe Gateway 4.2.0\n"
6
  "Report-Msgid-Bugs-To: "
7
  "https://wordpress.org/support/plugin/woocommerce-gateway-stripe\n"
8
+ "POT-Creation-Date: 2019-06-03 15:42:48+00:00\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=utf-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
29
  msgstr ""
30
 
31
  #: includes/abstracts/abstract-wc-stripe-payment-gateway.php:245
32
+ #: includes/compat/class-wc-stripe-sepa-subs-compat.php:216
33
+ #: includes/compat/class-wc-stripe-subs-compat.php:197
34
  #. translators: 1) dollar amount
35
  #. translators: minimum amount
36
  msgid "Sorry, the minimum allowed order total is %1$s to use this payment method."
49
  msgid "customer_email"
50
  msgstr ""
51
 
52
+ #: includes/abstracts/abstract-wc-stripe-payment-gateway.php:432
53
  #. translators: transaction id
54
  msgid "Stripe charge awaiting payment: %s."
55
  msgstr ""
56
 
57
+ #: includes/abstracts/abstract-wc-stripe-payment-gateway.php:439
58
+ #: includes/class-wc-stripe-order-handler.php:296
59
+ #: includes/class-wc-stripe-webhook-handler.php:315
60
+ #: includes/class-wc-stripe-webhook-handler.php:367
61
  #. translators: transaction id
62
  msgid "Stripe charge complete (Charge ID: %s)"
63
  msgstr ""
64
 
65
+ #: includes/abstracts/abstract-wc-stripe-payment-gateway.php:444
66
+ #: includes/class-wc-gateway-stripe.php:522
67
+ #: includes/compat/class-wc-stripe-sepa-subs-compat.php:173
68
+ #: includes/compat/class-wc-stripe-subs-compat.php:136
69
  msgid "Payment processing failed. Please retry."
70
  msgstr ""
71
 
72
+ #: includes/abstracts/abstract-wc-stripe-payment-gateway.php:456
73
  #. translators: transaction id
74
  msgid ""
75
  "Stripe charge authorized (Charge ID: %s). Process order to take payment, or "
76
  "cancel to remove the pre-authorization."
77
  msgstr ""
78
 
79
+ #: includes/abstracts/abstract-wc-stripe-payment-gateway.php:627
80
  msgid "Invalid payment method. Please input a new card number."
81
  msgstr ""
82
 
83
+ #: includes/abstracts/abstract-wc-stripe-payment-gateway.php:908
84
  #. translators: 1) dollar amount 2) transaction id 3) refund message
85
  msgid "Refunded %1$s - Refund ID: %2$s - Reason: %3$s"
86
  msgstr ""
87
 
88
+ #: includes/abstracts/abstract-wc-stripe-payment-gateway.php:908
89
  msgid "Pre-Authorization Released"
90
  msgstr ""
91
 
92
+ #: includes/abstracts/abstract-wc-stripe-payment-gateway.php:926
93
  msgid "There was a problem adding the payment method."
94
  msgstr ""
95
 
96
+ #: includes/admin/class-wc-stripe-admin-notices.php:122
97
+ #. translators: 1) A URL that explains Stripe Radar.
98
  msgid ""
99
+ "WooCommerce Stripe - We see that you had the \"Require 3D secure when "
100
+ "applicable\" setting turned on. This setting is not available here anymore, "
101
+ "because it is now replaced by Stripe Radar. You can learn more about it <a "
102
+ "href=\"%s\">here</a>."
103
  msgstr ""
104
 
105
+ #: includes/admin/class-wc-stripe-admin-notices.php:129
106
  #. translators: 1) int version 2) int version
107
  msgid ""
108
  "WooCommerce Stripe - We recently made changes to Stripe that may impact the "
112
  "target=\"_blank\">instructions</a> to fix."
113
  msgstr ""
114
 
115
+ #: includes/admin/class-wc-stripe-admin-notices.php:139
116
  #. translators: 1) int version 2) int version
117
  msgid ""
118
  "WooCommerce Stripe - The minimum PHP version required for this plugin is "
119
  "%1$s. You are running %2$s."
120
  msgstr ""
121
 
122
+ #: includes/admin/class-wc-stripe-admin-notices.php:150
123
  #. translators: 1) int version 2) int version
124
  msgid ""
125
  "WooCommerce Stripe - The minimum WooCommerce version required for this "
126
  "plugin is %1$s. You are running %2$s."
127
  msgstr ""
128
 
129
+ #: includes/admin/class-wc-stripe-admin-notices.php:160
130
  msgid "WooCommerce Stripe - cURL is not installed."
131
  msgstr ""
132
 
133
+ #: includes/admin/class-wc-stripe-admin-notices.php:170
134
  #. translators: 1) link
135
  msgid ""
136
  "Stripe is almost ready. To get started, <a href=\"%s\">set your Stripe "
137
  "account keys</a>."
138
  msgstr ""
139
 
140
+ #: includes/admin/class-wc-stripe-admin-notices.php:181
141
  #. translators: 1) link
142
  msgid ""
143
  "Stripe is in test mode however your test keys may not be valid. Test keys "
145
  "<a href=\"%s\">set your Stripe account keys</a>."
146
  msgstr ""
147
 
148
+ #: includes/admin/class-wc-stripe-admin-notices.php:190
149
  #. translators: 1) link
150
  msgid ""
151
  "Stripe is in live mode however your test keys may not be valid. Live keys "
153
  "<a href=\"%s\">set your Stripe account keys</a>."
154
  msgstr ""
155
 
156
+ #: includes/admin/class-wc-stripe-admin-notices.php:199
157
  #. translators: 1) link
158
  msgid ""
159
  "Stripe is enabled, but a SSL certificate is not detected. Your checkout may "
161
  "target=\"_blank\">SSL certificate</a>"
162
  msgstr ""
163
 
164
+ #: includes/admin/class-wc-stripe-admin-notices.php:223
165
  #. translators: %1$s Payment method, %2$s List of supported currencies
166
  msgid "%1$s is enabled - it requires store currency to be set to %2$s"
167
  msgstr ""
168
 
169
+ #: includes/admin/class-wc-stripe-admin-notices.php:237
170
  msgid "Action failed. Please refresh the page and retry."
171
  msgstr ""
172
 
173
+ #: includes/admin/class-wc-stripe-admin-notices.php:241
174
  msgid "Cheatin&#8217; huh?"
175
  msgstr ""
176
 
177
  #: includes/admin/class-wc-stripe-privacy.php:12
178
+ #: includes/class-wc-gateway-stripe.php:88
179
  msgid "Stripe"
180
  msgstr ""
181
 
205
  msgstr ""
206
 
207
  #: includes/admin/class-wc-stripe-privacy.php:41
208
+ #: includes/compat/class-wc-stripe-sepa-subs-compat.php:463
209
+ #: includes/compat/class-wc-stripe-subs-compat.php:475
210
+ #: includes/compat/class-wc-stripe-subs-compat.php:490
211
  msgid "N/A"
212
  msgstr ""
213
 
612
  msgstr ""
613
 
614
  #: includes/admin/stripe-settings.php:95
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
615
  msgid "Payment Request Buttons"
616
  msgstr ""
617
 
618
+ #: includes/admin/stripe-settings.php:97
619
  #. translators: 1) br tag 2) opening anchor tag 3) closing anchor tag
620
  msgid ""
621
  "Enable Payment Request Buttons. (Apple Pay/Chrome Payment Request API) "
622
  "%1$sBy using Apple Pay, you agree to %2$s and %3$s's terms of service."
623
  msgstr ""
624
 
625
+ #: includes/admin/stripe-settings.php:99
626
  msgid ""
627
  "If enabled, users will be able to pay using Apple Pay or Chrome Payment "
628
  "Request if supported by the browser."
629
  msgstr ""
630
 
631
+ #: includes/admin/stripe-settings.php:104
632
  msgid "Payment Request Button Type"
633
  msgstr ""
634
 
635
+ #: includes/admin/stripe-settings.php:105
636
  msgid "Button Type"
637
  msgstr ""
638
 
639
+ #: includes/admin/stripe-settings.php:107
640
  msgid "Select the button type you would like to show."
641
  msgstr ""
642
 
643
+ #: includes/admin/stripe-settings.php:111
644
  msgid "Default"
645
  msgstr ""
646
 
647
+ #: includes/admin/stripe-settings.php:112
648
  msgid "Buy"
649
  msgstr ""
650
 
651
+ #: includes/admin/stripe-settings.php:113
652
  msgid "Donate"
653
  msgstr ""
654
 
655
+ #: includes/admin/stripe-settings.php:117
656
  msgid "Payment Request Button Theme"
657
  msgstr ""
658
 
659
+ #: includes/admin/stripe-settings.php:118
660
  msgid "Button Theme"
661
  msgstr ""
662
 
663
+ #: includes/admin/stripe-settings.php:120
664
  msgid "Select the button theme you would like to show."
665
  msgstr ""
666
 
667
+ #: includes/admin/stripe-settings.php:124
668
  msgid "Dark"
669
  msgstr ""
670
 
671
+ #: includes/admin/stripe-settings.php:125
672
  msgid "Light"
673
  msgstr ""
674
 
675
+ #: includes/admin/stripe-settings.php:126
676
  msgid "Light-Outline"
677
  msgstr ""
678
 
679
+ #: includes/admin/stripe-settings.php:130
680
  msgid "Payment Request Button Height"
681
  msgstr ""
682
 
683
+ #: includes/admin/stripe-settings.php:131
684
  msgid "Button Height"
685
  msgstr ""
686
 
687
+ #: includes/admin/stripe-settings.php:133
688
  msgid ""
689
  "Enter the height you would like the button to be in pixels. Width will "
690
  "always be 100%."
691
  msgstr ""
692
 
693
+ #: includes/admin/stripe-settings.php:138
694
  msgid "Saved Cards"
695
  msgstr ""
696
 
697
+ #: includes/admin/stripe-settings.php:139
698
  msgid "Enable Payment via Saved Cards"
699
  msgstr ""
700
 
701
+ #: includes/admin/stripe-settings.php:141
702
  msgid ""
703
  "If enabled, users will be able to pay with a saved card during checkout. "
704
  "Card details are saved on Stripe servers, not on your store."
705
  msgstr ""
706
 
707
+ #: includes/admin/stripe-settings.php:146
708
  msgid "Logging"
709
  msgstr ""
710
 
711
+ #: includes/admin/stripe-settings.php:147
712
  msgid "Log debug messages"
713
  msgstr ""
714
 
715
+ #: includes/admin/stripe-settings.php:149
716
  msgid "Save debug messages to the WooCommerce System Status log."
717
  msgstr ""
718
 
738
  msgid "You will be redirected to SOFORT."
739
  msgstr ""
740
 
741
+ #: includes/class-wc-gateway-stripe.php:90
742
  #. translators: 1) link to Stripe register page 2) link to Stripe api keys page
743
  msgid ""
744
  "Stripe works by adding payment fields on the checkout and then sending the "
747
  "your Stripe account keys</a>."
748
  msgstr ""
749
 
750
+ #: includes/class-wc-gateway-stripe.php:189
 
 
 
 
751
  #. translators: 1) Opening anchor tag 2) closing anchor tag
752
  msgid ""
753
  "If your billing address has been changed for saved payment methods, be sure "
754
  "to remove any %1$ssaved payment methods%2$s on file and re-add them."
755
  msgstr ""
756
 
757
+ #: includes/class-wc-gateway-stripe.php:250
758
  msgid "Add Card"
759
  msgstr ""
760
 
761
+ #: includes/class-wc-gateway-stripe.php:256
762
  msgid "Change Payment Method"
763
  msgstr ""
764
 
765
+ #: includes/class-wc-gateway-stripe.php:277
766
  #. translators: link to Stripe testing page
767
  msgid ""
768
  "TEST MODE ENABLED. In test mode, you can use the card number "
771
  "card numbers."
772
  msgstr ""
773
 
774
+ #: includes/class-wc-gateway-stripe.php:316
775
  msgid "Credit or debit card"
776
  msgstr ""
777
 
778
+ #: includes/class-wc-gateway-stripe.php:324
779
  msgid "Card Number"
780
  msgstr ""
781
 
782
+ #: includes/class-wc-gateway-stripe.php:335
783
  msgid "Expiry Date"
784
  msgstr ""
785
 
786
+ #: includes/class-wc-gateway-stripe.php:343
787
  msgid "Card Code (CVC)"
788
  msgstr ""
789
 
790
+ #: includes/class-wc-gateway-stripe.php:418
791
  msgid "Please accept the terms and conditions first"
792
  msgstr ""
793
 
794
+ #: includes/class-wc-gateway-stripe.php:419
795
  msgid "Please fill in required checkout fields first"
796
  msgstr ""
797
 
798
+ #: includes/class-wc-gateway-stripe.php:448
799
+ #: includes/class-wc-gateway-stripe.php:509
800
  msgid ""
801
  "Sorry, we're not accepting prepaid cards at this time. Your credit card has "
802
  "not been charged. Please try with alternative payment method."
803
  msgstr ""
804
 
805
+ #: includes/class-wc-gateway-stripe.php:449
806
  msgid "Please enter your IBAN account name."
807
  msgstr ""
808
 
809
+ #: includes/class-wc-gateway-stripe.php:450
810
  msgid "Please enter your IBAN account number."
811
  msgstr ""
812
 
813
+ #: includes/class-wc-gateway-stripe.php:451
814
+ msgid "We couldn't initiate the payment. Please try again."
815
+ msgstr ""
816
+
817
+ #: includes/class-wc-gateway-stripe.php:462
818
  msgid "Billing First Name and Last Name are required."
819
  msgstr ""
820
 
821
+ #: includes/class-wc-gateway-stripe.php:713
822
+ #. translators: error message
823
+ msgid "This represents the fee Stripe collects for the transaction."
824
  msgstr ""
825
 
826
+ #: includes/class-wc-gateway-stripe.php:714
827
+ msgid "Stripe Fee:"
828
+ msgstr ""
829
+
830
+ #: includes/class-wc-gateway-stripe.php:750
831
+ msgid ""
832
+ "This represents the net total that will be credited to your Stripe bank "
833
+ "account. This may be in the currency that is set in your Stripe account."
834
  msgstr ""
835
 
836
+ #: includes/class-wc-gateway-stripe.php:751
837
+ msgid "Stripe Payout:"
838
+ msgstr ""
839
+
840
+ #: includes/class-wc-gateway-stripe.php:798
841
  #: includes/class-wc-stripe-order-handler.php:162
842
  #: includes/class-wc-stripe-webhook-handler.php:206
843
+ #: includes/compat/class-wc-stripe-sepa-subs-compat.php:263
844
+ #: includes/compat/class-wc-stripe-subs-compat.php:244
845
  #: includes/payment-methods/class-wc-gateway-stripe-sepa.php:373
846
  msgid ""
847
  "Sorry, we are unable to process your payment at this time. Please retry "
848
  "later."
849
  msgstr ""
850
 
851
+ #: includes/class-wc-gateway-stripe.php:844
852
+ msgid ""
853
+ "Almost there!\n"
854
+ "\n"
855
+ "Your order has already been created, the only thing that still needs to be "
856
+ "done is for you to authorize the payment with your bank."
857
  msgstr ""
858
 
859
+ #: includes/class-wc-gateway-stripe.php:992
860
+ #: includes/class-wc-stripe-webhook-handler.php:635
861
+ #. translators: 1) The error message that was received from Stripe.
862
+ msgid "Stripe SCA authentication failed. Reason: %s"
863
  msgstr ""
864
 
865
+ #: includes/class-wc-gateway-stripe.php:993
866
+ msgid "Stripe SCA authentication failed."
 
 
 
 
 
 
867
  msgstr ""
868
 
869
  #: includes/class-wc-stripe-api.php:138 includes/class-wc-stripe-api.php:172
976
  msgid "The billing country is not accepted by SOFORT. Please try another country."
977
  msgstr ""
978
 
979
+ #: includes/class-wc-stripe-intent-controller.php:58
980
+ msgid "CSRF verification failed."
981
+ msgstr ""
982
+
983
+ #: includes/class-wc-stripe-intent-controller.php:71
984
+ msgid "Missing order ID for payment confirmation"
985
+ msgstr ""
986
+
987
+ #: includes/class-wc-stripe-intent-controller.php:91
988
+ #. translators: Error message text
989
+ msgid "Payment verification error: %s"
990
+ msgstr ""
991
+
992
+ #: includes/class-wc-stripe-order-handler.php:144
993
+ #: includes/class-wc-stripe-webhook-handler.php:187
994
+ #: includes/payment-methods/class-wc-gateway-stripe-sepa.php:353
995
+ msgid "This card is no longer available and has been removed."
996
+ msgstr ""
997
+
998
  #: includes/class-wc-stripe-order-handler.php:194
999
  #. translators: error message
1000
  msgid "Stripe payment failed: %s"
1002
 
1003
  #: includes/class-wc-stripe-order-handler.php:245
1004
  #: includes/class-wc-stripe-order-handler.php:257
1005
+ #: includes/class-wc-stripe-order-handler.php:273
1006
+ #: includes/class-wc-stripe-order-handler.php:285
1007
  #. translators: error message
1008
  msgid "Unable to capture charge! %s"
1009
  msgstr ""
1025
  "Dashboard</a> to review this dispute."
1026
  msgstr ""
1027
 
1028
+ #: includes/class-wc-stripe-webhook-handler.php:310
1029
  #. translators: partial captured amount
1030
  msgid "This charge was partially captured via Stripe Dashboard in the amount of: %s"
1031
  msgstr ""
1032
 
1033
+ #: includes/class-wc-stripe-webhook-handler.php:396
1034
  msgid "This payment failed to clear."
1035
  msgstr ""
1036
 
1037
+ #: includes/class-wc-stripe-webhook-handler.php:429
1038
  msgid "This payment has cancelled."
1039
  msgstr ""
1040
 
1041
+ #: includes/class-wc-stripe-webhook-handler.php:464
1042
  msgid "Refunded via Stripe Dashboard"
1043
  msgstr ""
1044
 
1045
+ #: includes/class-wc-stripe-webhook-handler.php:464
1046
+ #: includes/class-wc-stripe-webhook-handler.php:492
1047
  msgid "Pre-Authorization Released via Stripe Dashboard"
1048
  msgstr ""
1049
 
1050
+ #: includes/class-wc-stripe-webhook-handler.php:492
1051
  #. translators: 1) dollar amount 2) transaction id 3) refund message
1052
  msgid "Refunded %1$s - Refund ID: %2$s - %3$s"
1053
  msgstr ""
1054
 
1055
+ #: includes/class-wc-stripe-webhook-handler.php:514
1056
  #. translators: 1) The URL to the order. 2) The reason type.
1057
  msgid ""
1058
  "A review has been opened for this order. Action is needed. Please go to "
1060
  "Dashboard</a> to review the issue. Reason: (%2$s)"
1061
  msgstr ""
1062
 
1063
+ #: includes/class-wc-stripe-webhook-handler.php:538
1064
  #. translators: 1) The reason type.
1065
  msgid "The opened review for this order is now closed. Reason: (%s)"
1066
  msgstr ""
1074
  msgid "Stripe Transaction Failed (%s)"
1075
  msgstr ""
1076
 
1077
+ #: includes/compat/class-wc-stripe-sepa-subs-compat.php:88
1078
+ #: includes/compat/class-wc-stripe-subs-compat.php:88
1079
  msgid ""
1080
  "Update the Payment Method used for all of my active subscriptions "
1081
  "(optional)."
1082
  msgstr ""
1083
 
1084
+ #: includes/compat/class-wc-stripe-sepa-subs-compat.php:226
1085
+ #: includes/compat/class-wc-stripe-subs-compat.php:207
1086
  msgid "Customer not found"
1087
  msgstr ""
1088
 
1089
+ #: includes/compat/class-wc-stripe-sepa-subs-compat.php:386
1090
+ #: includes/compat/class-wc-stripe-subs-compat.php:398
1091
  #. translators: error message
1092
  msgid "A \"Stripe Customer ID\" value is required."
1093
  msgstr ""
1094
 
1095
+ #: includes/compat/class-wc-stripe-sepa-subs-compat.php:388
1096
+ #: includes/compat/class-wc-stripe-subs-compat.php:400
1097
  msgid ""
1098
  "Invalid customer ID. A valid \"Stripe Customer ID\" must begin with "
1099
  "\"cus_\"."
1100
  msgstr ""
1101
 
1102
+ #: includes/compat/class-wc-stripe-sepa-subs-compat.php:397
1103
+ #: includes/compat/class-wc-stripe-subs-compat.php:409
1104
  msgid ""
1105
  "Invalid source ID. A valid source \"Stripe Source ID\" must begin with "
1106
  "\"src_\" or \"card_\"."
1107
  msgstr ""
1108
 
1109
+ #: includes/compat/class-wc-stripe-sepa-subs-compat.php:470
1110
  #. translators: 1) last 4 digits of SEPA Direct Debit
1111
  msgid "Via SEPA Direct Debit ending in %1$s"
1112
  msgstr ""
1113
 
1114
+ #: includes/compat/class-wc-stripe-subs-compat.php:131
1115
  msgid ""
1116
  "Sorry, we're not accepting prepaid cards at this time. Your credit card has "
1117
  "not been charge. Please try with alternative payment method."
1118
  msgstr ""
1119
 
1120
+ #: includes/compat/class-wc-stripe-subs-compat.php:490
1121
  #. translators: 1) card brand 2) last 4 digits
1122
  msgid "Via %1$s card ending in %2$s"
1123
  msgstr ""
1124
 
1125
  #: includes/payment-methods/class-wc-gateway-stripe-alipay.php:60
1126
+ #: woocommerce-gateway-stripe.php:253
1127
  msgid "Stripe Alipay"
1128
  msgstr ""
1129
 
1152
  msgstr ""
1153
 
1154
  #: includes/payment-methods/class-wc-gateway-stripe-bancontact.php:60
1155
+ #: woocommerce-gateway-stripe.php:247
1156
  msgid "Stripe Bancontact"
1157
  msgstr ""
1158
 
1159
  #: includes/payment-methods/class-wc-gateway-stripe-eps.php:60
1160
+ #: woocommerce-gateway-stripe.php:250
1161
  msgid "Stripe EPS"
1162
  msgstr ""
1163
 
1164
  #: includes/payment-methods/class-wc-gateway-stripe-giropay.php:60
1165
+ #: woocommerce-gateway-stripe.php:249
1166
  msgid "Stripe Giropay"
1167
  msgstr ""
1168
 
1169
  #: includes/payment-methods/class-wc-gateway-stripe-ideal.php:60
1170
+ #: woocommerce-gateway-stripe.php:251
1171
  msgid "Stripe iDeal"
1172
  msgstr ""
1173
 
1174
  #: includes/payment-methods/class-wc-gateway-stripe-multibanco.php:60
1175
+ #: woocommerce-gateway-stripe.php:255
1176
  msgid "Stripe Multibanco"
1177
  msgstr ""
1178
 
1201
  msgstr ""
1202
 
1203
  #: includes/payment-methods/class-wc-gateway-stripe-p24.php:60
1204
+ #: woocommerce-gateway-stripe.php:252
1205
  msgid "Stripe P24"
1206
  msgstr ""
1207
 
1208
  #: includes/payment-methods/class-wc-gateway-stripe-sepa.php:75
1209
+ #: woocommerce-gateway-stripe.php:254
1210
  msgid "Stripe SEPA Direct Debit"
1211
  msgstr ""
1212
 
1233
  msgstr ""
1234
 
1235
  #: includes/payment-methods/class-wc-gateway-stripe-sofort.php:60
1236
+ #: woocommerce-gateway-stripe.php:248
1237
  msgid "Stripe SOFORT"
1238
  msgstr ""
1239
 
1240
+ #: includes/payment-methods/class-wc-stripe-payment-request.php:261
1241
+ #: includes/payment-methods/class-wc-stripe-payment-request.php:849
1242
+ #: includes/payment-methods/class-wc-stripe-payment-request.php:1147
1243
  msgid "Tax"
1244
  msgstr ""
1245
 
1246
+ #: includes/payment-methods/class-wc-stripe-payment-request.php:269
1247
+ #: includes/payment-methods/class-wc-stripe-payment-request.php:857
1248
+ #: includes/payment-methods/class-wc-stripe-payment-request.php:1154
1249
  msgid "Shipping"
1250
  msgstr ""
1251
 
1252
+ #: includes/payment-methods/class-wc-stripe-payment-request.php:276
1253
+ #: includes/payment-methods/class-wc-stripe-payment-request.php:864
1254
  msgid "Pending"
1255
  msgstr ""
1256
 
1257
+ #: includes/payment-methods/class-wc-stripe-payment-request.php:496
1258
  msgid "Sorry, we're not accepting prepaid cards at this time."
1259
  msgstr ""
1260
 
1261
+ #: includes/payment-methods/class-wc-stripe-payment-request.php:498
1262
  #. translators: Do not translate the [option] placeholder
1263
  msgid "Unknown shipping option \"[option]\"."
1264
  msgstr ""
1265
 
1266
+ #: includes/payment-methods/class-wc-stripe-payment-request.php:629
1267
  msgid "OR"
1268
  msgstr ""
1269
 
1270
+ #: includes/payment-methods/class-wc-stripe-payment-request.php:723
1271
+ #: includes/payment-methods/class-wc-stripe-payment-request.php:736
1272
  msgid "Unable to find shipping method for address."
1273
  msgstr ""
1274
 
1275
+ #: includes/payment-methods/class-wc-stripe-payment-request.php:805
1276
  msgid "Product with the ID (%d) cannot be found."
1277
  msgstr ""
1278
 
1279
+ #: includes/payment-methods/class-wc-stripe-payment-request.php:832
1280
  #. translators: 1: product name 2: quantity in stock
1281
  msgid ""
1282
  "You cannot add that amount of \"%1$s\"; to the cart because there is not "
1283
  "enough stock (%2$s remaining)."
1284
  msgstr ""
1285
 
1286
+ #: includes/payment-methods/class-wc-stripe-payment-request.php:986
1287
  msgid "Empty cart"
1288
  msgstr ""
1289
 
1290
+ #: includes/payment-methods/class-wc-stripe-payment-request.php:1161
1291
  msgid "Discount"
1292
  msgstr ""
1293
 
1298
  "here."
1299
  msgstr ""
1300
 
1301
+ #: woocommerce-gateway-stripe.php:194
1302
  msgid "Settings"
1303
  msgstr ""
1304
 
1305
+ #: woocommerce-gateway-stripe.php:195
1306
  msgid "Docs"
1307
  msgstr ""
1308
 
1309
+ #: woocommerce-gateway-stripe.php:196
1310
  msgid "Support"
1311
  msgstr ""
1312
 
readme.txt CHANGED
@@ -2,9 +2,9 @@
2
  Contributors: automattic, royho, akeda, mattyza, bor0, woothemes
3
  Tags: credit card, stripe, apple pay, payment request, google pay, sepa, sofort, bancontact, alipay, giropay, ideal, p24, woocommerce, automattic
4
  Requires at least: 4.4
5
- Tested up to: 5.1
6
  Requires PHP: 5.6
7
- Stable tag: 4.1.16
8
  License: GPLv3
9
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
10
  Attributions: thorsten-stripe
@@ -13,24 +13,38 @@ Take credit card payments on your store using Stripe.
13
 
14
  == Description ==
15
 
16
- Accept Visa, MasterCard, American Express, Discover, JCB, Diners Club, SEPA, Sofort, iDeal, Giropay, Alipay and more directly on your store with the Stripe payment gateway for WooCommerce, including Apple Pay for mobile and desktop.
17
 
18
  = Take Credit card payments easily and directly on your store =
19
 
20
  The Stripe plugin extends WooCommerce allowing you to take payments directly on your store via Stripe’s API.
21
 
22
- Stripe is available in:
23
 
24
- * United States
25
- * Canada
26
- * UK
27
  * Australia
 
28
  * Belgium
 
 
 
29
  * France
30
  * Germany
 
31
  * Ireland
32
- * The Netherlands
33
- * [and more](https://support.stripe.com/questions/what-countries-does-stripe-support)
 
 
 
 
 
 
 
 
 
 
 
 
34
 
35
  Stripe is a simple way to accept payments online. With Stripe you can accept Visa, MasterCard, American Express, Discover, JCB, and Diners Club cards, even Bitcoin, directly on your store.
36
 
@@ -38,15 +52,15 @@ Stripe is a simple way to accept payments online. With Stripe you can accept Vis
38
 
39
  Stripe has no setup fees, no monthly fees, no hidden costs: you only get charged when you earn money! Earnings are transferred to your bank account on a 7-day rolling basis.
40
 
41
- Stripe also supports the [Subscriptions extension](https://woocommerce.com/products/woocommerce-subscriptions/) and re-using cards. When a customer pays, they are set up in Stripe as a customer. If they create another order, they can check out using the same card. A massive timesaver for returning customers.
42
 
43
  = Apple Pay Support =
44
 
45
- WooCommerce Stripe now includes [Apple Pay](https://stripe.com/apple-pay) support, which means customers can pay using payment details associated to their Apple ID. Checkout is now just a thumbprint away. on both mobile and desktop. Only supports simple and variable products for now. More support to come.
46
 
47
  = Web Payments API Support =
48
 
49
- WooCommerce Stripe now includes [Web Payments API](https://www.w3.org/TR/payment-request/) support, which means customers can pay using payment details associated to their mobile devices, in browsers supporting the Web Payments API (Chrome for Android, amongst others). Checkout is now just a few taps away. on mobile. Only supports simple and variable products for now. More support to come.
50
 
51
  == Installation ==
52
 
@@ -56,10 +70,9 @@ You can download an [older version of this gateway for older versions of WooComm
56
 
57
  = Automatic installation =
58
 
59
- Automatic installation is the easiest option as WordPress handles the file transfers itself and you don’t need to leave your web browser. To
60
- do an automatic install of, log in to your WordPress dashboard, navigate to the Plugins menu and click Add New.
61
 
62
- In the search field type “WooCommerce Stripe Payment Gateway” and click Search Plugins. Once you’ve found our plugin you can view details about it such as the point release, rating and description. Most importantly of course, you can install it by simply clicking "Install Now".
63
 
64
  = Manual installation =
65
 
@@ -77,15 +90,15 @@ Yes!
77
 
78
  = Does this require an SSL certificate? =
79
 
80
- Yes! In live mode, an SSL certificate must be installed on your site to use Stripe. In addition to SSL encryption, Stripe provides an extra JavaScript method to secure card data.
81
 
82
  = Does this support both production mode and sandbox mode for testing? =
83
 
84
- Yes it does - production and sandbox mode is driven by the API keys you use.
85
 
86
  = Where can I find documentation? =
87
 
88
- For help setting up and configuring, please refer to our [user guide](https://docs.woocommerce.com/document/stripe/)
89
 
90
  = Where can I get support or talk to other users? =
91
 
@@ -97,15 +110,17 @@ If you get stuck, you can ask for help in the Plugin Forum.
97
  2. Normal checkout with Stripe.
98
  3. Option to save a card to your account.
99
  4. Checking out with a saved card.
100
- 5. Using the Stripe checkout modal.
101
 
102
  == Changelog ==
103
 
104
- = 4.1.16 - 2019-04-18 =
105
- * Deprecate - Warn about the future removal of the Modal Checkout option.
106
- * Tweak - WC 3.6 compatibility.
 
 
 
107
 
108
- [See changelog for all versions](https://raw.githubusercontent.com/woothemes/woocommerce-gateway-stripe/master/changelog.txt).
109
 
110
  == Upgrade Notice ==
111
 
2
  Contributors: automattic, royho, akeda, mattyza, bor0, woothemes
3
  Tags: credit card, stripe, apple pay, payment request, google pay, sepa, sofort, bancontact, alipay, giropay, ideal, p24, woocommerce, automattic
4
  Requires at least: 4.4
5
+ Tested up to: 5.2.1
6
  Requires PHP: 5.6
7
+ Stable tag: 4.2.0
8
  License: GPLv3
9
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
10
  Attributions: thorsten-stripe
13
 
14
  == Description ==
15
 
16
+ Accept Visa, MasterCard, American Express, Discover, JCB, Diners Club, SEPA, Sofort, iDeal, Giropay, Alipay, and more directly on your store with the Stripe payment gateway for WooCommerce, including Apple Pay, Google Pay, and Microsoft Pay for mobile and desktop.
17
 
18
  = Take Credit card payments easily and directly on your store =
19
 
20
  The Stripe plugin extends WooCommerce allowing you to take payments directly on your store via Stripe’s API.
21
 
22
+ Stripe is available for Store Owners and Merchants in:
23
 
 
 
 
24
  * Australia
25
+ * Austria
26
  * Belgium
27
+ * Canada
28
+ * Denmark
29
+ * Finland
30
  * France
31
  * Germany
32
+ * Hong Kong
33
  * Ireland
34
+ * Italy
35
+ * Japan
36
+ * Luxembourg
37
+ * Netherlands
38
+ * New Zealand
39
+ * Norway
40
+ * Portugal
41
+ * Singapore
42
+ * Spain
43
+ * Sweden
44
+ * Switzerland
45
+ * United Kingdom
46
+ * United States
47
+ * [with more being added](https://stripe.com/global)
48
 
49
  Stripe is a simple way to accept payments online. With Stripe you can accept Visa, MasterCard, American Express, Discover, JCB, and Diners Club cards, even Bitcoin, directly on your store.
50
 
52
 
53
  Stripe has no setup fees, no monthly fees, no hidden costs: you only get charged when you earn money! Earnings are transferred to your bank account on a 7-day rolling basis.
54
 
55
+ Stripe also supports the [WooCommerce Subscriptions extension](https://woocommerce.com/products/woocommerce-subscriptions/) and re-using cards. When a customer pays, they are set up in Stripe as a customer. If they create another order, they can check out using the same card. A massive timesaver for returning customers.
56
 
57
  = Apple Pay Support =
58
 
59
+ WooCommerce Stripe now includes [Apple Pay](https://stripe.com/apple-pay) support, which means customers can pay using payment details associated with their Apple ID. Checkout is now just an authorization (Touch ID or Face ID) away on both mobile and desktop. Only supports simple and variable products for now. More support to come.
60
 
61
  = Web Payments API Support =
62
 
63
+ WooCommerce Stripe now includes [Web Payments API](https://www.w3.org/TR/payment-request/) support, which means customers can pay using payment details associated to their mobile devices, in browsers supporting the Web Payments API (Chrome for Android, amongst others). Checkout is now just a few taps away on mobile. Only supports simple and variable products for now. More support to come.
64
 
65
  == Installation ==
66
 
70
 
71
  = Automatic installation =
72
 
73
+ Automatic installation is the easiest option as WordPress handles the file transfers itself and you don’t need to leave your web browser. To do an automatic install of the WooCommerce Stripe plugin, log in to your WordPress dashboard, navigate to the Plugins menu and click Add New.
 
74
 
75
+ In the search field type “WooCommerce Stripe Payment Gateway” and click Search Plugins. Once you’ve found our plugin you can view details about it such as the point release, rating, and description. Most importantly, of course, you can install it by simply clicking "Install Now", then "Activate".
76
 
77
  = Manual installation =
78
 
90
 
91
  = Does this require an SSL certificate? =
92
 
93
+ Yes! In Live Mode, an SSL certificate must be installed on your site to use Stripe. In addition to SSL encryption, Stripe provides an extra JavaScript method to secure card data using [Stripe Elements](https://stripe.com/elements).
94
 
95
  = Does this support both production mode and sandbox mode for testing? =
96
 
97
+ Yes, it does - production and sandbox mode is driven by the API keys you use.
98
 
99
  = Where can I find documentation? =
100
 
101
+ For help setting up and configuring, please refer to our [documentation](https://docs.woocommerce.com/document/stripe/).
102
 
103
  = Where can I get support or talk to other users? =
104
 
110
  2. Normal checkout with Stripe.
111
  3. Option to save a card to your account.
112
  4. Checking out with a saved card.
 
113
 
114
  == Changelog ==
115
 
116
+ = 4.2.0 - 2019-05-29 =
117
+ * Update - Enable Payment Request buttons for Puerto Rico based stores.
118
+ * Update - Add support for Strong Customer Authentication (SCA) for user-initiated payments.
119
+ * Remove - Stripe Modal Checkout.
120
+ * Remove - 3D Secure settings are no longer available in the gateway settings. Use Stripe Radar instead.
121
+ * Fix - Display error messages only next to the chosen saved card.
122
 
123
+ [See changelog for all versions](https://raw.githubusercontent.com/woocommerce/woocommerce-gateway-stripe/master/changelog.txt).
124
 
125
  == Upgrade Notice ==
126
 
woocommerce-gateway-stripe.php CHANGED
@@ -5,11 +5,11 @@
5
  * Description: Take credit card payments on your store using Stripe.
6
  * Author: WooCommerce
7
  * Author URI: https://woocommerce.com/
8
- * Version: 4.1.16
9
  * Requires at least: 4.4
10
- * Tested up to: 5.1
11
  * WC requires at least: 2.6
12
- * WC tested up to: 3.6
13
  * Text Domain: woocommerce-gateway-stripe
14
  * Domain Path: /languages
15
  *
@@ -46,7 +46,7 @@ function woocommerce_gateway_stripe_init() {
46
  /**
47
  * Required minimums and constants
48
  */
49
- define( 'WC_STRIPE_VERSION', '4.1.16' );
50
  define( 'WC_STRIPE_MIN_PHP_VER', '5.6.0' );
51
  define( 'WC_STRIPE_MIN_WC_VER', '2.6.0' );
52
  define( 'WC_STRIPE_MAIN_FILE', __FILE__ );
@@ -133,6 +133,7 @@ function woocommerce_gateway_stripe_init() {
133
  require_once dirname( __FILE__ ) . '/includes/class-wc-stripe-order-handler.php';
134
  require_once dirname( __FILE__ ) . '/includes/class-wc-stripe-payment-tokens.php';
135
  require_once dirname( __FILE__ ) . '/includes/class-wc-stripe-customer.php';
 
136
 
137
  if ( is_admin() ) {
138
  require_once dirname( __FILE__ ) . '/includes/admin/class-wc-stripe-admin-notices.php';
@@ -192,7 +193,7 @@ function woocommerce_gateway_stripe_init() {
192
  $plugin_links = array(
193
  '<a href="admin.php?page=wc-settings&tab=checkout&section=stripe">' . esc_html__( 'Settings', 'woocommerce-gateway-stripe' ) . '</a>',
194
  '<a href="https://docs.woocommerce.com/document/stripe/">' . esc_html__( 'Docs', 'woocommerce-gateway-stripe' ) . '</a>',
195
- '<a href="https://woocommerce.com/contact-us/">' . esc_html__( 'Support', 'woocommerce-gateway-stripe' ) . '</a>',
196
  );
197
  return array_merge( $plugin_links, $links );
198
  }
5
  * Description: Take credit card payments on your store using Stripe.
6
  * Author: WooCommerce
7
  * Author URI: https://woocommerce.com/
8
+ * Version: 4.2.0
9
  * Requires at least: 4.4
10
+ * Tested up to: 5.2.1
11
  * WC requires at least: 2.6
12
+ * WC tested up to: 3.6.4
13
  * Text Domain: woocommerce-gateway-stripe
14
  * Domain Path: /languages
15
  *
46
  /**
47
  * Required minimums and constants
48
  */
49
+ define( 'WC_STRIPE_VERSION', '4.2.0' );
50
  define( 'WC_STRIPE_MIN_PHP_VER', '5.6.0' );
51
  define( 'WC_STRIPE_MIN_WC_VER', '2.6.0' );
52
  define( 'WC_STRIPE_MAIN_FILE', __FILE__ );
133
  require_once dirname( __FILE__ ) . '/includes/class-wc-stripe-order-handler.php';
134
  require_once dirname( __FILE__ ) . '/includes/class-wc-stripe-payment-tokens.php';
135
  require_once dirname( __FILE__ ) . '/includes/class-wc-stripe-customer.php';
136
+ require_once dirname( __FILE__ ) . '/includes/class-wc-stripe-intent-controller.php';
137
 
138
  if ( is_admin() ) {
139
  require_once dirname( __FILE__ ) . '/includes/admin/class-wc-stripe-admin-notices.php';
193
  $plugin_links = array(
194
  '<a href="admin.php?page=wc-settings&tab=checkout&section=stripe">' . esc_html__( 'Settings', 'woocommerce-gateway-stripe' ) . '</a>',
195
  '<a href="https://docs.woocommerce.com/document/stripe/">' . esc_html__( 'Docs', 'woocommerce-gateway-stripe' ) . '</a>',
196
+ '<a href="https://woocommerce.com/my-account/create-a-ticket?broken=primary&select=18627">' . esc_html__( 'Support', 'woocommerce-gateway-stripe' ) . '</a>',
197
  );
198
  return array_merge( $plugin_links, $links );
199
  }