WooCommerce Stripe Payment Gateway - Version 4.7.0

Version Description

  • 2020-12-22 =
  • Fix - Updating subscription payment methods from the "My Account" page now adds a note to the subscription.
  • Fix - Link is now correctly formatted in readme.txt.
  • Fix - Using SCA cards for subscriptions renewal payments now works as intended.
  • Fix - Cards added under "My Account -> Payment Methods -> Add Payment Method" will now handle SCA properly.
  • Fix - Changing a payment method for a subscription in "My Account -> Subscriptions" will now handle SCA properly.
  • Fix - Missing space causing fatal errors for certain WooCommerce Inbox Note features.

See changelog for all versions.

Download this release

Release Info

Developer automattic
Plugin Icon 128x128 WooCommerce Stripe Payment Gateway
Version 4.7.0
Comparing to
See all releases

Code changes from version 4.6.0 to 4.7.0

assets/js/stripe.js CHANGED
@@ -56,7 +56,8 @@ jQuery( function( $ ) {
56
  }
57
 
58
  if ( 'yes' === wc_stripe_params.inline_cc_form ) {
59
- return stripe_card.mount( '#stripe-card-element' );
 
60
  }
61
 
62
  stripe_card.mount( '#stripe-card-element' );
@@ -512,7 +513,8 @@ jQuery( function( $ ) {
512
  */
513
  sourceResponse: function( response ) {
514
  if ( response.error ) {
515
- return $( document.body ).trigger( 'stripeError', response );
 
516
  }
517
 
518
  wc_stripe_form.reset();
@@ -524,13 +526,67 @@ jQuery( function( $ ) {
524
  .val( response.source.id )
525
  );
526
 
527
- if ( $( 'form#add_payment_method' ).length ) {
528
- $( wc_stripe_form.form ).off( 'submit', wc_stripe_form.form.onSubmit );
 
529
  }
530
 
531
  wc_stripe_form.form.trigger( 'submit' );
532
  },
533
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
534
  /**
535
  * Performs payment-related actions when a checkout/payment form is being submitted.
536
  *
@@ -590,7 +646,8 @@ jQuery( function( $ ) {
590
  var errorContainer = wc_stripe_form.getSelectedPaymentElement().parents( 'li' ).eq( 0 ).find( '.stripe-source-errors' );
591
 
592
  if ( ! e.error ) {
593
- return $( errorContainer ).html( '' );
 
594
  }
595
 
596
  console.log( e.error.message ); // Leave for troubleshooting.
@@ -641,7 +698,8 @@ jQuery( function( $ ) {
641
  if ( 'invalid_owner_name' === result.error.code && wc_stripe_params.hasOwnProperty( result.error.code ) ) {
642
  var error = $( '<div><ul class="woocommerce-error"><li /></ul></div>' );
643
  error.find( 'li' ).text( wc_stripe_params[ result.error.code ] ); // Prevent XSS
644
- return wc_stripe_form.submitError( error.html() );
 
645
  }
646
  }
647
 
@@ -786,7 +844,8 @@ jQuery( function( $ ) {
786
  } )
787
  .catch( function( error ) {
788
  if ( alwaysRedirect ) {
789
- return window.location = redirectURL;
 
790
  }
791
 
792
  $( document.body ).trigger( 'stripeError', { error: error } );
56
  }
57
 
58
  if ( 'yes' === wc_stripe_params.inline_cc_form ) {
59
+ stripe_card.mount( '#stripe-card-element' );
60
+ return;
61
  }
62
 
63
  stripe_card.mount( '#stripe-card-element' );
513
  */
514
  sourceResponse: function( response ) {
515
  if ( response.error ) {
516
+ $( document.body ).trigger( 'stripeError', response );
517
+ return;
518
  }
519
 
520
  wc_stripe_form.reset();
526
  .val( response.source.id )
527
  );
528
 
529
+ if ( $( 'form#add_payment_method' ).length || $( '#wc-stripe-change-payment-method' ).length ) {
530
+ wc_stripe_form.sourceSetup( response );
531
+ return;
532
  }
533
 
534
  wc_stripe_form.form.trigger( 'submit' );
535
  },
536
 
537
+ /**
538
+ * Authenticate Source if necessary by creating and confirming a SetupIntent.
539
+ *
540
+ * @param {Object} response The `stripe.createSource` response.
541
+ */
542
+ sourceSetup: function( response ) {
543
+ var apiError = {
544
+ error: {
545
+ type: 'api_connection_error'
546
+ }
547
+ };
548
+
549
+ $.post( {
550
+ url: wc_stripe_form.getAjaxURL( 'create_setup_intent'),
551
+ dataType: 'json',
552
+ data: {
553
+ stripe_source_id: response.source.id,
554
+ nonce: wc_stripe_params.add_card_nonce,
555
+ },
556
+ error: function() {
557
+ $( document.body ).trigger( 'stripeError', apiError );
558
+ }
559
+ } ).done( function( serverResponse ) {
560
+ if ( 'success' === serverResponse.status ) {
561
+ if ( $( 'form#add_payment_method' ).length ) {
562
+ $( wc_stripe_form.form ).off( 'submit', wc_stripe_form.form.onSubmit );
563
+ }
564
+ wc_stripe_form.form.trigger( 'submit' );
565
+ return;
566
+ } else if ( 'requires_action' !== serverResponse.status ) {
567
+ $( document.body ).trigger( 'stripeError', serverResponse );
568
+ return;
569
+ }
570
+
571
+ stripe.confirmCardSetup( serverResponse.client_secret, { payment_method: response.source.id } )
572
+ .then( function( result ) {
573
+ if ( result.error ) {
574
+ $( document.body ).trigger( 'stripeError', result );
575
+ return;
576
+ }
577
+
578
+ if ( $( 'form#add_payment_method' ).length ) {
579
+ $( wc_stripe_form.form ).off( 'submit', wc_stripe_form.form.onSubmit );
580
+ }
581
+ wc_stripe_form.form.trigger( 'submit' );
582
+ } )
583
+ .catch( function( err ) {
584
+ console.log( err );
585
+ $( document.body ).trigger( 'stripeError', { error: err } );
586
+ } );
587
+ } );
588
+ },
589
+
590
  /**
591
  * Performs payment-related actions when a checkout/payment form is being submitted.
592
  *
646
  var errorContainer = wc_stripe_form.getSelectedPaymentElement().parents( 'li' ).eq( 0 ).find( '.stripe-source-errors' );
647
 
648
  if ( ! e.error ) {
649
+ $( errorContainer ).html( '' );
650
+ return;
651
  }
652
 
653
  console.log( e.error.message ); // Leave for troubleshooting.
698
  if ( 'invalid_owner_name' === result.error.code && wc_stripe_params.hasOwnProperty( result.error.code ) ) {
699
  var error = $( '<div><ul class="woocommerce-error"><li /></ul></div>' );
700
  error.find( 'li' ).text( wc_stripe_params[ result.error.code ] ); // Prevent XSS
701
+ wc_stripe_form.submitError( error.html() );
702
+ return;
703
  }
704
  }
705
 
844
  } )
845
  .catch( function( error ) {
846
  if ( alwaysRedirect ) {
847
+ window.location = redirectURL;
848
+ return;
849
  }
850
 
851
  $( document.body ).trigger( 'stripeError', { error: error } );
assets/js/stripe.min.js CHANGED
@@ -1 +1 @@
1
- jQuery(function(c){"use strict";try{var o=Stripe(wc_stripe_params.key)}catch(e){return void console.log(e)}var t,n,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=o.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"),n.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"),n.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}),n=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)}),n.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(){c("#stripe-card-element").children().length||(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),c("#early_renewal_modal_submit").on("click",this.onEarlyRenewalSubmit),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,t.address.line1=c("#billing_address_1").val()||wc_stripe_params.billing_address_1,t.address.line2=c("#billing_address_2").val()||wc_stripe_params.billing_address_2,t.address.state=c("#billing_state").val()||wc_stripe_params.billing_state,t.address.city=c("#billing_city").val()||wc_stripe_params.billing_city,t.address.postal_code=c("#billing_postcode").val()||wc_stripe_params.billing_postcode,t.address.country=c("#billing_country").val()||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",o.createSource(a,e).then(m.sourceResponse)):o.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.trigger("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(c("body").hasClass("woocommerce-stripe-prb-clicked"))c("body").removeClass("woocommerce-stripe-prb-clicked"),t=c("div.woocommerce-notices-wrapper").first();else 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=c('<div><ul class="woocommerce-error"><li /></ul></div>');return a.find("li").text(wc_stripe_params[r.error.code]),m.submitError(a.html())}"email_invalid"===r.error.code?n=wc_stripe_params.email_invalid:"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").trigger("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|si)-([^:]+):(.+)$/);if(e&&!(e.length<4)){var r=e[1],t=e[2],n=decodeURIComponent(e[3]);window.location.hash="",m.openIntentModal(t,n,!1,"si"===r)}},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,!1)}},openIntentModal:function(e,t,r,n){o[n?"handleCardSetup":"handleCardPayment"](e).then(function(e){if(e.error)throw e.error;var r=e[n?"setupIntent":"paymentIntent"];"requires_capture"!==r.status&&"succeeded"!==r.status||(window.location=t)}).catch(function(e){if(r)return window.location=t;c(document.body).trigger("stripeError",{error:e}),m.form&&m.form.removeClass("processing"),c.get(t+"&is_ajax")})},onEarlyRenewalSubmit:function(e){return e.preventDefault(),c.ajax({url:c("#early_renewal_modal_submit").attr("href"),method:"get",success:function(e){var r=JSON.parse(e);r.stripe_sca_required?m.openIntentModal(r.intent_secret,r.redirect_url,!0,!1):window.location=r.redirect_url}}),!1}};m.init()});
1
+ jQuery(function(c){"use strict";try{var n=Stripe(wc_stripe_params.key)}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(){c("#stripe-card-element").length&&("yes"!==wc_stripe_params.inline_cc_form?(t.mount("#stripe-card-element"),o.mount("#stripe-exp-element"),i.mount("#stripe-cvc-element")):t.mount("#stripe-card-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(){c("#stripe-card-element").children().length||(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"),o="stripe-credit-card-brand";e in r&&(o=r[e]),c.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||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),c("#early_renewal_modal_submit").on("click",this.onEarlyRenewalSubmit),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,t.address.line1=c("#billing_address_1").val()||wc_stripe_params.billing_address_1,t.address.line2=c("#billing_address_2").val()||wc_stripe_params.billing_address_2,t.address.state=c("#billing_state").val()||wc_stripe_params.billing_state,t.address.city=c("#billing_city").val()||wc_stripe_params.billing_city,t.address.postal_code=c("#billing_postcode").val()||wc_stripe_params.billing_postcode,t.address.country=c("#billing_country").val()||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){e.error?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("#wc-stripe-change-payment-method").length?m.sourceSetup(e):m.form.trigger("submit"))},sourceSetup:function(r){var e={error:{type:"api_connection_error"}};c.post({url:m.getAjaxURL("create_setup_intent"),dataType:"json",data:{stripe_source_id:r.source.id,nonce:wc_stripe_params.add_card_nonce},error:function(){c(document.body).trigger("stripeError",e)}}).done(function(e){if("success"===e.status)return c("form#add_payment_method").length&&c(m.form).off("submit",m.form.onSubmit),void m.form.trigger("submit");"requires_action"===e.status?n.confirmCardSetup(e.client_secret,{payment_method:r.source.id}).then(function(e){e.error?c(document.body).trigger("stripeError",e):(c("form#add_payment_method").length&&c(m.form).off("submit",m.form.onSubmit),m.form.trigger("submit"))}).catch(function(e){console.log(e),c(document.body).trigger("stripeError",{error:e})}):c(document.body).trigger("stripeError",e)})},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");e.error?(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)):c(r).html("")},onError:function(e,r){var t,o=r.error.message,n=m.getSelectedPaymentElement().closest("li"),i=n.find(".woocommerce-SavedPaymentMethods-tokenInput");if(c("body").hasClass("woocommerce-stripe-prb-clicked"))c("body").removeClass("woocommerce-stripe-prb-clicked"),t=c("div.woocommerce-notices-wrapper").first();else 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=n.find(".stripe-source-errors");if(m.isSepaChosen()&&"invalid_owner_name"===r.error.code&&wc_stripe_params.hasOwnProperty(r.error.code)){var a=c('<div><ul class="woocommerce-error"><li /></ul></div>');return a.find("li").text(wc_stripe_params[r.error.code]),void m.submitError(a.html())}"email_invalid"===r.error.code?o=wc_stripe_params.email_invalid:"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||(o=wc_stripe_params.invalid_request_error),"card_error"===r.error.type&&wc_stripe_params.hasOwnProperty(r.error.code)&&(o=wc_stripe_params[r.error.code]),"validation_error"===r.error.type&&wc_stripe_params.hasOwnProperty(r.error.code)&&(o=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(o),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").trigger("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|si)-([^:]+):(.+)$/);if(e&&!(e.length<4)){var r=e[1],t=e[2],o=decodeURIComponent(e[3]);window.location.hash="",m.openIntentModal(t,o,!1,"si"===r)}},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,!1)}},openIntentModal:function(e,t,r,o){n[o?"handleCardSetup":"handleCardPayment"](e).then(function(e){if(e.error)throw e.error;var r=e[o?"setupIntent":"paymentIntent"];"requires_capture"!==r.status&&"succeeded"!==r.status||(window.location=t)}).catch(function(e){r?window.location=t:(c(document.body).trigger("stripeError",{error:e}),m.form&&m.form.removeClass("processing"),c.get(t+"&is_ajax"))})},onEarlyRenewalSubmit:function(e){return e.preventDefault(),c.ajax({url:c("#early_renewal_modal_submit").attr("href"),method:"get",success:function(e){var r=JSON.parse(e);r.stripe_sca_required?m.openIntentModal(r.intent_secret,r.redirect_url,!0,!1):window.location=r.redirect_url}}),!1}};m.init()});
changelog.txt CHANGED
@@ -1,5 +1,13 @@
1
  *** Changelog ***
2
 
 
 
 
 
 
 
 
 
3
  = 4.6.0 - 2020-12-15 =
4
  * Tweak - Update packages for Composer 2 compatibility.
5
  * Tweak - Use full jQuery function calls instead of soon-to-be-deprecated shorthands.
1
  *** Changelog ***
2
 
3
+ = 4.7.0 - 2020-12-22 =
4
+ * Fix - Updating subscription payment methods from the "My Account" page now adds a note to the subscription.
5
+ * Fix - Link is now correctly formatted in readme.txt.
6
+ * Fix - Using SCA cards for subscriptions renewal payments now works as intended.
7
+ * Fix - Cards added under "My Account -> Payment Methods -> Add Payment Method" will now handle SCA properly.
8
+ * Fix - Changing a payment method for a subscription in "My Account -> Subscriptions" will now handle SCA properly.
9
+ * Fix - Missing space causing fatal errors for certain WooCommerce Inbox Note features.
10
+
11
  = 4.6.0 - 2020-12-15 =
12
  * Tweak - Update packages for Composer 2 compatibility.
13
  * Tweak - Use full jQuery function calls instead of soon-to-be-deprecated shorthands.
includes/abstracts/abstract-wc-stripe-payment-gateway.php CHANGED
@@ -1170,6 +1170,12 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
1170
  $request['customer'] = $prepared_source->customer;
1171
  }
1172
 
 
 
 
 
 
 
1173
  if ( empty( $request ) ) {
1174
  return $intent;
1175
  }
1170
  $request['customer'] = $prepared_source->customer;
1171
  }
1172
 
1173
+ if ( $this->has_subscription( $order ) ) {
1174
+ // If this is a failed subscription order payment, the intent should be
1175
+ // prepared for future usage.
1176
+ $request['setup_future_usage'] = 'off_session';
1177
+ }
1178
+
1179
  if ( empty( $request ) ) {
1180
  return $intent;
1181
  }
includes/admin/class-wc-stripe-inbox-notes.php CHANGED
@@ -42,7 +42,7 @@ class WC_Stripe_Inbox_Notes {
42
  return __( 'Boost sales this holiday season with Apple Pay!', 'woocommerce-gateway-stripe' );
43
  }
44
 
45
- return__( 'Boost sales with Apple Pay!', 'woocommerce-gateway-stripe' );
46
  }
47
 
48
  /**
42
  return __( 'Boost sales this holiday season with Apple Pay!', 'woocommerce-gateway-stripe' );
43
  }
44
 
45
+ return __( 'Boost sales with Apple Pay!', 'woocommerce-gateway-stripe' );
46
  }
47
 
48
  /**
includes/class-wc-gateway-stripe.php CHANGED
@@ -455,6 +455,7 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
455
  $stripe_params['is_pay_for_order_page'] = is_wc_endpoint_url( 'order-pay' ) ? 'yes' : 'no';
456
  $stripe_params['elements_styling'] = apply_filters( 'wc_stripe_elements_styling', false );
457
  $stripe_params['elements_classes'] = apply_filters( 'wc_stripe_elements_classes', false );
 
458
 
459
  // Merge localized messages to be use in JS.
460
  $stripe_params = array_merge( $stripe_params, WC_Stripe_Helper::get_localized_messages() );
455
  $stripe_params['is_pay_for_order_page'] = is_wc_endpoint_url( 'order-pay' ) ? 'yes' : 'no';
456
  $stripe_params['elements_styling'] = apply_filters( 'wc_stripe_elements_styling', false );
457
  $stripe_params['elements_classes'] = apply_filters( 'wc_stripe_elements_classes', false );
458
+ $stripe_params['add_card_nonce'] = wp_create_nonce( 'wc_stripe_create_si' );
459
 
460
  // Merge localized messages to be use in JS.
461
  $stripe_params = array_merge( $stripe_params, WC_Stripe_Helper::get_localized_messages() );
includes/class-wc-stripe-customer.php CHANGED
@@ -232,40 +232,36 @@ class WC_Stripe_Customer {
232
  );
233
  }
234
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
  /**
236
  * Add a source for this stripe customer.
237
  * @param string $source_id
238
  * @return WP_Error|int
239
  */
240
  public function add_source( $source_id ) {
241
- if ( ! $this->get_id() ) {
242
- $this->set_id( $this->create_customer() );
 
243
  }
244
 
245
- $response = WC_Stripe_API::request(
246
- array(
247
- 'source' => $source_id,
248
- ),
249
- 'customers/' . $this->get_id() . '/sources'
250
- );
251
-
252
  $wc_token = false;
253
 
254
- if ( ! empty( $response->error ) ) {
255
- // It is possible the WC user once was linked to a customer on Stripe
256
- // but no longer exists. Instead of failing, lets try to create a
257
- // new customer.
258
- if ( $this->is_no_such_customer_error( $response->error ) ) {
259
- $this->recreate_customer();
260
- return $this->add_source( $source_id );
261
- } else {
262
- return $response;
263
- }
264
- } elseif ( empty( $response->id ) ) {
265
- return new WP_Error( 'error', __( 'Unable to add payment source.', 'woocommerce-gateway-stripe' ) );
266
- }
267
-
268
- // Add token to WooCommerce.
269
  if ( $this->get_user_id() && class_exists( 'WC_Payment_Token_CC' ) ) {
270
  if ( ! empty( $response->type ) ) {
271
  switch ( $response->type ) {
@@ -311,6 +307,43 @@ class WC_Stripe_Customer {
311
  return $response->id;
312
  }
313
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
314
  /**
315
  * Get a customers saved sources using their Stripe ID.
316
  *
232
  );
233
  }
234
 
235
+ /**
236
+ * Checks to see if error is of invalid request
237
+ * error and it is no such customer.
238
+ *
239
+ * @since 4.5.6
240
+ * @param array $error
241
+ * @return bool
242
+ */
243
+ public function is_source_already_attached_error( $error ) {
244
+ return (
245
+ $error &&
246
+ 'invalid_request_error' === $error->type &&
247
+ preg_match( '/already been attached to a customer/i', $error->message )
248
+ );
249
+ }
250
+
251
  /**
252
  * Add a source for this stripe customer.
253
  * @param string $source_id
254
  * @return WP_Error|int
255
  */
256
  public function add_source( $source_id ) {
257
+ $response = $this->attach_source( $source_id );
258
+ if ( is_wp_error( $response ) ) {
259
+ return $response;
260
  }
261
 
262
+ // Add token to WooCommerce.
 
 
 
 
 
 
263
  $wc_token = false;
264
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
265
  if ( $this->get_user_id() && class_exists( 'WC_Payment_Token_CC' ) ) {
266
  if ( ! empty( $response->type ) ) {
267
  switch ( $response->type ) {
307
  return $response->id;
308
  }
309
 
310
+ /**
311
+ * Attaches a source to the Stripe customer.
312
+ *
313
+ * @param string $source_id The ID of the new source.
314
+ * @return object|WP_Error Either a source object, or a WP error.
315
+ */
316
+ public function attach_source( $source_id ) {
317
+ if ( ! $this->get_id() ) {
318
+ $this->set_id( $this->create_customer() );
319
+ }
320
+
321
+ $response = WC_Stripe_API::request(
322
+ array(
323
+ 'source' => $source_id,
324
+ ),
325
+ 'customers/' . $this->get_id() . '/sources'
326
+ );
327
+
328
+ if ( ! empty( $response->error ) ) {
329
+ // It is possible the WC user once was linked to a customer on Stripe
330
+ // but no longer exists. Instead of failing, lets try to create a
331
+ // new customer.
332
+ if ( $this->is_no_such_customer_error( $response->error ) ) {
333
+ $this->recreate_customer();
334
+ return $this->attach_source( $source_id );
335
+ } elseif( $this->is_source_already_attached_error( $response->error ) ) {
336
+ return WC_Stripe_API::request( array(), 'sources/' . $source_id, 'GET' );
337
+ } else {
338
+ return $response;
339
+ }
340
+ } elseif ( empty( $response->id ) ) {
341
+ return new WP_Error( 'error', __( 'Unable to add payment source.', 'woocommerce-gateway-stripe' ) );
342
+ } else {
343
+ return $response;
344
+ }
345
+ }
346
+
347
  /**
348
  * Get a customers saved sources using their Stripe ID.
349
  *
includes/class-wc-stripe-helper.php CHANGED
@@ -209,9 +209,11 @@ class WC_Stripe_Helper {
209
  'card_declined' => __( 'The card was declined.', 'woocommerce-gateway-stripe' ),
210
  'missing' => __( 'There is no card on a customer that is being charged.', 'woocommerce-gateway-stripe' ),
211
  'processing_error' => __( 'An error occurred while processing the card.', 'woocommerce-gateway-stripe' ),
212
- 'invalid_request_error' => __( 'Unable to process this payment, please try again or use alternative method.', 'woocommerce-gateway-stripe' ),
213
  'invalid_sofort_country' => __( 'The billing country is not accepted by SOFORT. Please try another country.', 'woocommerce-gateway-stripe' ),
214
  'email_invalid' => __( 'Invalid email address, please correct and try again.', 'woocommerce-gateway-stripe' ),
 
 
 
215
  )
216
  );
217
  }
209
  'card_declined' => __( 'The card was declined.', 'woocommerce-gateway-stripe' ),
210
  'missing' => __( 'There is no card on a customer that is being charged.', 'woocommerce-gateway-stripe' ),
211
  'processing_error' => __( 'An error occurred while processing the card.', 'woocommerce-gateway-stripe' ),
 
212
  'invalid_sofort_country' => __( 'The billing country is not accepted by SOFORT. Please try another country.', 'woocommerce-gateway-stripe' ),
213
  'email_invalid' => __( 'Invalid email address, please correct and try again.', 'woocommerce-gateway-stripe' ),
214
+ 'invalid_request_error' => is_add_payment_method_page()
215
+ ? __( 'Unable to save this payment method, please try again or use alternative method.', 'woocommerce-gateway-stripe' )
216
+ : __( 'Unable to process this payment, please try again or use alternative method.', 'woocommerce-gateway-stripe' ),
217
  )
218
  );
219
  }
includes/class-wc-stripe-intent-controller.php CHANGED
@@ -24,6 +24,7 @@ class WC_Stripe_Intent_Controller {
24
  */
25
  public function __construct() {
26
  add_action( 'wc_ajax_wc_stripe_verify_intent', array( $this, 'verify_intent' ) );
 
27
  }
28
 
29
  /**
@@ -135,6 +136,94 @@ class WC_Stripe_Intent_Controller {
135
  wp_safe_redirect( $redirect_url );
136
  exit;
137
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
138
  }
139
 
140
  new WC_Stripe_Intent_Controller();
24
  */
25
  public function __construct() {
26
  add_action( 'wc_ajax_wc_stripe_verify_intent', array( $this, 'verify_intent' ) );
27
+ add_action( 'wc_ajax_wc_stripe_create_setup_intent', array( $this, 'create_setup_intent' ) );
28
  }
29
 
30
  /**
136
  wp_safe_redirect( $redirect_url );
137
  exit;
138
  }
139
+
140
+ /**
141
+ * Creates a Setup Intent through AJAX while adding cards.
142
+ */
143
+ public function create_setup_intent() {
144
+ if (
145
+ ! is_user_logged_in()
146
+ || ! isset( $_POST['stripe_source_id'] )
147
+ || ! isset( $_POST['nonce'] )
148
+ ) {
149
+ return;
150
+ }
151
+
152
+ try {
153
+ $source_id = wc_clean( $_POST['stripe_source_id'] );
154
+
155
+ // 1. Verify.
156
+ if (
157
+ ! wp_verify_nonce( sanitize_key( $_POST['nonce'] ), 'wc_stripe_create_si' )
158
+ || ! preg_match( '/^src_.*$/', $source_id )
159
+ ) {
160
+ throw new Exception( __( 'Unable to verify your request. Please reload the page and try again.', 'woocommerce-gateway-stripe' ) );
161
+ }
162
+
163
+
164
+ // 2. Load the customer ID (and create a customer eventually).
165
+ $customer = new WC_Stripe_Customer( wp_get_current_user()->ID );
166
+
167
+ // 3. Attach the source to the customer (Setup Intents require that).
168
+ $source_object = $customer->attach_source( $source_id );
169
+ if ( is_wp_error( $source_object ) ) {
170
+ throw new Exception( $source_object->get_error_message() );
171
+ }
172
+
173
+ // 4. Generate the setup intent
174
+ $setup_intent = WC_Stripe_API::request(
175
+ [
176
+ 'customer' => $customer->get_id(),
177
+ 'confirm' => 'true',
178
+ 'payment_method' => $source_id,
179
+ ],
180
+ 'setup_intents'
181
+ );
182
+
183
+ if ( $setup_intent->error ) {
184
+ $error_response_message = print_r( $setup_intent, true );
185
+ WC_Stripe_Logger::log("Failed create Setup Intent while saving a card.");
186
+ WC_Stripe_Logger::log("Response: $error_response_message");
187
+ throw new Exception( __( 'Your card could not be set up for future usage.', 'woocommerce-gateway-stripe' ) );
188
+ }
189
+
190
+ // 5. Respond.
191
+ if ( 'requires_action' === $setup_intent->status ) {
192
+ $response = [
193
+ 'status' => 'requires_action',
194
+ 'client_secret' => $setup_intent->client_secret,
195
+ ];
196
+ } elseif ( 'requires_payment_method' === $setup_intent->status
197
+ || 'requires_confirmation' === $setup_intent->status
198
+ || 'canceled' === $setup_intent->status ) {
199
+ // These statuses should not be possible, as such we return an error.
200
+ $response = [
201
+ 'status' => 'error',
202
+ 'error' => [
203
+ 'type' => 'setup_intent_error',
204
+ 'message' => __( 'Failed to save payment method.', 'woocommerce-gateway-stripe' ),
205
+ ],
206
+ ];
207
+ } else {
208
+ // This should only be reached when status is `processing` or `succeeded`, which are
209
+ // the only statuses that we haven't explicitly handled.
210
+ $response = [
211
+ 'status' => 'success',
212
+ ];
213
+ }
214
+ } catch ( Exception $e ) {
215
+ $response = [
216
+ 'status' => 'error',
217
+ 'error' => array(
218
+ 'type' => 'setup_intent_error',
219
+ 'message' => $e->getMessage(),
220
+ ),
221
+ ];
222
+ }
223
+
224
+ echo wp_json_encode( $response );
225
+ exit;
226
+ }
227
  }
228
 
229
  new WC_Stripe_Intent_Controller();
includes/compat/class-wc-stripe-sepa-subs-compat.php CHANGED
@@ -109,10 +109,16 @@ class WC_Stripe_Sepa_Subs_Compat extends WC_Gateway_Stripe_Sepa {
109
  if ( ! empty( $all_subs ) ) {
110
  foreach ( $all_subs as $sub ) {
111
  if ( $sub->has_status( $subs_statuses ) ) {
112
- update_post_meta( $sub->get_id(), '_stripe_source_id', $source_id );
113
- update_post_meta( $sub->get_id(), '_stripe_customer_id', $stripe_customer->get_id() );
114
- update_post_meta( $sub->get_id(), '_payment_method', $this->id );
115
- update_post_meta( $sub->get_id(), '_payment_method_title', $this->method_title );
 
 
 
 
 
 
116
  }
117
  }
118
  }
109
  if ( ! empty( $all_subs ) ) {
110
  foreach ( $all_subs as $sub ) {
111
  if ( $sub->has_status( $subs_statuses ) ) {
112
+ WC_Subscriptions_Change_Payment_Gateway::update_payment_method(
113
+ $sub,
114
+ $this->id,
115
+ array(
116
+ 'post_meta' => array(
117
+ '_stripe_source_id' => array( 'value' => $source_id ),
118
+ '_stripe_customer_id' => array( 'value' => $stripe_customer->get_id() ),
119
+ ),
120
+ )
121
+ );
122
  }
123
  }
124
  }
includes/compat/class-wc-stripe-subs-compat.php CHANGED
@@ -22,6 +22,7 @@ class WC_Stripe_Subs_Compat extends WC_Gateway_Stripe {
22
  add_action( 'woocommerce_subscription_failing_payment_method_updated_stripe', array( $this, 'update_failing_payment_method' ), 10, 2 );
23
  add_action( 'wc_stripe_cards_payment_fields', array( $this, 'display_update_subs_payment_checkout' ) );
24
  add_action( 'wc_stripe_add_payment_method_' . $this->id . '_success', array( $this, 'handle_add_payment_method_success' ), 10, 2 );
 
25
 
26
  // display the credit card used for a subscription in the "My Subscriptions" table
27
  add_filter( 'woocommerce_my_subscriptions_payment_method', array( $this, 'maybe_render_subscription_payment_method' ), 10, 2 );
@@ -118,16 +119,32 @@ class WC_Stripe_Subs_Compat extends WC_Gateway_Stripe {
118
  if ( ! empty( $all_subs ) ) {
119
  foreach ( $all_subs as $sub ) {
120
  if ( $sub->has_status( $subs_statuses ) ) {
121
- update_post_meta( $sub->get_id(), '_stripe_source_id', $source_id );
122
- update_post_meta( $sub->get_id(), '_stripe_customer_id', $stripe_customer->get_id() );
123
- update_post_meta( $sub->get_id(), '_payment_method', $this->id );
124
- update_post_meta( $sub->get_id(), '_payment_method_title', $this->method_title );
 
 
 
 
 
 
125
  }
126
  }
127
  }
128
  }
129
  }
130
 
 
 
 
 
 
 
 
 
 
 
131
  /**
132
  * Process the payment method change for subscriptions.
133
  *
22
  add_action( 'woocommerce_subscription_failing_payment_method_updated_stripe', array( $this, 'update_failing_payment_method' ), 10, 2 );
23
  add_action( 'wc_stripe_cards_payment_fields', array( $this, 'display_update_subs_payment_checkout' ) );
24
  add_action( 'wc_stripe_add_payment_method_' . $this->id . '_success', array( $this, 'handle_add_payment_method_success' ), 10, 2 );
25
+ add_action( 'woocommerce_subscriptions_change_payment_before_submit', array( $this, 'differentiate_change_payment_method_form' ) );
26
 
27
  // display the credit card used for a subscription in the "My Subscriptions" table
28
  add_filter( 'woocommerce_my_subscriptions_payment_method', array( $this, 'maybe_render_subscription_payment_method' ), 10, 2 );
119
  if ( ! empty( $all_subs ) ) {
120
  foreach ( $all_subs as $sub ) {
121
  if ( $sub->has_status( $subs_statuses ) ) {
122
+ WC_Subscriptions_Change_Payment_Gateway::update_payment_method(
123
+ $sub,
124
+ $this->id,
125
+ array(
126
+ 'post_meta' => array(
127
+ '_stripe_source_id' => array( 'value' => $source_id ),
128
+ '_stripe_customer_id' => array( 'value' => $stripe_customer->get_id() ),
129
+ ),
130
+ )
131
+ );
132
  }
133
  }
134
  }
135
  }
136
  }
137
 
138
+ /**
139
+ * Render a dummy element in the "Change payment method" form (that does not appear in the "Pay for order" form)
140
+ * which can be checked to determine proper SCA handling to apply for each form.
141
+ *
142
+ * @since 4.6.1
143
+ */
144
+ public function differentiate_change_payment_method_form() {
145
+ echo '<input type="hidden" id="wc-stripe-change-payment-method" />';
146
+ }
147
+
148
  /**
149
  * Process the payment method change for subscriptions.
150
  *
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.6.0\n"
6
  "Report-Msgid-Bugs-To: "
7
  "https://wordpress.org/support/plugin/woocommerce-gateway-stripe\n"
8
- "POT-Creation-Date: 2020-12-15 10:59:40+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:246
32
- #: includes/compat/class-wc-stripe-sepa-subs-compat.php:222
33
- #: includes/compat/class-wc-stripe-subs-compat.php:224
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."
@@ -63,8 +63,8 @@ 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:495
67
- #: includes/compat/class-wc-stripe-sepa-subs-compat.php:179
68
  msgid "Payment processing failed. Please retry."
69
  msgstr ""
70
 
@@ -192,6 +192,10 @@ msgstr ""
192
  msgid "Boost sales this holiday season with Apple Pay!"
193
  msgstr ""
194
 
 
 
 
 
195
  #: includes/admin/class-wc-stripe-inbox-notes.php:130
196
  msgid ""
197
  "Now that you accept Apple Pay® with Stripe, you can increase conversion "
@@ -249,9 +253,9 @@ msgid "Retains any Stripe data such as Stripe customer ID, source ID."
249
  msgstr ""
250
 
251
  #: includes/admin/class-wc-stripe-privacy.php:41
252
- #: includes/compat/class-wc-stripe-sepa-subs-compat.php:476
253
- #: includes/compat/class-wc-stripe-subs-compat.php:574
254
- #: includes/compat/class-wc-stripe-subs-compat.php:589
255
  msgid "N/A"
256
  msgstr ""
257
 
@@ -930,7 +934,7 @@ msgid "Please fill in required checkout fields first"
930
  msgstr ""
931
 
932
  #: includes/class-wc-gateway-stripe.php:438
933
- #: includes/class-wc-gateway-stripe.php:482
934
  msgid ""
935
  "Sorry, we're not accepting prepaid cards at this time. Your credit card has "
936
  "not been charged. Please try with alternative payment method."
@@ -952,37 +956,37 @@ msgstr ""
952
  msgid "Billing First Name and Last Name are required."
953
  msgstr ""
954
 
955
- #: includes/class-wc-gateway-stripe.php:723
956
  #. translators: error message
957
  msgid "This represents the fee Stripe collects for the transaction."
958
  msgstr ""
959
 
960
- #: includes/class-wc-gateway-stripe.php:724
961
  msgid "Stripe Fee:"
962
  msgstr ""
963
 
964
- #: includes/class-wc-gateway-stripe.php:760
965
  msgid ""
966
  "This represents the net total that will be credited to your Stripe bank "
967
  "account. This may be in the currency that is set in your Stripe account."
968
  msgstr ""
969
 
970
- #: includes/class-wc-gateway-stripe.php:761
971
  msgid "Stripe Payout:"
972
  msgstr ""
973
 
974
- #: includes/class-wc-gateway-stripe.php:824
975
  #: includes/class-wc-stripe-order-handler.php:158
976
  #: includes/class-wc-stripe-webhook-handler.php:233
977
- #: includes/compat/class-wc-stripe-sepa-subs-compat.php:278
978
- #: includes/compat/class-wc-stripe-subs-compat.php:317
979
  #: includes/payment-methods/class-wc-gateway-stripe-sepa.php:369
980
  msgid ""
981
  "Sorry, we are unable to process your payment at this time. Please retry "
982
  "later."
983
  msgstr ""
984
 
985
- #: includes/class-wc-gateway-stripe.php:877
986
  msgid ""
987
  "Almost there!\n"
988
  "\n"
@@ -990,36 +994,36 @@ msgid ""
990
  "done is for you to authorize the payment with your bank."
991
  msgstr ""
992
 
993
- #: includes/class-wc-gateway-stripe.php:1118
994
  #: includes/class-wc-stripe-webhook-handler.php:674
995
  #: includes/class-wc-stripe-webhook-handler.php:713
996
  #. translators: 1) The error message that was received from Stripe.
997
  msgid "Stripe SCA authentication failed. Reason: %s"
998
  msgstr ""
999
 
1000
- #: includes/class-wc-gateway-stripe.php:1119
1001
  msgid "Stripe SCA authentication failed."
1002
  msgstr ""
1003
 
1004
- #: includes/class-wc-gateway-stripe.php:1176
1005
  msgid ""
1006
  "The \"Live Publishable Key\" should start with \"pk_live\", enter the "
1007
  "correct key."
1008
  msgstr ""
1009
 
1010
- #: includes/class-wc-gateway-stripe.php:1184
1011
  msgid ""
1012
  "The \"Live Secret Key\" should start with \"sk_live\" or \"rk_live\", enter "
1013
  "the correct key."
1014
  msgstr ""
1015
 
1016
- #: includes/class-wc-gateway-stripe.php:1192
1017
  msgid ""
1018
  "The \"Test Publishable Key\" should start with \"pk_test\", enter the "
1019
  "correct key."
1020
  msgstr ""
1021
 
1022
- #: includes/class-wc-gateway-stripe.php:1200
1023
  msgid ""
1024
  "The \"Test Secret Key\" should start with \"sk_test\" or \"rk_test\", enter "
1025
  "the correct key."
@@ -1068,7 +1072,7 @@ msgstr ""
1068
  msgid "Attempting to update a Stripe customer without a customer ID."
1069
  msgstr ""
1070
 
1071
- #: includes/class-wc-stripe-customer.php:265
1072
  msgid "Unable to add payment source."
1073
  msgstr ""
1074
 
@@ -1133,31 +1137,49 @@ msgid "An error occurred while processing the card."
1133
  msgstr ""
1134
 
1135
  #: includes/class-wc-stripe-helper.php:212
1136
- #: includes/class-wc-stripe-order-handler.php:96
1137
- msgid "Unable to process this payment, please try again or use alternative method."
1138
  msgstr ""
1139
 
1140
  #: includes/class-wc-stripe-helper.php:213
1141
- msgid "The billing country is not accepted by SOFORT. Please try another country."
1142
  msgstr ""
1143
 
1144
- #: includes/class-wc-stripe-helper.php:214
1145
- msgid "Invalid email address, please correct and try again."
 
 
 
 
 
 
 
1146
  msgstr ""
1147
 
1148
- #: includes/class-wc-stripe-intent-controller.php:58
1149
  msgid "CSRF verification failed."
1150
  msgstr ""
1151
 
1152
- #: includes/class-wc-stripe-intent-controller.php:71
1153
  msgid "Missing order ID for payment confirmation"
1154
  msgstr ""
1155
 
1156
- #: includes/class-wc-stripe-intent-controller.php:91
1157
  #. translators: Error message text
1158
  msgid "Payment verification error: %s"
1159
  msgstr ""
1160
 
 
 
 
 
 
 
 
 
 
 
 
 
1161
  #: includes/class-wc-stripe-order-handler.php:140
1162
  #: includes/class-wc-stripe-webhook-handler.php:214
1163
  #: includes/payment-methods/class-wc-gateway-stripe-sepa.php:349
@@ -1302,8 +1324,8 @@ msgid "Unable to store payment details. Please try again."
1302
  msgstr ""
1303
 
1304
  #: includes/compat/class-wc-stripe-pre-orders-compat.php:114
1305
- #: includes/compat/class-wc-stripe-subs-compat.php:349
1306
- #: includes/compat/class-wc-stripe-subs-compat.php:653
1307
  msgid "Stripe charge awaiting authentication by user: %s."
1308
  msgstr ""
1309
 
@@ -1313,59 +1335,59 @@ msgid "Stripe Transaction Failed (%s)"
1313
  msgstr ""
1314
 
1315
  #: includes/compat/class-wc-stripe-sepa-subs-compat.php:83
1316
- #: includes/compat/class-wc-stripe-subs-compat.php:92
1317
  msgid "Update the Payment Method used for all of my active subscriptions."
1318
  msgstr ""
1319
 
1320
- #: includes/compat/class-wc-stripe-sepa-subs-compat.php:240
1321
- #: includes/compat/class-wc-stripe-subs-compat.php:277
1322
  msgid "Customer not found"
1323
  msgstr ""
1324
 
1325
- #: includes/compat/class-wc-stripe-sepa-subs-compat.php:398
1326
- #: includes/compat/class-wc-stripe-subs-compat.php:495
1327
  #. translators: error message
1328
  msgid "A \"Stripe Customer ID\" value is required."
1329
  msgstr ""
1330
 
1331
- #: includes/compat/class-wc-stripe-sepa-subs-compat.php:401
1332
- #: includes/compat/class-wc-stripe-subs-compat.php:498
1333
  msgid ""
1334
  "Invalid customer ID. A valid \"Stripe Customer ID\" must begin with "
1335
  "\"cus_\"."
1336
  msgstr ""
1337
 
1338
- #: includes/compat/class-wc-stripe-sepa-subs-compat.php:410
1339
  msgid ""
1340
  "Invalid source ID. A valid source \"Stripe Source ID\" must begin with "
1341
  "\"src_\" or \"card_\"."
1342
  msgstr ""
1343
 
1344
- #: includes/compat/class-wc-stripe-sepa-subs-compat.php:483
1345
  #. translators: 1) last 4 digits of SEPA Direct Debit
1346
  msgid "Via SEPA Direct Debit ending in %1$s"
1347
  msgstr ""
1348
 
1349
- #: includes/compat/class-wc-stripe-subs-compat.php:341
1350
  msgid "This transaction requires authentication."
1351
  msgstr ""
1352
 
1353
- #: includes/compat/class-wc-stripe-subs-compat.php:508
1354
  msgid ""
1355
  "Invalid source ID. A valid source \"Stripe Source ID\" must begin with "
1356
  "\"src_\", \"pm_\", or \"card_\"."
1357
  msgstr ""
1358
 
1359
- #: includes/compat/class-wc-stripe-subs-compat.php:589
1360
  #. translators: 1) card brand 2) last 4 digits
1361
  msgid "Via %1$s card ending in %2$s"
1362
  msgstr ""
1363
 
1364
- #: includes/compat/class-wc-stripe-subs-compat.php:686
1365
  msgid "Your early renewal order was successful."
1366
  msgstr ""
1367
 
1368
- #: includes/compat/class-wc-stripe-subs-compat.php:699
1369
  msgid ""
1370
  "Payment authorization for the renewal order was unsuccessful, please try "
1371
  "again."
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.7.0\n"
6
  "Report-Msgid-Bugs-To: "
7
  "https://wordpress.org/support/plugin/woocommerce-gateway-stripe\n"
8
+ "POT-Creation-Date: 2020-12-22 16:57:55+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:246
32
+ #: includes/compat/class-wc-stripe-sepa-subs-compat.php:228
33
+ #: includes/compat/class-wc-stripe-subs-compat.php:241
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."
63
  msgstr ""
64
 
65
  #: includes/abstracts/abstract-wc-stripe-payment-gateway.php:455
66
+ #: includes/class-wc-gateway-stripe.php:496
67
+ #: includes/compat/class-wc-stripe-sepa-subs-compat.php:185
68
  msgid "Payment processing failed. Please retry."
69
  msgstr ""
70
 
192
  msgid "Boost sales this holiday season with Apple Pay!"
193
  msgstr ""
194
 
195
+ #: includes/admin/class-wc-stripe-inbox-notes.php:45
196
+ msgid "Boost sales with Apple Pay!"
197
+ msgstr ""
198
+
199
  #: includes/admin/class-wc-stripe-inbox-notes.php:130
200
  msgid ""
201
  "Now that you accept Apple Pay® with Stripe, you can increase conversion "
253
  msgstr ""
254
 
255
  #: includes/admin/class-wc-stripe-privacy.php:41
256
+ #: includes/compat/class-wc-stripe-sepa-subs-compat.php:482
257
+ #: includes/compat/class-wc-stripe-subs-compat.php:591
258
+ #: includes/compat/class-wc-stripe-subs-compat.php:606
259
  msgid "N/A"
260
  msgstr ""
261
 
934
  msgstr ""
935
 
936
  #: includes/class-wc-gateway-stripe.php:438
937
+ #: includes/class-wc-gateway-stripe.php:483
938
  msgid ""
939
  "Sorry, we're not accepting prepaid cards at this time. Your credit card has "
940
  "not been charged. Please try with alternative payment method."
956
  msgid "Billing First Name and Last Name are required."
957
  msgstr ""
958
 
959
+ #: includes/class-wc-gateway-stripe.php:724
960
  #. translators: error message
961
  msgid "This represents the fee Stripe collects for the transaction."
962
  msgstr ""
963
 
964
+ #: includes/class-wc-gateway-stripe.php:725
965
  msgid "Stripe Fee:"
966
  msgstr ""
967
 
968
+ #: includes/class-wc-gateway-stripe.php:761
969
  msgid ""
970
  "This represents the net total that will be credited to your Stripe bank "
971
  "account. This may be in the currency that is set in your Stripe account."
972
  msgstr ""
973
 
974
+ #: includes/class-wc-gateway-stripe.php:762
975
  msgid "Stripe Payout:"
976
  msgstr ""
977
 
978
+ #: includes/class-wc-gateway-stripe.php:825
979
  #: includes/class-wc-stripe-order-handler.php:158
980
  #: includes/class-wc-stripe-webhook-handler.php:233
981
+ #: includes/compat/class-wc-stripe-sepa-subs-compat.php:284
982
+ #: includes/compat/class-wc-stripe-subs-compat.php:334
983
  #: includes/payment-methods/class-wc-gateway-stripe-sepa.php:369
984
  msgid ""
985
  "Sorry, we are unable to process your payment at this time. Please retry "
986
  "later."
987
  msgstr ""
988
 
989
+ #: includes/class-wc-gateway-stripe.php:878
990
  msgid ""
991
  "Almost there!\n"
992
  "\n"
994
  "done is for you to authorize the payment with your bank."
995
  msgstr ""
996
 
997
+ #: includes/class-wc-gateway-stripe.php:1119
998
  #: includes/class-wc-stripe-webhook-handler.php:674
999
  #: includes/class-wc-stripe-webhook-handler.php:713
1000
  #. translators: 1) The error message that was received from Stripe.
1001
  msgid "Stripe SCA authentication failed. Reason: %s"
1002
  msgstr ""
1003
 
1004
+ #: includes/class-wc-gateway-stripe.php:1120
1005
  msgid "Stripe SCA authentication failed."
1006
  msgstr ""
1007
 
1008
+ #: includes/class-wc-gateway-stripe.php:1177
1009
  msgid ""
1010
  "The \"Live Publishable Key\" should start with \"pk_live\", enter the "
1011
  "correct key."
1012
  msgstr ""
1013
 
1014
+ #: includes/class-wc-gateway-stripe.php:1185
1015
  msgid ""
1016
  "The \"Live Secret Key\" should start with \"sk_live\" or \"rk_live\", enter "
1017
  "the correct key."
1018
  msgstr ""
1019
 
1020
+ #: includes/class-wc-gateway-stripe.php:1193
1021
  msgid ""
1022
  "The \"Test Publishable Key\" should start with \"pk_test\", enter the "
1023
  "correct key."
1024
  msgstr ""
1025
 
1026
+ #: includes/class-wc-gateway-stripe.php:1201
1027
  msgid ""
1028
  "The \"Test Secret Key\" should start with \"sk_test\" or \"rk_test\", enter "
1029
  "the correct key."
1072
  msgid "Attempting to update a Stripe customer without a customer ID."
1073
  msgstr ""
1074
 
1075
+ #: includes/class-wc-stripe-customer.php:341
1076
  msgid "Unable to add payment source."
1077
  msgstr ""
1078
 
1137
  msgstr ""
1138
 
1139
  #: includes/class-wc-stripe-helper.php:212
1140
+ msgid "The billing country is not accepted by SOFORT. Please try another country."
 
1141
  msgstr ""
1142
 
1143
  #: includes/class-wc-stripe-helper.php:213
1144
+ msgid "Invalid email address, please correct and try again."
1145
  msgstr ""
1146
 
1147
+ #: includes/class-wc-stripe-helper.php:215
1148
+ msgid ""
1149
+ "Unable to save this payment method, please try again or use alternative "
1150
+ "method."
1151
+ msgstr ""
1152
+
1153
+ #: includes/class-wc-stripe-helper.php:216
1154
+ #: includes/class-wc-stripe-order-handler.php:96
1155
+ msgid "Unable to process this payment, please try again or use alternative method."
1156
  msgstr ""
1157
 
1158
+ #: includes/class-wc-stripe-intent-controller.php:59
1159
  msgid "CSRF verification failed."
1160
  msgstr ""
1161
 
1162
+ #: includes/class-wc-stripe-intent-controller.php:72
1163
  msgid "Missing order ID for payment confirmation"
1164
  msgstr ""
1165
 
1166
+ #: includes/class-wc-stripe-intent-controller.php:92
1167
  #. translators: Error message text
1168
  msgid "Payment verification error: %s"
1169
  msgstr ""
1170
 
1171
+ #: includes/class-wc-stripe-intent-controller.php:160
1172
+ msgid "Unable to verify your request. Please reload the page and try again."
1173
+ msgstr ""
1174
+
1175
+ #: includes/class-wc-stripe-intent-controller.php:187
1176
+ msgid "Your card could not be set up for future usage."
1177
+ msgstr ""
1178
+
1179
+ #: includes/class-wc-stripe-intent-controller.php:204
1180
+ msgid "Failed to save payment method."
1181
+ msgstr ""
1182
+
1183
  #: includes/class-wc-stripe-order-handler.php:140
1184
  #: includes/class-wc-stripe-webhook-handler.php:214
1185
  #: includes/payment-methods/class-wc-gateway-stripe-sepa.php:349
1324
  msgstr ""
1325
 
1326
  #: includes/compat/class-wc-stripe-pre-orders-compat.php:114
1327
+ #: includes/compat/class-wc-stripe-subs-compat.php:366
1328
+ #: includes/compat/class-wc-stripe-subs-compat.php:670
1329
  msgid "Stripe charge awaiting authentication by user: %s."
1330
  msgstr ""
1331
 
1335
  msgstr ""
1336
 
1337
  #: includes/compat/class-wc-stripe-sepa-subs-compat.php:83
1338
+ #: includes/compat/class-wc-stripe-subs-compat.php:93
1339
  msgid "Update the Payment Method used for all of my active subscriptions."
1340
  msgstr ""
1341
 
1342
+ #: includes/compat/class-wc-stripe-sepa-subs-compat.php:246
1343
+ #: includes/compat/class-wc-stripe-subs-compat.php:294
1344
  msgid "Customer not found"
1345
  msgstr ""
1346
 
1347
+ #: includes/compat/class-wc-stripe-sepa-subs-compat.php:404
1348
+ #: includes/compat/class-wc-stripe-subs-compat.php:512
1349
  #. translators: error message
1350
  msgid "A \"Stripe Customer ID\" value is required."
1351
  msgstr ""
1352
 
1353
+ #: includes/compat/class-wc-stripe-sepa-subs-compat.php:407
1354
+ #: includes/compat/class-wc-stripe-subs-compat.php:515
1355
  msgid ""
1356
  "Invalid customer ID. A valid \"Stripe Customer ID\" must begin with "
1357
  "\"cus_\"."
1358
  msgstr ""
1359
 
1360
+ #: includes/compat/class-wc-stripe-sepa-subs-compat.php:416
1361
  msgid ""
1362
  "Invalid source ID. A valid source \"Stripe Source ID\" must begin with "
1363
  "\"src_\" or \"card_\"."
1364
  msgstr ""
1365
 
1366
+ #: includes/compat/class-wc-stripe-sepa-subs-compat.php:489
1367
  #. translators: 1) last 4 digits of SEPA Direct Debit
1368
  msgid "Via SEPA Direct Debit ending in %1$s"
1369
  msgstr ""
1370
 
1371
+ #: includes/compat/class-wc-stripe-subs-compat.php:358
1372
  msgid "This transaction requires authentication."
1373
  msgstr ""
1374
 
1375
+ #: includes/compat/class-wc-stripe-subs-compat.php:525
1376
  msgid ""
1377
  "Invalid source ID. A valid source \"Stripe Source ID\" must begin with "
1378
  "\"src_\", \"pm_\", or \"card_\"."
1379
  msgstr ""
1380
 
1381
+ #: includes/compat/class-wc-stripe-subs-compat.php:606
1382
  #. translators: 1) card brand 2) last 4 digits
1383
  msgid "Via %1$s card ending in %2$s"
1384
  msgstr ""
1385
 
1386
+ #: includes/compat/class-wc-stripe-subs-compat.php:703
1387
  msgid "Your early renewal order was successful."
1388
  msgstr ""
1389
 
1390
+ #: includes/compat/class-wc-stripe-subs-compat.php:716
1391
  msgid ""
1392
  "Payment authorization for the renewal order was unsuccessful, please try "
1393
  "again."
readme.txt CHANGED
@@ -4,7 +4,7 @@ Tags: credit card, stripe, apple pay, payment request, google pay, sepa, sofort,
4
  Requires at least: 4.4
5
  Tested up to: 5.5
6
  Requires PHP: 5.6
7
- Stable tag: 4.6.0
8
  License: GPLv3
9
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
10
  Attributions: thorsten-stripe
@@ -126,14 +126,13 @@ If you get stuck, you can ask for help in the Plugin Forum.
126
 
127
  == Changelog ==
128
 
129
- = 4.6.0 - 2020-12-15 =
130
- * Tweak - Update packages for Composer 2 compatibility.
131
- * Tweak - Use full jQuery function calls instead of soon-to-be-deprecated shorthands.
132
- * Tweak - Use JSON.parse() instead of jQuery.parseJSON().
133
- * Tweak - Remove holiday messaging from Apple Pay note after Dec 22.
134
- * Fix - Compatibility with the Stripe for WooCommerce plugin.
135
- * Fix - Guard against fatal errors caused by WC_Admin_Note.
136
- * Fix - Display error message when payment made with payment request buttons fails.
137
 
138
- See changelog for all versions](https://raw.githubusercontent.com/woocommerce/woocommerce-gateway-stripe/master/changelog.txt).
139
 
4
  Requires at least: 4.4
5
  Tested up to: 5.5
6
  Requires PHP: 5.6
7
+ Stable tag: 4.7.0
8
  License: GPLv3
9
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
10
  Attributions: thorsten-stripe
126
 
127
  == Changelog ==
128
 
129
+ = 4.7.0 - 2020-12-22 =
130
+ * Fix - Updating subscription payment methods from the "My Account" page now adds a note to the subscription.
131
+ * Fix - Link is now correctly formatted in readme.txt.
132
+ * Fix - Using SCA cards for subscriptions renewal payments now works as intended.
133
+ * Fix - Cards added under "My Account -> Payment Methods -> Add Payment Method" will now handle SCA properly.
134
+ * Fix - Changing a payment method for a subscription in "My Account -> Subscriptions" will now handle SCA properly.
135
+ * Fix - Missing space causing fatal errors for certain WooCommerce Inbox Note features.
 
136
 
137
+ [See changelog for all versions](https://raw.githubusercontent.com/woocommerce/woocommerce-gateway-stripe/master/changelog.txt).
138
 
woocommerce-gateway-stripe.php CHANGED
@@ -5,7 +5,7 @@
5
  * Description: Take credit card payments on your store using Stripe.
6
  * Author: WooCommerce
7
  * Author URI: https://woocommerce.com/
8
- * Version: 4.6.0
9
  * Requires at least: 4.4
10
  * Tested up to: 5.5
11
  * WC requires at least: 3.0
@@ -22,7 +22,7 @@ if ( ! defined( 'ABSPATH' ) ) {
22
  /**
23
  * Required minimums and constants
24
  */
25
- define( 'WC_STRIPE_VERSION', '4.6.0' ); // WRCS: DEFINED_VERSION.
26
  define( 'WC_STRIPE_MIN_PHP_VER', '5.6.0' );
27
  define( 'WC_STRIPE_MIN_WC_VER', '3.0' );
28
  define( 'WC_STRIPE_FUTURE_MIN_WC_VER', '3.0' );
5
  * Description: Take credit card payments on your store using Stripe.
6
  * Author: WooCommerce
7
  * Author URI: https://woocommerce.com/
8
+ * Version: 4.7.0
9
  * Requires at least: 4.4
10
  * Tested up to: 5.5
11
  * WC requires at least: 3.0
22
  /**
23
  * Required minimums and constants
24
  */
25
+ define( 'WC_STRIPE_VERSION', '4.7.0' ); // WRCS: DEFINED_VERSION.
26
  define( 'WC_STRIPE_MIN_PHP_VER', '5.6.0' );
27
  define( 'WC_STRIPE_MIN_WC_VER', '3.0' );
28
  define( 'WC_STRIPE_FUTURE_MIN_WC_VER', '3.0' );