Version Description
2019-10-17 =
* Add - For WooCommerce Subscriptions optimize the payment flow for subsequent subscription payments when authentication may be required by using the setup_future_usage parameter for the first subscription payment
* Add - Allow customer to authenticate payment even if they are not charged right away for WooCommerce Subscriptions and Pre-Orders, for example for a WooCommerce Subscription that has a free trial
* Add - When an off-session payment requires authentication, create a link for customers to come back to the store to authenticate the payment
* Add - Send an email to WooCommerce Subscription and Pre-Orders customers who need to authenticate a payment that was automatically tried on their behalf
* Add - When an off-session payment requires authentication, send an email to the admin
* Add - Admin notice about SCA-readiness
* Fix - Avoid idempotency key errors for Pre-Orders
* Fix - Use unique anchor for link about checkout styling changes
Release Info
| Developer | woothemes |
| Plugin | |
| Version | 4.3.0 |
| Comparing to | |
| See all releases | |
Code changes from version 4.2.5 to 4.3.0
- assets/js/stripe.js +16 -11
- assets/js/stripe.min.js +1 -1
- changelog.txt +10 -0
- includes/abstracts/abstract-wc-stripe-payment-gateway.php +153 -29
- includes/admin/class-wc-stripe-admin-notices.php +30 -2
- includes/class-wc-gateway-stripe.php +116 -58
- includes/class-wc-stripe-api.php +1 -1
- includes/class-wc-stripe-customer.php +11 -5
- includes/class-wc-stripe-helper.php +19 -0
- includes/class-wc-stripe-intent-controller.php +1 -1
- includes/class-wc-stripe-webhook-handler.php +42 -1
- includes/compat/class-wc-stripe-email-failed-authentication-retry.php +132 -0
- includes/compat/class-wc-stripe-email-failed-authentication.php +126 -0
- includes/compat/class-wc-stripe-email-failed-preorder-authentication.php +104 -0
- includes/compat/class-wc-stripe-email-failed-renewal-authentication.php +113 -0
- includes/compat/class-wc-stripe-pre-orders-compat.php +58 -40
- includes/compat/class-wc-stripe-subs-compat.php +123 -67
- languages/woocommerce-gateway-stripe.pot +239 -109
- readme.txt +12 -13
- templates/emails/failed-preorder-authentication.php +63 -0
- templates/emails/failed-renewal-authentication-requested.php +57 -0
- templates/emails/failed-renewal-authentication.php +17 -0
- templates/emails/plain/failed-preorder-authentication.php +29 -0
- templates/emails/plain/failed-renewal-authentication-requested.php +49 -0
- templates/emails/plain/failed-renewal-authentication.php +17 -0
- woocommerce-gateway-stripe.php +27 -4
|
@@ -709,30 +709,32 @@ jQuery( function( $ ) {
|
|
| 709 |
},
|
| 710 |
|
| 711 |
/**
|
| 712 |
-
* Handles changes in the hash in order to show a modal for PaymentIntent confirmations.
|
| 713 |
*
|
| 714 |
* Listens for `hashchange` events and checks for a hash in the following format:
|
| 715 |
* #confirm-pi-<intentClientSecret>:<successRedirectURL>
|
| 716 |
*
|
| 717 |
* If such a hash appears, the partials will be used to call `stripe.handleCardPayment`
|
| 718 |
-
* in order to allow customers to confirm an 3DS/SCA authorization.
|
|
|
|
| 719 |
*
|
| 720 |
* Those redirects/hashes are generated in `WC_Gateway_Stripe::process_payment`.
|
| 721 |
*/
|
| 722 |
onHashChange: function() {
|
| 723 |
-
var partials = window.location.hash.match( /^#?confirm-pi-([^:]+):(.+)$/ );
|
| 724 |
|
| 725 |
-
if ( ! partials ||
|
| 726 |
return;
|
| 727 |
}
|
| 728 |
|
| 729 |
-
var
|
| 730 |
-
var
|
|
|
|
| 731 |
|
| 732 |
// Cleanup the URL
|
| 733 |
window.location.hash = '';
|
| 734 |
|
| 735 |
-
wc_stripe_form.openIntentModal( intentClientSecret, redirectURL );
|
| 736 |
},
|
| 737 |
|
| 738 |
maybeConfirmIntent: function() {
|
|
@@ -743,7 +745,7 @@ jQuery( function( $ ) {
|
|
| 743 |
var intentSecret = $( '#stripe-intent-id' ).val();
|
| 744 |
var returnURL = $( '#stripe-intent-return' ).val();
|
| 745 |
|
| 746 |
-
wc_stripe_form.openIntentModal( intentSecret, returnURL, true );
|
| 747 |
},
|
| 748 |
|
| 749 |
/**
|
|
@@ -753,15 +755,18 @@ jQuery( function( $ ) {
|
|
| 753 |
* @param {string} redirectURL The URL to ping on fail or redirect to on success.
|
| 754 |
* @param {boolean} alwaysRedirect If set to true, an immediate redirect will happen no matter the result.
|
| 755 |
* If not, an error will be displayed on failure.
|
|
|
|
|
|
|
| 756 |
*/
|
| 757 |
-
openIntentModal: function( intentClientSecret, redirectURL, alwaysRedirect ) {
|
| 758 |
-
stripe
|
| 759 |
.then( function( response ) {
|
| 760 |
if ( response.error ) {
|
| 761 |
throw response.error;
|
| 762 |
}
|
| 763 |
|
| 764 |
-
|
|
|
|
| 765 |
return;
|
| 766 |
}
|
| 767 |
|
| 709 |
},
|
| 710 |
|
| 711 |
/**
|
| 712 |
+
* Handles changes in the hash in order to show a modal for PaymentIntent/SetupIntent confirmations.
|
| 713 |
*
|
| 714 |
* Listens for `hashchange` events and checks for a hash in the following format:
|
| 715 |
* #confirm-pi-<intentClientSecret>:<successRedirectURL>
|
| 716 |
*
|
| 717 |
* If such a hash appears, the partials will be used to call `stripe.handleCardPayment`
|
| 718 |
+
* in order to allow customers to confirm an 3DS/SCA authorization, or stripe.handleCardSetup if
|
| 719 |
+
* what needs to be confirmed is a SetupIntent.
|
| 720 |
*
|
| 721 |
* Those redirects/hashes are generated in `WC_Gateway_Stripe::process_payment`.
|
| 722 |
*/
|
| 723 |
onHashChange: function() {
|
| 724 |
+
var partials = window.location.hash.match( /^#?confirm-(pi|si)-([^:]+):(.+)$/ );
|
| 725 |
|
| 726 |
+
if ( ! partials || 4 > partials.length ) {
|
| 727 |
return;
|
| 728 |
}
|
| 729 |
|
| 730 |
+
var type = partials[1];
|
| 731 |
+
var intentClientSecret = partials[2];
|
| 732 |
+
var redirectURL = decodeURIComponent( partials[3] );
|
| 733 |
|
| 734 |
// Cleanup the URL
|
| 735 |
window.location.hash = '';
|
| 736 |
|
| 737 |
+
wc_stripe_form.openIntentModal( intentClientSecret, redirectURL, false, 'si' === type );
|
| 738 |
},
|
| 739 |
|
| 740 |
maybeConfirmIntent: function() {
|
| 745 |
var intentSecret = $( '#stripe-intent-id' ).val();
|
| 746 |
var returnURL = $( '#stripe-intent-return' ).val();
|
| 747 |
|
| 748 |
+
wc_stripe_form.openIntentModal( intentSecret, returnURL, true, false );
|
| 749 |
},
|
| 750 |
|
| 751 |
/**
|
| 755 |
* @param {string} redirectURL The URL to ping on fail or redirect to on success.
|
| 756 |
* @param {boolean} alwaysRedirect If set to true, an immediate redirect will happen no matter the result.
|
| 757 |
* If not, an error will be displayed on failure.
|
| 758 |
+
* @param {boolean} isSetupIntent If set to true, ameans that the flow is handling a Setup Intent.
|
| 759 |
+
* If false, it's a Payment Intent.
|
| 760 |
*/
|
| 761 |
+
openIntentModal: function( intentClientSecret, redirectURL, alwaysRedirect, isSetupIntent ) {
|
| 762 |
+
stripe[ isSetupIntent ? 'handleCardSetup' : 'handleCardPayment' ]( intentClientSecret )
|
| 763 |
.then( function( response ) {
|
| 764 |
if ( response.error ) {
|
| 765 |
throw response.error;
|
| 766 |
}
|
| 767 |
|
| 768 |
+
var intent = response[ isSetupIntent ? 'setupIntent' : 'paymentIntent' ];
|
| 769 |
+
if ( 'requires_capture' !== intent.status && 'succeeded' !== intent.status ) {
|
| 770 |
return;
|
| 771 |
}
|
| 772 |
|
|
@@ -1 +1 @@
|
|
| 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(){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,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){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)}"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").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()});
|
| 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(){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,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.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)}"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").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")})}};m.init()});
|
|
@@ -1,5 +1,15 @@
|
|
| 1 |
*** Changelog ***
|
| 2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
= 4.2.5 - 2019-10-02 =
|
| 4 |
* Fix - WooCommerce Subscriptions that use only the Stripe customer ID can again be renewed
|
| 5 |
|
| 1 |
*** Changelog ***
|
| 2 |
|
| 3 |
+
= 4.3.0 2019-10-17 =
|
| 4 |
+
* Add - For WooCommerce Subscriptions optimize the payment flow for subsequent subscription payments when authentication may be required by using the `setup_future_usage` parameter for the first subscription payment
|
| 5 |
+
* Add - Allow customer to authenticate payment even if they are not charged right away for WooCommerce Subscriptions and Pre-Orders, for example for a WooCommerce Subscription that has a free trial
|
| 6 |
+
* Add - When an off-session payment requires authentication, create a link for customers to come back to the store to authenticate the payment
|
| 7 |
+
* Add - Send an email to WooCommerce Subscription and Pre-Orders customers who need to authenticate a payment that was automatically tried on their behalf
|
| 8 |
+
* Add - When an off-session payment requires authentication, send an email to the admin
|
| 9 |
+
* Add - Admin notice about SCA-readiness
|
| 10 |
+
* Fix - Avoid idempotency key errors for Pre-Orders
|
| 11 |
+
* Fix - Use unique anchor for link about checkout styling changes
|
| 12 |
+
|
| 13 |
= 4.2.5 - 2019-10-02 =
|
| 14 |
* Fix - WooCommerce Subscriptions that use only the Stripe customer ID can again be renewed
|
| 15 |
|
|
@@ -72,21 +72,6 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
|
|
| 72 |
);
|
| 73 |
}
|
| 74 |
|
| 75 |
-
/**
|
| 76 |
-
* Checks to see if error is of invalid request
|
| 77 |
-
* error and source is already consumed.
|
| 78 |
-
*
|
| 79 |
-
* @since 4.1.0
|
| 80 |
-
* @param array $error
|
| 81 |
-
*/
|
| 82 |
-
public function is_source_already_consumed_error( $error ) {
|
| 83 |
-
return (
|
| 84 |
-
$error &&
|
| 85 |
-
'invalid_request_error' === $error->type &&
|
| 86 |
-
preg_match( '/The reusable source you provided is consumed because it was previously charged without being attached to a customer or was detached from a customer. To charge a reusable source multiple time you must attach it to a customer first./i', $error->message )
|
| 87 |
-
);
|
| 88 |
-
}
|
| 89 |
-
|
| 90 |
/**
|
| 91 |
* Checks to see if error is of invalid request
|
| 92 |
* error and it is no such customer.
|
|
@@ -548,7 +533,11 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
|
|
| 548 |
* @return bool
|
| 549 |
*/
|
| 550 |
public function is_prepaid_card( $source_object ) {
|
| 551 |
-
return (
|
|
|
|
|
|
|
|
|
|
|
|
|
| 552 |
}
|
| 553 |
|
| 554 |
/**
|
|
@@ -589,7 +578,6 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
|
|
| 589 |
*/
|
| 590 |
public function prepare_source( $user_id, $force_save_source = false ) {
|
| 591 |
$customer = new WC_Stripe_Customer( $user_id );
|
| 592 |
-
$set_customer = true;
|
| 593 |
$force_save_source = apply_filters( 'wc_stripe_force_save_source', $force_save_source, $customer );
|
| 594 |
$source_object = '';
|
| 595 |
$source_id = '';
|
|
@@ -644,16 +632,15 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
|
|
| 644 |
throw new WC_Stripe_Exception( print_r( $response, true ), $response->error->message );
|
| 645 |
}
|
| 646 |
} else {
|
| 647 |
-
$set_customer = false;
|
| 648 |
$source_id = $stripe_token;
|
| 649 |
$is_token = true;
|
| 650 |
}
|
| 651 |
}
|
| 652 |
|
| 653 |
-
|
| 654 |
-
|
| 655 |
-
|
| 656 |
-
$customer_id = $customer->get_id()
|
| 657 |
}
|
| 658 |
|
| 659 |
if ( empty( $source_object ) && ! $is_token ) {
|
|
@@ -1021,13 +1008,13 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
|
|
| 1021 |
}
|
| 1022 |
|
| 1023 |
/**
|
| 1024 |
-
*
|
| 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
|
| 1029 |
*/
|
| 1030 |
-
public function
|
| 1031 |
// The request for a charge contains metadata for the intent.
|
| 1032 |
$full_request = $this->generate_payment_request( $order, $prepared_source );
|
| 1033 |
|
|
@@ -1037,7 +1024,6 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
|
|
| 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',
|
|
@@ -1048,6 +1034,31 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
|
|
| 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 ) ) {
|
|
@@ -1167,11 +1178,22 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
|
|
| 1167 |
$intent_id = $order->get_meta( '_stripe_intent_id' );
|
| 1168 |
}
|
| 1169 |
|
| 1170 |
-
if (
|
| 1171 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1172 |
}
|
| 1173 |
|
| 1174 |
-
return
|
| 1175 |
}
|
| 1176 |
|
| 1177 |
/**
|
|
@@ -1208,4 +1230,106 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
|
|
| 1208 |
$order_id = WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $order->id : $order->get_id();
|
| 1209 |
delete_transient( 'wc_stripe_processing_intent_' . $order_id );
|
| 1210 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1211 |
}
|
| 72 |
);
|
| 73 |
}
|
| 74 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 75 |
/**
|
| 76 |
* Checks to see if error is of invalid request
|
| 77 |
* error and it is no such customer.
|
| 533 |
* @return bool
|
| 534 |
*/
|
| 535 |
public function is_prepaid_card( $source_object ) {
|
| 536 |
+
return (
|
| 537 |
+
$source_object
|
| 538 |
+
&& ( 'token' === $source_object->object || 'source' === $source_object->object )
|
| 539 |
+
&& 'prepaid' === $source_object->card->funding
|
| 540 |
+
);
|
| 541 |
}
|
| 542 |
|
| 543 |
/**
|
| 578 |
*/
|
| 579 |
public function prepare_source( $user_id, $force_save_source = false ) {
|
| 580 |
$customer = new WC_Stripe_Customer( $user_id );
|
|
|
|
| 581 |
$force_save_source = apply_filters( 'wc_stripe_force_save_source', $force_save_source, $customer );
|
| 582 |
$source_object = '';
|
| 583 |
$source_id = '';
|
| 632 |
throw new WC_Stripe_Exception( print_r( $response, true ), $response->error->message );
|
| 633 |
}
|
| 634 |
} else {
|
|
|
|
| 635 |
$source_id = $stripe_token;
|
| 636 |
$is_token = true;
|
| 637 |
}
|
| 638 |
}
|
| 639 |
|
| 640 |
+
$customer_id = $customer->get_id();
|
| 641 |
+
if ( ! $customer_id ) {
|
| 642 |
+
$customer->set_id( $customer->create_customer() );
|
| 643 |
+
$customer_id = $customer->get_id();
|
| 644 |
}
|
| 645 |
|
| 646 |
if ( empty( $source_object ) && ! $is_token ) {
|
| 1008 |
}
|
| 1009 |
|
| 1010 |
/**
|
| 1011 |
+
* Generates the request when creating a new payment intent.
|
| 1012 |
*
|
| 1013 |
* @param WC_Order $order The order that is being paid for.
|
| 1014 |
* @param object $prepared_source The source that is used for the payment.
|
| 1015 |
+
* @return array The arguments for the request.
|
| 1016 |
*/
|
| 1017 |
+
public function generate_create_intent_request( $order, $prepared_source ) {
|
| 1018 |
// The request for a charge contains metadata for the intent.
|
| 1019 |
$full_request = $this->generate_payment_request( $order, $prepared_source );
|
| 1020 |
|
| 1024 |
'currency' => strtolower( WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $order->get_order_currency() : $order->get_currency() ),
|
| 1025 |
'description' => $full_request['description'],
|
| 1026 |
'metadata' => $full_request['metadata'],
|
|
|
|
| 1027 |
'capture_method' => ( 'true' === $full_request['capture'] ) ? 'automatic' : 'manual',
|
| 1028 |
'payment_method_types' => array(
|
| 1029 |
'card',
|
| 1034 |
$request['customer'] = $prepared_source->customer;
|
| 1035 |
}
|
| 1036 |
|
| 1037 |
+
if ( isset( $full_request['statement_descriptor'] ) ) {
|
| 1038 |
+
$request['statement_descriptor'] = $full_request['statement_descriptor'];
|
| 1039 |
+
}
|
| 1040 |
+
|
| 1041 |
+
/**
|
| 1042 |
+
* Filter the return value of the WC_Payment_Gateway_CC::generate_create_intent_request.
|
| 1043 |
+
*
|
| 1044 |
+
* @since 3.1.0
|
| 1045 |
+
* @param array $request
|
| 1046 |
+
* @param WC_Order $order
|
| 1047 |
+
* @param object $source
|
| 1048 |
+
*/
|
| 1049 |
+
return apply_filters( 'wc_stripe_generate_create_intent_request', $request, $order, $prepared_source );
|
| 1050 |
+
}
|
| 1051 |
+
|
| 1052 |
+
/**
|
| 1053 |
+
* Create a new PaymentIntent.
|
| 1054 |
+
*
|
| 1055 |
+
* @param WC_Order $order The order that is being paid for.
|
| 1056 |
+
* @param object $prepared_source The source that is used for the payment.
|
| 1057 |
+
* @return object An intent or an error.
|
| 1058 |
+
*/
|
| 1059 |
+
public function create_intent( $order, $prepared_source ) {
|
| 1060 |
+
$request = $this->generate_create_intent_request( $order, $prepared_source );
|
| 1061 |
+
|
| 1062 |
// Create an intent that awaits an action.
|
| 1063 |
$intent = WC_Stripe_API::request( $request, 'payment_intents' );
|
| 1064 |
if ( ! empty( $intent->error ) ) {
|
| 1178 |
$intent_id = $order->get_meta( '_stripe_intent_id' );
|
| 1179 |
}
|
| 1180 |
|
| 1181 |
+
if ( $intent_id ) {
|
| 1182 |
+
return WC_Stripe_API::request( array(), "payment_intents/$intent_id", 'GET' );
|
| 1183 |
+
}
|
| 1184 |
+
|
| 1185 |
+
// The order doesn't have a payment intent, but it may have a setup intent.
|
| 1186 |
+
if ( WC_Stripe_Helper::is_wc_lt( '3.0' ) ) {
|
| 1187 |
+
$intent_id = get_post_meta( $order_id, '_stripe_setup_intent', true );
|
| 1188 |
+
} else {
|
| 1189 |
+
$intent_id = $order->get_meta( '_stripe_setup_intent' );
|
| 1190 |
+
}
|
| 1191 |
+
|
| 1192 |
+
if ( $intent_id ) {
|
| 1193 |
+
return WC_Stripe_API::request( array(), "setup_intents/$intent_id", 'GET' );
|
| 1194 |
}
|
| 1195 |
|
| 1196 |
+
return false;
|
| 1197 |
}
|
| 1198 |
|
| 1199 |
/**
|
| 1230 |
$order_id = WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $order->id : $order->get_id();
|
| 1231 |
delete_transient( 'wc_stripe_processing_intent_' . $order_id );
|
| 1232 |
}
|
| 1233 |
+
|
| 1234 |
+
/**
|
| 1235 |
+
* Given a response from Stripe, check if it's a card error where authentication is required
|
| 1236 |
+
* to complete the payment.
|
| 1237 |
+
*
|
| 1238 |
+
* @param object $response The response from Stripe.
|
| 1239 |
+
* @return boolean Whether or not it's a 'authentication_required' error
|
| 1240 |
+
*/
|
| 1241 |
+
public function is_authentication_required_for_payment( $response ) {
|
| 1242 |
+
return ( ! empty( $response->error ) && 'authentication_required' === $response->error->code )
|
| 1243 |
+
|| ( ! empty( $response->last_payment_error ) && 'authentication_required' === $response->last_payment_error->code );
|
| 1244 |
+
}
|
| 1245 |
+
|
| 1246 |
+
/**
|
| 1247 |
+
* Creates a SetupIntent for future payments, and saves it to the order.
|
| 1248 |
+
*
|
| 1249 |
+
* @param WC_Order $order The ID of the (free/pre- order).
|
| 1250 |
+
* @param object $prepared_source The source, entered/chosen by the customer.
|
| 1251 |
+
* @return string The client secret of the intent, used for confirmation in JS.
|
| 1252 |
+
*/
|
| 1253 |
+
public function setup_intent( $order, $prepared_source ) {
|
| 1254 |
+
$order_id = WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $order->id : $order->get_id();
|
| 1255 |
+
$setup_intent = WC_Stripe_API::request( array(
|
| 1256 |
+
'payment_method' => $prepared_source->source,
|
| 1257 |
+
'customer' => $prepared_source->customer,
|
| 1258 |
+
'confirm' => 'true',
|
| 1259 |
+
), 'setup_intents' );
|
| 1260 |
+
|
| 1261 |
+
if ( is_wp_error( $setup_intent ) ) {
|
| 1262 |
+
WC_Stripe_Logger::log( "Unable to create SetupIntent for Order #$order_id: " . print_r( $setup_intent, true ) );
|
| 1263 |
+
} elseif ( 'requires_action' === $setup_intent->status ) {
|
| 1264 |
+
if ( WC_Stripe_Helper::is_wc_lt( '3.0' ) ) {
|
| 1265 |
+
update_post_meta( $order_id, '_stripe_setup_intent', $setup_intent->id );
|
| 1266 |
+
} else {
|
| 1267 |
+
$order->update_meta_data( '_stripe_setup_intent', $setup_intent->id );
|
| 1268 |
+
$order->save();
|
| 1269 |
+
}
|
| 1270 |
+
|
| 1271 |
+
return $setup_intent->client_secret;
|
| 1272 |
+
}
|
| 1273 |
+
}
|
| 1274 |
+
|
| 1275 |
+
/**
|
| 1276 |
+
* Create and confirm a new PaymentIntent.
|
| 1277 |
+
*
|
| 1278 |
+
* @param WC_Order $order The order that is being paid for.
|
| 1279 |
+
* @param object $prepared_source The source that is used for the payment.
|
| 1280 |
+
* @param float $amount The amount to charge. If not specified, it will be read from the order.
|
| 1281 |
+
* @return object An intent or an error.
|
| 1282 |
+
*/
|
| 1283 |
+
public function create_and_confirm_intent_for_off_session( $order, $prepared_source, $amount = NULL ) {
|
| 1284 |
+
// The request for a charge contains metadata for the intent.
|
| 1285 |
+
$full_request = $this->generate_payment_request( $order, $prepared_source );
|
| 1286 |
+
|
| 1287 |
+
$request = array(
|
| 1288 |
+
'amount' => $amount ? WC_Stripe_Helper::get_stripe_amount( $amount, $full_request['currency'] ) : $full_request['amount'],
|
| 1289 |
+
'currency' => $full_request['currency'],
|
| 1290 |
+
'description' => $full_request['description'],
|
| 1291 |
+
'metadata' => $full_request['metadata'],
|
| 1292 |
+
'payment_method_types' => array(
|
| 1293 |
+
'card',
|
| 1294 |
+
),
|
| 1295 |
+
'off_session' => 'true',
|
| 1296 |
+
'confirm' => 'true',
|
| 1297 |
+
'confirmation_method' => 'automatic',
|
| 1298 |
+
);
|
| 1299 |
+
|
| 1300 |
+
if ( isset( $full_request['statement_descriptor'] ) ) {
|
| 1301 |
+
$request['statement_descriptor'] = $full_request['statement_descriptor'];
|
| 1302 |
+
}
|
| 1303 |
+
|
| 1304 |
+
if ( isset( $full_request['customer'] ) ) {
|
| 1305 |
+
$request['customer'] = $full_request['customer'];
|
| 1306 |
+
}
|
| 1307 |
+
|
| 1308 |
+
if ( isset( $full_request['source'] ) ) {
|
| 1309 |
+
$request['source'] = $full_request['source'];
|
| 1310 |
+
}
|
| 1311 |
+
|
| 1312 |
+
$intent = WC_Stripe_API::request( $request, 'payment_intents' );
|
| 1313 |
+
$is_authentication_required = $this->is_authentication_required_for_payment( $intent );
|
| 1314 |
+
|
| 1315 |
+
if ( ! empty( $intent->error ) && ! $is_authentication_required ) {
|
| 1316 |
+
return $intent;
|
| 1317 |
+
}
|
| 1318 |
+
|
| 1319 |
+
$intent_id = ( ! empty( $intent->error )
|
| 1320 |
+
? $intent->error->payment_intent->id
|
| 1321 |
+
: $intent->id
|
| 1322 |
+
);
|
| 1323 |
+
$payment_intent = ( ! empty( $intent->error )
|
| 1324 |
+
? $intent->error->payment_intent
|
| 1325 |
+
: $intent
|
| 1326 |
+
);
|
| 1327 |
+
$order_id = WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $order->id : $order->get_id();
|
| 1328 |
+
WC_Stripe_Logger::log( "Stripe PaymentIntent $intent_id initiated for order $order_id" );
|
| 1329 |
+
|
| 1330 |
+
// Save the intent ID to the order.
|
| 1331 |
+
$this->save_intent_to_order( $order, $payment_intent );
|
| 1332 |
+
|
| 1333 |
+
return $intent;
|
| 1334 |
+
}
|
| 1335 |
}
|
|
@@ -23,6 +23,7 @@ class WC_Stripe_Admin_Notices {
|
|
| 23 |
public function __construct() {
|
| 24 |
add_action( 'admin_notices', array( $this, 'admin_notices' ) );
|
| 25 |
add_action( 'wp_loaded', array( $this, 'hide_notices' ) );
|
|
|
|
| 26 |
}
|
| 27 |
|
| 28 |
/**
|
|
@@ -106,6 +107,7 @@ class WC_Stripe_Admin_Notices {
|
|
| 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' );
|
|
|
|
| 109 |
$options = get_option( 'woocommerce_stripe_settings' );
|
| 110 |
$testmode = ( isset( $options['testmode'] ) && 'yes' === $options['testmode'] ) ? true : false;
|
| 111 |
$test_pub_key = isset( $options['test_publishable_key'] ) ? $options['test_publishable_key'] : '';
|
|
@@ -126,9 +128,9 @@ class WC_Stripe_Admin_Notices {
|
|
| 126 |
|
| 127 |
if ( empty( $show_style_notice ) ) {
|
| 128 |
/* translators: 1) int version 2) int version */
|
| 129 |
-
$message = __( 'WooCommerce Stripe - We recently made changes to Stripe that may impact the appearance of your checkout. If your checkout has changed unexpectedly, please follow these <a href="https://docs.woocommerce.com/document/stripe/#
|
| 130 |
|
| 131 |
-
$this->add_admin_notice( 'style', '
|
| 132 |
|
| 133 |
return;
|
| 134 |
}
|
|
@@ -199,6 +201,10 @@ class WC_Stripe_Admin_Notices {
|
|
| 199 |
$this->add_admin_notice( 'ssl', 'notice notice-warning', sprintf( __( 'Stripe is enabled, but a SSL certificate is not detected. Your checkout may not be secure! Please ensure your server has a valid <a href="%1$s" target="_blank">SSL certificate</a>', 'woocommerce-gateway-stripe' ), 'https://en.wikipedia.org/wiki/Transport_Layer_Security' ), true );
|
| 200 |
}
|
| 201 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 202 |
}
|
| 203 |
}
|
| 204 |
|
|
@@ -292,6 +298,9 @@ class WC_Stripe_Admin_Notices {
|
|
| 292 |
case 'SOFORT':
|
| 293 |
update_option( 'wc_stripe_show_sofort_notice', 'no' );
|
| 294 |
break;
|
|
|
|
|
|
|
|
|
|
| 295 |
}
|
| 296 |
}
|
| 297 |
}
|
|
@@ -310,6 +319,25 @@ class WC_Stripe_Admin_Notices {
|
|
| 310 |
|
| 311 |
return admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=' . $section_slug );
|
| 312 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 313 |
}
|
| 314 |
|
| 315 |
new WC_Stripe_Admin_Notices();
|
| 23 |
public function __construct() {
|
| 24 |
add_action( 'admin_notices', array( $this, 'admin_notices' ) );
|
| 25 |
add_action( 'wp_loaded', array( $this, 'hide_notices' ) );
|
| 26 |
+
add_action( 'woocommerce_stripe_updated', array( $this, 'stripe_updated' ) );
|
| 27 |
}
|
| 28 |
|
| 29 |
/**
|
| 107 |
$show_phpver_notice = get_option( 'wc_stripe_show_phpver_notice' );
|
| 108 |
$show_wcver_notice = get_option( 'wc_stripe_show_wcver_notice' );
|
| 109 |
$show_curl_notice = get_option( 'wc_stripe_show_curl_notice' );
|
| 110 |
+
$show_sca_notice = get_option( 'wc_stripe_show_sca_notice' );
|
| 111 |
$options = get_option( 'woocommerce_stripe_settings' );
|
| 112 |
$testmode = ( isset( $options['testmode'] ) && 'yes' === $options['testmode'] ) ? true : false;
|
| 113 |
$test_pub_key = isset( $options['test_publishable_key'] ) ? $options['test_publishable_key'] : '';
|
| 128 |
|
| 129 |
if ( empty( $show_style_notice ) ) {
|
| 130 |
/* translators: 1) int version 2) int version */
|
| 131 |
+
$message = __( 'WooCommerce Stripe - We recently made changes to Stripe that may impact the appearance of your checkout. If your checkout has changed unexpectedly, please follow these <a href="https://docs.woocommerce.com/document/stripe/#styling" target="_blank">instructions</a> to fix.', 'woocommerce-gateway-stripe' );
|
| 132 |
|
| 133 |
+
$this->add_admin_notice( 'style', 'notice notice-warning', $message, true );
|
| 134 |
|
| 135 |
return;
|
| 136 |
}
|
| 201 |
$this->add_admin_notice( 'ssl', 'notice notice-warning', sprintf( __( 'Stripe is enabled, but a SSL certificate is not detected. Your checkout may not be secure! Please ensure your server has a valid <a href="%1$s" target="_blank">SSL certificate</a>', 'woocommerce-gateway-stripe' ), 'https://en.wikipedia.org/wiki/Transport_Layer_Security' ), true );
|
| 202 |
}
|
| 203 |
}
|
| 204 |
+
|
| 205 |
+
if ( empty( $show_sca_notice ) ) {
|
| 206 |
+
$this->add_admin_notice( 'sca', 'notice notice-success', sprintf( __( 'Stripe is now ready for Strong Customer Authentication (SCA) and 3D Secure 2! <a href="%1$s" target="_blank">Read about SCA</a>', 'woocommerce-gateway-stripe' ), 'https://woocommerce.com/posts/introducing-strong-customer-authentication-sca/' ), true );
|
| 207 |
+
}
|
| 208 |
}
|
| 209 |
}
|
| 210 |
|
| 298 |
case 'SOFORT':
|
| 299 |
update_option( 'wc_stripe_show_sofort_notice', 'no' );
|
| 300 |
break;
|
| 301 |
+
case 'sca':
|
| 302 |
+
update_option( 'wc_stripe_show_sca_notice', 'no' );
|
| 303 |
+
break;
|
| 304 |
}
|
| 305 |
}
|
| 306 |
}
|
| 319 |
|
| 320 |
return admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=' . $section_slug );
|
| 321 |
}
|
| 322 |
+
|
| 323 |
+
/**
|
| 324 |
+
* Saves options in order to hide notices based on the gateway's version.
|
| 325 |
+
*
|
| 326 |
+
* @since 4.3.0
|
| 327 |
+
*/
|
| 328 |
+
public function stripe_updated() {
|
| 329 |
+
$previous_version = get_option( 'wc_stripe_version' );
|
| 330 |
+
|
| 331 |
+
// Only show the style notice if the plugin was installed and older than 4.1.4.
|
| 332 |
+
if ( empty( $previous_version ) || version_compare( $previous_version, '4.1.4', 'ge' ) ) {
|
| 333 |
+
update_option( 'wc_stripe_show_style_notice', 'no' );
|
| 334 |
+
}
|
| 335 |
+
|
| 336 |
+
// Only show the SCA notice on pre-4.3.0 installs.
|
| 337 |
+
if ( empty( $previous_version ) || version_compare( $previous_version, '4.3.0', 'ge' ) ) {
|
| 338 |
+
update_option( 'wc_stripe_show_sca_notice', 'no' );
|
| 339 |
+
}
|
| 340 |
+
}
|
| 341 |
}
|
| 342 |
|
| 343 |
new WC_Stripe_Admin_Notices();
|
|
@@ -139,6 +139,7 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
|
|
| 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 |
add_action( 'set_logged_in_cookie', array( $this, 'set_cookie_on_current_request' ) );
|
|
|
|
| 142 |
|
| 143 |
if ( WC_Stripe_Helper::is_pre_orders_exists() ) {
|
| 144 |
$this->pre_orders = new WC_Stripe_Pre_Orders_Compat();
|
|
@@ -248,29 +249,17 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
|
|
| 248 |
}
|
| 249 |
|
| 250 |
if ( is_add_payment_method_page() ) {
|
| 251 |
-
$pay_button_text = __( 'Add Card', 'woocommerce-gateway-stripe' );
|
| 252 |
-
$total = '';
|
| 253 |
$firstname = $user->user_firstname;
|
| 254 |
$lastname = $user->user_lastname;
|
| 255 |
-
|
| 256 |
-
} elseif ( function_exists( 'wcs_order_contains_subscription' ) && isset( $_GET['change_payment_method'] ) ) { // wpcs: csrf ok.
|
| 257 |
-
$pay_button_text = __( 'Change Payment Method', 'woocommerce-gateway-stripe' );
|
| 258 |
-
$total = '';
|
| 259 |
-
} else {
|
| 260 |
-
$pay_button_text = '';
|
| 261 |
}
|
| 262 |
|
| 263 |
ob_start();
|
| 264 |
|
| 265 |
echo '<div
|
| 266 |
id="stripe-payment-data"
|
| 267 |
-
data-panel-label="' . esc_attr( $pay_button_text ) . '"
|
| 268 |
data-email="' . esc_attr( $user_email ) . '"
|
| 269 |
-
data-amount="' . esc_attr( WC_Stripe_Helper::get_stripe_amount( $total ) ) . '"
|
| 270 |
-
data-name="' . esc_attr( $this->statement_descriptor ) . '"
|
| 271 |
data-full-name="' . esc_attr( $firstname . ' ' . $lastname ) . '"
|
| 272 |
data-currency="' . esc_attr( strtolower( get_woocommerce_currency() ) ) . '"
|
| 273 |
-
data-allow-remember-me="' . esc_attr( apply_filters( 'wc_stripe_allow_remember_me', true ) ? 'true' : 'false' ) . '"
|
| 274 |
>';
|
| 275 |
|
| 276 |
if ( $this->testmode ) {
|
|
@@ -383,7 +372,7 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
|
|
| 383 |
* @version 4.0.0
|
| 384 |
*/
|
| 385 |
public function payment_scripts() {
|
| 386 |
-
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.
|
| 387 |
return;
|
| 388 |
}
|
| 389 |
|
|
@@ -476,23 +465,6 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
|
|
| 476 |
wp_enqueue_script( 'woocommerce_stripe' );
|
| 477 |
}
|
| 478 |
|
| 479 |
-
/**
|
| 480 |
-
* Creates a new WC_Stripe_Customer if the visitor chooses to.
|
| 481 |
-
*
|
| 482 |
-
* @since 4.2.0
|
| 483 |
-
* @param WC_Order $order The order that is being created.
|
| 484 |
-
*/
|
| 485 |
-
public function maybe_create_customer( $order ) {
|
| 486 |
-
// This comes from the create account checkbox in the checkout page.
|
| 487 |
-
if ( empty( $_POST['createaccount'] ) ) { // wpcs: csrf ok.
|
| 488 |
-
return;
|
| 489 |
-
}
|
| 490 |
-
|
| 491 |
-
$new_customer_id = WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $order->customer_user : $order->get_customer_id();
|
| 492 |
-
$new_stripe_customer = new WC_Stripe_Customer( $new_customer_id );
|
| 493 |
-
$new_stripe_customer->create_customer();
|
| 494 |
-
}
|
| 495 |
-
|
| 496 |
/**
|
| 497 |
* Checks if a source object represents a prepaid credit card and
|
| 498 |
* throws an exception if it is one, but that is not allowed.
|
|
@@ -554,20 +526,33 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
|
|
| 554 |
* Completes an order without a positive value.
|
| 555 |
*
|
| 556 |
* @since 4.2.0
|
| 557 |
-
* @param WC_Order $order
|
| 558 |
-
* @
|
|
|
|
|
|
|
| 559 |
*/
|
| 560 |
-
public function complete_free_order( $order ) {
|
| 561 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 562 |
|
| 563 |
// Remove cart.
|
| 564 |
WC()->cart->empty_cart();
|
| 565 |
|
|
|
|
|
|
|
| 566 |
// Return thank you page redirect.
|
| 567 |
-
return
|
| 568 |
-
'result' => 'success',
|
| 569 |
-
'redirect' => $this->get_return_url( $order ),
|
| 570 |
-
);
|
| 571 |
}
|
| 572 |
|
| 573 |
/**
|
|
@@ -593,8 +578,6 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
|
|
| 593 |
return $this->pre_orders->process_pre_order( $order_id );
|
| 594 |
}
|
| 595 |
|
| 596 |
-
$this->maybe_create_customer( $order );
|
| 597 |
-
|
| 598 |
$prepared_source = $this->prepare_source( get_current_user_id(), $force_save_source );
|
| 599 |
|
| 600 |
$this->maybe_disallow_prepaid_card( $prepared_source );
|
|
@@ -602,7 +585,7 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
|
|
| 602 |
$this->save_source_to_order( $order, $prepared_source );
|
| 603 |
|
| 604 |
if ( 0 >= $order->get_total() ) {
|
| 605 |
-
return $this->complete_free_order( $order );
|
| 606 |
}
|
| 607 |
|
| 608 |
// This will throw exception if not valid.
|
|
@@ -611,6 +594,10 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
|
|
| 611 |
WC_Stripe_Logger::log( "Info: Begin processing payment for order $order_id for the amount of {$order->get_total()}" );
|
| 612 |
|
| 613 |
$intent = $this->get_intent_from_order( $order );
|
|
|
|
|
|
|
|
|
|
|
|
|
| 614 |
if ( $intent ) {
|
| 615 |
$intent = $this->update_existing_intent( $intent, $order, $prepared_source );
|
| 616 |
} else {
|
|
@@ -658,9 +645,9 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
|
|
| 658 |
*/
|
| 659 |
|
| 660 |
return array(
|
| 661 |
-
'result'
|
| 662 |
-
'redirect'
|
| 663 |
-
'
|
| 664 |
);
|
| 665 |
}
|
| 666 |
}
|
|
@@ -670,7 +657,9 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
|
|
| 670 |
$this->process_response( $response, $order );
|
| 671 |
|
| 672 |
// Remove cart.
|
| 673 |
-
WC()->cart
|
|
|
|
|
|
|
| 674 |
|
| 675 |
// Unlock the order.
|
| 676 |
$this->unlock_order_payment( $order );
|
|
@@ -836,9 +825,16 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
|
|
| 836 |
return $gateways;
|
| 837 |
}
|
| 838 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 839 |
add_filter( 'woocommerce_checkout_show_terms', '__return_false' );
|
| 840 |
add_filter( 'woocommerce_pay_order_button_html', '__return_false' );
|
| 841 |
-
add_filter( 'woocommerce_available_payment_gateways',
|
| 842 |
add_filter( 'woocommerce_no_available_payment_methods_message', array( $this, 'change_no_available_methods_message' ) );
|
| 843 |
add_action( 'woocommerce_pay_order_after_submit', array( $this, 'render_payment_intent_inputs' ) );
|
| 844 |
|
|
@@ -856,14 +852,52 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
|
|
| 856 |
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' ) );
|
| 857 |
}
|
| 858 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 859 |
/**
|
| 860 |
* Renders hidden inputs on the "Pay for Order" page in order to let Stripe handle PaymentIntents.
|
| 861 |
*
|
|
|
|
|
|
|
|
|
|
| 862 |
* @since 4.2
|
| 863 |
*/
|
| 864 |
-
public function render_payment_intent_inputs() {
|
| 865 |
-
|
| 866 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 867 |
|
| 868 |
$verification_url = add_query_arg(
|
| 869 |
array(
|
|
@@ -875,7 +909,7 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
|
|
| 875 |
WC_AJAX::get_endpoint( 'wc_stripe_verify_intent' )
|
| 876 |
);
|
| 877 |
|
| 878 |
-
echo '<input type="hidden" id="stripe-intent-id" value="' . esc_attr( $
|
| 879 |
echo '<input type="hidden" id="stripe-intent-return" value="' . esc_attr( $verification_url ) . '" />';
|
| 880 |
}
|
| 881 |
|
|
@@ -917,7 +951,7 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
|
|
| 917 |
/**
|
| 918 |
* Attached to `woocommerce_payment_successful_result` with a late priority,
|
| 919 |
* this method will combine the "naturally" generated redirect URL from
|
| 920 |
-
* WooCommerce and a payment intent secret into a hash, which contains both
|
| 921 |
* the secret, and a proper URL, which will confirm whether the intent succeeded.
|
| 922 |
*
|
| 923 |
* @since 4.2.0
|
|
@@ -926,8 +960,8 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
|
|
| 926 |
* @return array
|
| 927 |
*/
|
| 928 |
public function modify_successful_payment_result( $result, $order_id ) {
|
| 929 |
-
|
| 930 |
-
|
| 931 |
return $result;
|
| 932 |
}
|
| 933 |
|
|
@@ -941,8 +975,11 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
|
|
| 941 |
WC_AJAX::get_endpoint( 'wc_stripe_verify_intent' )
|
| 942 |
);
|
| 943 |
|
| 944 |
-
|
| 945 |
-
|
|
|
|
|
|
|
|
|
|
| 946 |
|
| 947 |
return array(
|
| 948 |
'result' => 'success',
|
|
@@ -990,7 +1027,14 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
|
|
| 990 |
return;
|
| 991 |
}
|
| 992 |
|
| 993 |
-
if ( '
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 994 |
// Proceed with the payment completion.
|
| 995 |
$this->process_response( end( $intent->charges->data ), $order );
|
| 996 |
} else if ( 'requires_payment_method' === $intent->status ) {
|
|
@@ -1015,12 +1059,26 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
|
|
| 1015 |
}
|
| 1016 |
|
| 1017 |
// Load the right message and update the status.
|
| 1018 |
-
$status_message = ( $intent->last_payment_error )
|
| 1019 |
/* translators: 1) The error message that was received from Stripe. */
|
| 1020 |
? sprintf( __( 'Stripe SCA authentication failed. Reason: %s', 'woocommerce-gateway-stripe' ), $intent->last_payment_error->message )
|
| 1021 |
: __( 'Stripe SCA authentication failed.', 'woocommerce-gateway-stripe' );
|
| 1022 |
$order->update_status( 'failed', $status_message );
|
|
|
|
| 1023 |
|
| 1024 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1025 |
}
|
| 1026 |
}
|
| 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 |
add_action( 'set_logged_in_cookie', array( $this, 'set_cookie_on_current_request' ) );
|
| 142 |
+
add_filter( 'woocommerce_get_checkout_payment_url', array( $this, 'get_checkout_payment_url' ), 10, 2 );
|
| 143 |
|
| 144 |
if ( WC_Stripe_Helper::is_pre_orders_exists() ) {
|
| 145 |
$this->pre_orders = new WC_Stripe_Pre_Orders_Compat();
|
| 249 |
}
|
| 250 |
|
| 251 |
if ( is_add_payment_method_page() ) {
|
|
|
|
|
|
|
| 252 |
$firstname = $user->user_firstname;
|
| 253 |
$lastname = $user->user_lastname;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 254 |
}
|
| 255 |
|
| 256 |
ob_start();
|
| 257 |
|
| 258 |
echo '<div
|
| 259 |
id="stripe-payment-data"
|
|
|
|
| 260 |
data-email="' . esc_attr( $user_email ) . '"
|
|
|
|
|
|
|
| 261 |
data-full-name="' . esc_attr( $firstname . ' ' . $lastname ) . '"
|
| 262 |
data-currency="' . esc_attr( strtolower( get_woocommerce_currency() ) ) . '"
|
|
|
|
| 263 |
>';
|
| 264 |
|
| 265 |
if ( $this->testmode ) {
|
| 372 |
* @version 4.0.0
|
| 373 |
*/
|
| 374 |
public function payment_scripts() {
|
| 375 |
+
if ( ! is_product() && ! is_cart() && ! is_checkout() && ! isset( $_GET['pay_for_order'] ) && ! is_add_payment_method_page() && ! isset( $_GET['change_payment_method'] ) || ( is_order_received_page() ) ) { // wpcs: csrf ok.
|
| 376 |
return;
|
| 377 |
}
|
| 378 |
|
| 465 |
wp_enqueue_script( 'woocommerce_stripe' );
|
| 466 |
}
|
| 467 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 468 |
/**
|
| 469 |
* Checks if a source object represents a prepaid credit card and
|
| 470 |
* throws an exception if it is one, but that is not allowed.
|
| 526 |
* Completes an order without a positive value.
|
| 527 |
*
|
| 528 |
* @since 4.2.0
|
| 529 |
+
* @param WC_Order $order The order to complete.
|
| 530 |
+
* @param WC_Order $prepared_source Payment source and customer data.
|
| 531 |
+
* @param boolean $force_save_source Whether the payment source must be saved, like when dealing with a Subscription setup.
|
| 532 |
+
* @return array Redirection data for `process_payment`.
|
| 533 |
*/
|
| 534 |
+
public function complete_free_order( $order, $prepared_source, $force_save_source ) {
|
| 535 |
+
$response = array(
|
| 536 |
+
'result' => 'success',
|
| 537 |
+
'redirect' => $this->get_return_url( $order ),
|
| 538 |
+
);
|
| 539 |
+
|
| 540 |
+
if ( $force_save_source ) {
|
| 541 |
+
$intent_secret = $this->setup_intent( $order, $prepared_source );
|
| 542 |
+
|
| 543 |
+
if ( ! empty( $intent_secret ) ) {
|
| 544 |
+
$response['setup_intent_secret'] = $intent_secret;
|
| 545 |
+
return $response;
|
| 546 |
+
}
|
| 547 |
+
}
|
| 548 |
|
| 549 |
// Remove cart.
|
| 550 |
WC()->cart->empty_cart();
|
| 551 |
|
| 552 |
+
$order->payment_complete();
|
| 553 |
+
|
| 554 |
// Return thank you page redirect.
|
| 555 |
+
return $response;
|
|
|
|
|
|
|
|
|
|
| 556 |
}
|
| 557 |
|
| 558 |
/**
|
| 578 |
return $this->pre_orders->process_pre_order( $order_id );
|
| 579 |
}
|
| 580 |
|
|
|
|
|
|
|
| 581 |
$prepared_source = $this->prepare_source( get_current_user_id(), $force_save_source );
|
| 582 |
|
| 583 |
$this->maybe_disallow_prepaid_card( $prepared_source );
|
| 585 |
$this->save_source_to_order( $order, $prepared_source );
|
| 586 |
|
| 587 |
if ( 0 >= $order->get_total() ) {
|
| 588 |
+
return $this->complete_free_order( $order, $prepared_source, $force_save_source );
|
| 589 |
}
|
| 590 |
|
| 591 |
// This will throw exception if not valid.
|
| 594 |
WC_Stripe_Logger::log( "Info: Begin processing payment for order $order_id for the amount of {$order->get_total()}" );
|
| 595 |
|
| 596 |
$intent = $this->get_intent_from_order( $order );
|
| 597 |
+
if ( isset( $intent->object ) && 'setup_intent' === $intent->object ) {
|
| 598 |
+
$intent = false; // This function can only deal with *payment* intents
|
| 599 |
+
}
|
| 600 |
+
|
| 601 |
if ( $intent ) {
|
| 602 |
$intent = $this->update_existing_intent( $intent, $order, $prepared_source );
|
| 603 |
} else {
|
| 645 |
*/
|
| 646 |
|
| 647 |
return array(
|
| 648 |
+
'result' => 'success',
|
| 649 |
+
'redirect' => $this->get_return_url( $order ),
|
| 650 |
+
'payment_intent_secret' => $intent->client_secret,
|
| 651 |
);
|
| 652 |
}
|
| 653 |
}
|
| 657 |
$this->process_response( $response, $order );
|
| 658 |
|
| 659 |
// Remove cart.
|
| 660 |
+
if ( isset( WC()->cart ) ) {
|
| 661 |
+
WC()->cart->empty_cart();
|
| 662 |
+
}
|
| 663 |
|
| 664 |
// Unlock the order.
|
| 665 |
$this->unlock_order_payment( $order );
|
| 825 |
return $gateways;
|
| 826 |
}
|
| 827 |
|
| 828 |
+
try {
|
| 829 |
+
$this->prepare_intent_for_order_pay_page();
|
| 830 |
+
} catch ( WC_Stripe_Exception $e ) {
|
| 831 |
+
// Just show the full order pay page if there was a problem preparing the Payment Intent
|
| 832 |
+
return $gateways;
|
| 833 |
+
}
|
| 834 |
+
|
| 835 |
add_filter( 'woocommerce_checkout_show_terms', '__return_false' );
|
| 836 |
add_filter( 'woocommerce_pay_order_button_html', '__return_false' );
|
| 837 |
+
add_filter( 'woocommerce_available_payment_gateways', '__return_empty_array' );
|
| 838 |
add_filter( 'woocommerce_no_available_payment_methods_message', array( $this, 'change_no_available_methods_message' ) );
|
| 839 |
add_action( 'woocommerce_pay_order_after_submit', array( $this, 'render_payment_intent_inputs' ) );
|
| 840 |
|
| 852 |
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' ) );
|
| 853 |
}
|
| 854 |
|
| 855 |
+
/**
|
| 856 |
+
* Prepares the Payment Intent for it to be completed in the "Pay for Order" page.
|
| 857 |
+
*
|
| 858 |
+
* @param WC_Order|null $order Order object, or null to get the order from the "order-pay" URL parameter
|
| 859 |
+
*
|
| 860 |
+
* @throws WC_Stripe_Exception
|
| 861 |
+
* @since 4.3
|
| 862 |
+
*/
|
| 863 |
+
public function prepare_intent_for_order_pay_page( $order = null ) {
|
| 864 |
+
if ( ! isset( $order ) || empty( $order ) ) {
|
| 865 |
+
$order = wc_get_order( absint( get_query_var( 'order-pay' ) ) );
|
| 866 |
+
}
|
| 867 |
+
$intent = $this->get_intent_from_order( $order );
|
| 868 |
+
|
| 869 |
+
if ( ! $intent ) {
|
| 870 |
+
throw new WC_Stripe_Exception( 'Payment Intent not found', __( 'Payment Intent not found for order #' . $order->get_id(), 'woocommerce-gateway-stripe' ) );
|
| 871 |
+
}
|
| 872 |
+
|
| 873 |
+
if ( 'requires_payment_method' === $intent->status && isset( $intent->last_payment_error )
|
| 874 |
+
&& 'authentication_required' === $intent->last_payment_error->code ) {
|
| 875 |
+
$intent = WC_Stripe_API::request( array(
|
| 876 |
+
'payment_method' => $intent->last_payment_error->source->id,
|
| 877 |
+
), 'payment_intents/' . $intent->id . '/confirm' );
|
| 878 |
+
if ( isset( $intent->error ) ) {
|
| 879 |
+
throw new WC_Stripe_Exception( print_r( $intent, true ), $intent->error->message );
|
| 880 |
+
}
|
| 881 |
+
}
|
| 882 |
+
|
| 883 |
+
$this->order_pay_intent = $intent;
|
| 884 |
+
}
|
| 885 |
+
|
| 886 |
/**
|
| 887 |
* Renders hidden inputs on the "Pay for Order" page in order to let Stripe handle PaymentIntents.
|
| 888 |
*
|
| 889 |
+
* @param WC_Order|null $order Order object, or null to get the order from the "order-pay" URL parameter
|
| 890 |
+
*
|
| 891 |
+
* @throws WC_Stripe_Exception
|
| 892 |
* @since 4.2
|
| 893 |
*/
|
| 894 |
+
public function render_payment_intent_inputs( $order = null ) {
|
| 895 |
+
if ( ! isset( $order ) || empty( $order ) ) {
|
| 896 |
+
$order = wc_get_order( absint( get_query_var( 'order-pay' ) ) );
|
| 897 |
+
}
|
| 898 |
+
if ( ! isset( $this->order_pay_intent ) ) {
|
| 899 |
+
$this->prepare_intent_for_order_pay_page( $order );
|
| 900 |
+
}
|
| 901 |
|
| 902 |
$verification_url = add_query_arg(
|
| 903 |
array(
|
| 909 |
WC_AJAX::get_endpoint( 'wc_stripe_verify_intent' )
|
| 910 |
);
|
| 911 |
|
| 912 |
+
echo '<input type="hidden" id="stripe-intent-id" value="' . esc_attr( $this->order_pay_intent->client_secret ) . '" />';
|
| 913 |
echo '<input type="hidden" id="stripe-intent-return" value="' . esc_attr( $verification_url ) . '" />';
|
| 914 |
}
|
| 915 |
|
| 951 |
/**
|
| 952 |
* Attached to `woocommerce_payment_successful_result` with a late priority,
|
| 953 |
* this method will combine the "naturally" generated redirect URL from
|
| 954 |
+
* WooCommerce and a payment/setup intent secret into a hash, which contains both
|
| 955 |
* the secret, and a proper URL, which will confirm whether the intent succeeded.
|
| 956 |
*
|
| 957 |
* @since 4.2.0
|
| 960 |
* @return array
|
| 961 |
*/
|
| 962 |
public function modify_successful_payment_result( $result, $order_id ) {
|
| 963 |
+
if ( ! isset( $result['payment_intent_secret'] ) && ! isset( $result['setup_intent_secret'] ) ) {
|
| 964 |
+
// Only redirects with intents need to be modified.
|
| 965 |
return $result;
|
| 966 |
}
|
| 967 |
|
| 975 |
WC_AJAX::get_endpoint( 'wc_stripe_verify_intent' )
|
| 976 |
);
|
| 977 |
|
| 978 |
+
if ( isset( $result['payment_intent_secret'] ) ) {
|
| 979 |
+
$redirect = sprintf( '#confirm-pi-%s:%s', $result['payment_intent_secret'], rawurlencode( $verification_url ) );
|
| 980 |
+
} else if ( isset( $result['setup_intent_secret'] ) ) {
|
| 981 |
+
$redirect = sprintf( '#confirm-si-%s:%s', $result['setup_intent_secret'], rawurlencode( $verification_url ) );
|
| 982 |
+
}
|
| 983 |
|
| 984 |
return array(
|
| 985 |
'result' => 'success',
|
| 1027 |
return;
|
| 1028 |
}
|
| 1029 |
|
| 1030 |
+
if ( 'setup_intent' === $intent->object && 'succeeded' === $intent->status ) {
|
| 1031 |
+
WC()->cart->empty_cart();
|
| 1032 |
+
if ( WC_Stripe_Helper::is_pre_orders_exists() && WC_Pre_Orders_Order::order_contains_pre_order( $order ) ) {
|
| 1033 |
+
WC_Pre_Orders_Order::mark_order_as_pre_ordered( $order );
|
| 1034 |
+
} else {
|
| 1035 |
+
$order->payment_complete();
|
| 1036 |
+
}
|
| 1037 |
+
} else if ( 'succeeded' === $intent->status || 'requires_capture' === $intent->status ) {
|
| 1038 |
// Proceed with the payment completion.
|
| 1039 |
$this->process_response( end( $intent->charges->data ), $order );
|
| 1040 |
} else if ( 'requires_payment_method' === $intent->status ) {
|
| 1059 |
}
|
| 1060 |
|
| 1061 |
// Load the right message and update the status.
|
| 1062 |
+
$status_message = isset( $intent->last_payment_error )
|
| 1063 |
/* translators: 1) The error message that was received from Stripe. */
|
| 1064 |
? sprintf( __( 'Stripe SCA authentication failed. Reason: %s', 'woocommerce-gateway-stripe' ), $intent->last_payment_error->message )
|
| 1065 |
: __( 'Stripe SCA authentication failed.', 'woocommerce-gateway-stripe' );
|
| 1066 |
$order->update_status( 'failed', $status_message );
|
| 1067 |
+
}
|
| 1068 |
|
| 1069 |
+
/**
|
| 1070 |
+
* Preserves the "wc-stripe-confirmation" URL parameter so the user can complete the SCA authentication after logging in.
|
| 1071 |
+
*
|
| 1072 |
+
* @param string $pay_url Current computed checkout URL for the given order.
|
| 1073 |
+
* @param WC_Order $order Order object.
|
| 1074 |
+
*
|
| 1075 |
+
* @return string Checkout URL for the given order.
|
| 1076 |
+
*/
|
| 1077 |
+
public function get_checkout_payment_url( $pay_url, $order ) {
|
| 1078 |
+
global $wp;
|
| 1079 |
+
if ( isset( $_GET['wc-stripe-confirmation'] ) && isset( $wp->query_vars['order-pay'] ) && $wp->query_vars['order-pay'] == $order->get_id() ) {
|
| 1080 |
+
$pay_url = add_query_arg( 'wc-stripe-confirmation', 1, $pay_url );
|
| 1081 |
+
}
|
| 1082 |
+
return $pay_url;
|
| 1083 |
}
|
| 1084 |
}
|
|
@@ -14,7 +14,7 @@ class WC_Stripe_API {
|
|
| 14 |
* Stripe API Endpoint
|
| 15 |
*/
|
| 16 |
const ENDPOINT = 'https://api.stripe.com/v1/';
|
| 17 |
-
const STRIPE_API_VERSION = '2019-
|
| 18 |
|
| 19 |
/**
|
| 20 |
* Secret API Key.
|
| 14 |
* Stripe API Endpoint
|
| 15 |
*/
|
| 16 |
const ENDPOINT = 'https://api.stripe.com/v1/';
|
| 17 |
+
const STRIPE_API_VERSION = '2019-09-09';
|
| 18 |
|
| 19 |
/**
|
| 20 |
* Secret API Key.
|
|
@@ -116,16 +116,23 @@ class WC_Stripe_Customer {
|
|
| 116 |
$billing_last_name = get_user_meta( $user->ID, 'last_name', true );
|
| 117 |
}
|
| 118 |
|
| 119 |
-
|
|
|
|
| 120 |
|
| 121 |
$defaults = array(
|
| 122 |
'email' => $user->user_email,
|
| 123 |
'description' => $description,
|
| 124 |
);
|
| 125 |
} else {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 126 |
$defaults = array(
|
| 127 |
'email' => $billing_email,
|
| 128 |
-
'description' =>
|
| 129 |
);
|
| 130 |
}
|
| 131 |
|
|
@@ -171,10 +178,9 @@ class WC_Stripe_Customer {
|
|
| 171 |
/**
|
| 172 |
* Add a source for this stripe customer.
|
| 173 |
* @param string $source_id
|
| 174 |
-
* @param bool $retry
|
| 175 |
* @return WP_Error|int
|
| 176 |
*/
|
| 177 |
-
public function add_source( $source_id
|
| 178 |
if ( ! $this->get_id() ) {
|
| 179 |
$this->set_id( $this->create_customer() );
|
| 180 |
}
|
|
@@ -195,7 +201,7 @@ class WC_Stripe_Customer {
|
|
| 195 |
if ( $this->is_no_such_customer_error( $response->error ) ) {
|
| 196 |
delete_user_meta( $this->get_user_id(), '_stripe_customer_id' );
|
| 197 |
$this->create_customer();
|
| 198 |
-
return $this->add_source( $source_id
|
| 199 |
} else {
|
| 200 |
return $response;
|
| 201 |
}
|
| 116 |
$billing_last_name = get_user_meta( $user->ID, 'last_name', true );
|
| 117 |
}
|
| 118 |
|
| 119 |
+
// translators: %1$s First name, %2$s Second name, %3$s Username.
|
| 120 |
+
$description = sprintf( __( 'Name: %1$s %2$s, Username: %s', 'woocommerce-gateway-stripe' ), $billing_first_name, $billing_last_name, $user->user_login );
|
| 121 |
|
| 122 |
$defaults = array(
|
| 123 |
'email' => $user->user_email,
|
| 124 |
'description' => $description,
|
| 125 |
);
|
| 126 |
} else {
|
| 127 |
+
$billing_first_name = isset( $_POST['billing_first_name'] ) ? filter_var( wp_unslash( $_POST['billing_first_name'] ), FILTER_SANITIZE_STRING ) : ''; // phpcs:ignore WordPress.Security.NonceVerification
|
| 128 |
+
$billing_last_name = isset( $_POST['billing_last_name'] ) ? filter_var( wp_unslash( $_POST['billing_last_name'] ), FILTER_SANITIZE_STRING ) : ''; // phpcs:ignore WordPress.Security.NonceVerification
|
| 129 |
+
|
| 130 |
+
// translators: %1$s First name, %2$s Second name.
|
| 131 |
+
$description = sprintf( __( 'Name: %1$s %2$s, Guest', 'woocommerce-gateway-stripe' ), $billing_first_name, $billing_last_name );
|
| 132 |
+
|
| 133 |
$defaults = array(
|
| 134 |
'email' => $billing_email,
|
| 135 |
+
'description' => $description,
|
| 136 |
);
|
| 137 |
}
|
| 138 |
|
| 178 |
/**
|
| 179 |
* Add a source for this stripe customer.
|
| 180 |
* @param string $source_id
|
|
|
|
| 181 |
* @return WP_Error|int
|
| 182 |
*/
|
| 183 |
+
public function add_source( $source_id ) {
|
| 184 |
if ( ! $this->get_id() ) {
|
| 185 |
$this->set_id( $this->create_customer() );
|
| 186 |
}
|
| 201 |
if ( $this->is_no_such_customer_error( $response->error ) ) {
|
| 202 |
delete_user_meta( $this->get_user_id(), '_stripe_customer_id' );
|
| 203 |
$this->create_customer();
|
| 204 |
+
return $this->add_source( $source_id );
|
| 205 |
} else {
|
| 206 |
return $response;
|
| 207 |
}
|
|
@@ -453,6 +453,25 @@ class WC_Stripe_Helper {
|
|
| 453 |
return false;
|
| 454 |
}
|
| 455 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 456 |
/**
|
| 457 |
* Sanitize statement descriptor text.
|
| 458 |
*
|
| 453 |
return false;
|
| 454 |
}
|
| 455 |
|
| 456 |
+
/**
|
| 457 |
+
* Gets the order by Stripe SetupIntent ID.
|
| 458 |
+
*
|
| 459 |
+
* @since 4.3
|
| 460 |
+
* @param string $intent_id The ID of the intent.
|
| 461 |
+
* @return WC_Order|bool Either an order or false when not found.
|
| 462 |
+
*/
|
| 463 |
+
public static function get_order_by_setup_intent_id( $intent_id ) {
|
| 464 |
+
global $wpdb;
|
| 465 |
+
|
| 466 |
+
$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_setup_intent' ) );
|
| 467 |
+
|
| 468 |
+
if ( ! empty( $order_id ) ) {
|
| 469 |
+
return wc_get_order( $order_id );
|
| 470 |
+
}
|
| 471 |
+
|
| 472 |
+
return false;
|
| 473 |
+
}
|
| 474 |
+
|
| 475 |
/**
|
| 476 |
* Sanitize statement descriptor text.
|
| 477 |
*
|
|
@@ -92,7 +92,7 @@ class WC_Stripe_Intent_Controller {
|
|
| 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 );
|
| 92 |
wc_add_notice( esc_html( $message ), 'error' );
|
| 93 |
|
| 94 |
$redirect_url = $woocommerce->cart->is_empty()
|
| 95 |
+
? get_permalink( WC_Stripe_Helper::is_wc_lt( '3.0' ) ? woocommerce_get_page_id( 'shop' ) : wc_get_page_id( 'shop' ) )
|
| 96 |
: wc_get_checkout_url();
|
| 97 |
|
| 98 |
$this->handle_error( $e, $redirect_url );
|
|
@@ -81,7 +81,6 @@ class WC_Stripe_Webhook_Handler extends WC_Stripe_Payment_Gateway {
|
|
| 81 |
*
|
| 82 |
* @since 4.0.0
|
| 83 |
* @version 4.0.0
|
| 84 |
-
* @todo Implement proper webhook signature validation. Ref https://stripe.com/docs/webhooks#signatures
|
| 85 |
* @param string $request_headers The request headers from Stripe.
|
| 86 |
* @param string $request_body The request body from Stripe.
|
| 87 |
* @return bool
|
|
@@ -693,6 +692,43 @@ class WC_Stripe_Webhook_Handler extends WC_Stripe_Payment_Gateway {
|
|
| 693 |
$this->unlock_order_payment( $order );
|
| 694 |
}
|
| 695 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 696 |
/**
|
| 697 |
* Processes the incoming webhook.
|
| 698 |
*
|
|
@@ -744,6 +780,11 @@ class WC_Stripe_Webhook_Handler extends WC_Stripe_Payment_Gateway {
|
|
| 744 |
case 'payment_intent.payment_failed':
|
| 745 |
case 'payment_intent.amount_capturable_updated':
|
| 746 |
$this->process_payment_intent_success( $notification );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 747 |
|
| 748 |
}
|
| 749 |
}
|
| 81 |
*
|
| 82 |
* @since 4.0.0
|
| 83 |
* @version 4.0.0
|
|
|
|
| 84 |
* @param string $request_headers The request headers from Stripe.
|
| 85 |
* @param string $request_body The request body from Stripe.
|
| 86 |
* @return bool
|
| 692 |
$this->unlock_order_payment( $order );
|
| 693 |
}
|
| 694 |
|
| 695 |
+
public function process_setup_intent( $notification ) {
|
| 696 |
+
$intent = $notification->data->object;
|
| 697 |
+
$order = WC_Stripe_Helper::get_order_by_setup_intent_id( $intent->id );
|
| 698 |
+
|
| 699 |
+
if ( ! $order ) {
|
| 700 |
+
WC_Stripe_Logger::log( 'Could not find order via setup intent ID: ' . $intent->id );
|
| 701 |
+
return;
|
| 702 |
+
}
|
| 703 |
+
|
| 704 |
+
if ( 'pending' !== $order->get_status() && 'failed' !== $order->get_status() ) {
|
| 705 |
+
return;
|
| 706 |
+
}
|
| 707 |
+
|
| 708 |
+
if ( $this->lock_order_payment( $order, $intent ) ) {
|
| 709 |
+
return;
|
| 710 |
+
}
|
| 711 |
+
|
| 712 |
+
$order_id = WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $order->id : $order->get_id();
|
| 713 |
+
if ( 'setup_intent.succeeded' === $notification->type ) {
|
| 714 |
+
WC_Stripe_Logger::log( "Stripe SetupIntent $intent->id succeeded for order $order_id" );
|
| 715 |
+
if ( WC_Stripe_Helper::is_pre_orders_exists() && WC_Pre_Orders_Order::order_contains_pre_order( $order ) ) {
|
| 716 |
+
WC_Pre_Orders_Order::mark_order_as_pre_ordered( $order );
|
| 717 |
+
} else {
|
| 718 |
+
$order->payment_complete();
|
| 719 |
+
}
|
| 720 |
+
} else {
|
| 721 |
+
$error_message = $intent->last_setup_error ? $intent->last_setup_error->message : "";
|
| 722 |
+
|
| 723 |
+
/* translators: 1) The error message that was received from Stripe. */
|
| 724 |
+
$order->update_status( 'failed', sprintf( __( 'Stripe SCA authentication failed. Reason: %s', 'woocommerce-gateway-stripe' ), $error_message ) );
|
| 725 |
+
|
| 726 |
+
$this->send_failed_order_email( $order_id );
|
| 727 |
+
}
|
| 728 |
+
|
| 729 |
+
$this->unlock_order_payment( $order );
|
| 730 |
+
}
|
| 731 |
+
|
| 732 |
/**
|
| 733 |
* Processes the incoming webhook.
|
| 734 |
*
|
| 780 |
case 'payment_intent.payment_failed':
|
| 781 |
case 'payment_intent.amount_capturable_updated':
|
| 782 |
$this->process_payment_intent_success( $notification );
|
| 783 |
+
break;
|
| 784 |
+
|
| 785 |
+
case 'setup_intent.succeeded':
|
| 786 |
+
case 'setup_intent.setup_failed':
|
| 787 |
+
$this->process_setup_intent( $notification );
|
| 788 |
|
| 789 |
}
|
| 790 |
}
|
|
@@ -0,0 +1,132 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
/**
|
| 3 |
+
* Admin email about payment retry failed due to authentication
|
| 4 |
+
*
|
| 5 |
+
* Email sent to admins when an attempt to automatically process a subscription renewal payment has failed
|
| 6 |
+
* with the `authentication_needed` error, and a retry rule has been applied to retry the payment in the future.
|
| 7 |
+
*
|
| 8 |
+
* @version 4.3.0
|
| 9 |
+
* @package WooCommerce_Stripe/Classes/WC_Stripe_Email_Failed_Authentication_Retry
|
| 10 |
+
* @extends WC_Email_Failed_Order
|
| 11 |
+
*/
|
| 12 |
+
|
| 13 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
| 14 |
+
exit;
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
/**
|
| 18 |
+
* An email sent to the admin when payment fails to go through due to authentication_required error.
|
| 19 |
+
*
|
| 20 |
+
* @since 4.3.0
|
| 21 |
+
*/
|
| 22 |
+
class WC_Stripe_Email_Failed_Authentication_Retry extends WC_Email_Failed_Order {
|
| 23 |
+
|
| 24 |
+
/**
|
| 25 |
+
* Constructor
|
| 26 |
+
*/
|
| 27 |
+
public function __construct() {
|
| 28 |
+
$this->id = 'failed_authentication_requested';
|
| 29 |
+
$this->title = __( 'Payment Authentication Requested Email', 'woocommerce-gateway-stripe' );
|
| 30 |
+
$this->description = __( 'Payment authentication requested emails are sent to chosen recipient(s) when an attempt to automatically process a subscription renewal payment fails because the transaction requires an SCA verification, the customer is requested to authenticate the payment, and a retry rule has been applied to notify the customer again within a certain time period.', 'woocommerce-gateway-stripe' );
|
| 31 |
+
|
| 32 |
+
$this->heading = __( 'Automatic renewal payment failed due to authentication required', 'woocommerce-gateway-stripe' );
|
| 33 |
+
$this->subject = __( '[{site_title}] Automatic payment failed for {order_number}. Customer asked to authenticate payment and will be notified again {retry_time}', 'woocommerce-gateway-stripe' );
|
| 34 |
+
|
| 35 |
+
$this->template_html = 'emails/failed-renewal-authentication-requested.php';
|
| 36 |
+
$this->template_plain = 'emails/plain/failed-renewal-authentication-requested.php';
|
| 37 |
+
$this->template_base = plugin_dir_path( WC_STRIPE_MAIN_FILE ) . 'templates/';
|
| 38 |
+
|
| 39 |
+
$this->recipient = $this->get_option( 'recipient', get_option( 'admin_email' ) );
|
| 40 |
+
|
| 41 |
+
// We want all the parent's methods, with none of its properties, so call its parent's constructor, rather than my parent constructor.
|
| 42 |
+
WC_Email::__construct();
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
/**
|
| 46 |
+
* Get the default e-mail subject.
|
| 47 |
+
*
|
| 48 |
+
* @return string
|
| 49 |
+
*/
|
| 50 |
+
public function get_default_subject() {
|
| 51 |
+
return $this->subject;
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
/**
|
| 55 |
+
* Get the default e-mail heading.
|
| 56 |
+
*
|
| 57 |
+
* @return string
|
| 58 |
+
*/
|
| 59 |
+
public function get_default_heading() {
|
| 60 |
+
return $this->heading;
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
/**
|
| 64 |
+
* Trigger.
|
| 65 |
+
*
|
| 66 |
+
* @param int $order_id The order ID.
|
| 67 |
+
* @param WC_Order|null $order Order object.
|
| 68 |
+
*/
|
| 69 |
+
public function trigger( $order_id, $order = null ) {
|
| 70 |
+
$this->object = $order;
|
| 71 |
+
|
| 72 |
+
$this->find['retry-time'] = '{retry_time}';
|
| 73 |
+
if ( class_exists( 'WCS_Retry_Manager' ) && function_exists( 'wcs_get_human_time_diff' ) ) {
|
| 74 |
+
$this->retry = WCS_Retry_Manager::store()->get_last_retry_for_order( wcs_get_objects_property( $order, 'id' ) );
|
| 75 |
+
$this->replace['retry-time'] = wcs_get_human_time_diff( $this->retry->get_time() );
|
| 76 |
+
} else {
|
| 77 |
+
WC_Stripe_Logger::log( 'WCS_Retry_Manager class or does not exist. Not able to send admnin email about customer notification for authentication required for renewal payment.' );
|
| 78 |
+
return;
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
$this->find['order-number'] = '{order_number}';
|
| 82 |
+
$this->replace['order-number'] = $this->object->get_order_number();
|
| 83 |
+
|
| 84 |
+
if ( ! $this->is_enabled() || ! $this->get_recipient() ) {
|
| 85 |
+
return;
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
$this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );
|
| 89 |
+
}
|
| 90 |
+
|
| 91 |
+
/**
|
| 92 |
+
* Get content html.
|
| 93 |
+
*
|
| 94 |
+
* @return string
|
| 95 |
+
*/
|
| 96 |
+
public function get_content_html() {
|
| 97 |
+
return wc_get_template_html(
|
| 98 |
+
$this->template_html,
|
| 99 |
+
array(
|
| 100 |
+
'order' => $this->object,
|
| 101 |
+
'retry' => $this->retry,
|
| 102 |
+
'email_heading' => $this->get_heading(),
|
| 103 |
+
'sent_to_admin' => true,
|
| 104 |
+
'plain_text' => false,
|
| 105 |
+
'email' => $this,
|
| 106 |
+
),
|
| 107 |
+
'',
|
| 108 |
+
$this->template_base
|
| 109 |
+
);
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
/**
|
| 113 |
+
* Get content plain.
|
| 114 |
+
*
|
| 115 |
+
* @return string
|
| 116 |
+
*/
|
| 117 |
+
public function get_content_plain() {
|
| 118 |
+
return wc_get_template_html(
|
| 119 |
+
$this->template_plain,
|
| 120 |
+
array(
|
| 121 |
+
'order' => $this->object,
|
| 122 |
+
'retry' => $this->retry,
|
| 123 |
+
'email_heading' => $this->get_heading(),
|
| 124 |
+
'sent_to_admin' => true,
|
| 125 |
+
'plain_text' => true,
|
| 126 |
+
'email' => $this,
|
| 127 |
+
),
|
| 128 |
+
'',
|
| 129 |
+
$this->template_base
|
| 130 |
+
);
|
| 131 |
+
}
|
| 132 |
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
| 3 |
+
exit; // Exit if accessed directly.
|
| 4 |
+
}
|
| 5 |
+
|
| 6 |
+
/**
|
| 7 |
+
* Base for Failed Renewal/Pre-Order Authentication Notifications.
|
| 8 |
+
*
|
| 9 |
+
* @extends WC_Email
|
| 10 |
+
*/
|
| 11 |
+
abstract class WC_Stripe_Email_Failed_Authentication extends WC_Email {
|
| 12 |
+
/**
|
| 13 |
+
* An instance of the email, which would normally be sent after a failed payment.
|
| 14 |
+
*
|
| 15 |
+
* @var WC_Email
|
| 16 |
+
*/
|
| 17 |
+
public $original_email;
|
| 18 |
+
|
| 19 |
+
/**
|
| 20 |
+
* Generates the HTML for the email while keeping the `template_base` in mind.
|
| 21 |
+
*
|
| 22 |
+
* @return string
|
| 23 |
+
*/
|
| 24 |
+
public function get_content_html() {
|
| 25 |
+
ob_start();
|
| 26 |
+
wc_get_template(
|
| 27 |
+
$this->template_html,
|
| 28 |
+
array(
|
| 29 |
+
'order' => $this->object,
|
| 30 |
+
'email_heading' => $this->get_heading(),
|
| 31 |
+
'sent_to_admin' => false,
|
| 32 |
+
'plain_text' => false,
|
| 33 |
+
'authorization_url' => $this->get_authorization_url( $this->object ),
|
| 34 |
+
'email' => $this,
|
| 35 |
+
),
|
| 36 |
+
'',
|
| 37 |
+
$this->template_base
|
| 38 |
+
);
|
| 39 |
+
return ob_get_clean();
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
/**
|
| 43 |
+
* Generates the plain text for the email while keeping the `template_base` in mind.
|
| 44 |
+
*
|
| 45 |
+
* @return string
|
| 46 |
+
*/
|
| 47 |
+
public function get_content_plain() {
|
| 48 |
+
ob_start();
|
| 49 |
+
wc_get_template(
|
| 50 |
+
$this->template_plain,
|
| 51 |
+
array(
|
| 52 |
+
'order' => $this->object,
|
| 53 |
+
'email_heading' => $this->get_heading(),
|
| 54 |
+
'sent_to_admin' => false,
|
| 55 |
+
'plain_text' => true,
|
| 56 |
+
'authorization_url' => $this->get_authorization_url( $this->object ),
|
| 57 |
+
'email' => $this,
|
| 58 |
+
),
|
| 59 |
+
'',
|
| 60 |
+
$this->template_base
|
| 61 |
+
);
|
| 62 |
+
return ob_get_clean();
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
/**
|
| 66 |
+
* Generates the URL, which will be used to authenticate the payment.
|
| 67 |
+
*
|
| 68 |
+
* @param WC_Order $order The order whose payment needs authentication.
|
| 69 |
+
* @return string
|
| 70 |
+
*/
|
| 71 |
+
public function get_authorization_url( $order ) {
|
| 72 |
+
return add_query_arg( 'wc-stripe-confirmation', 1, $order->get_checkout_payment_url( false ) );
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
/**
|
| 76 |
+
* Uses specific fields from `WC_Email_Customer_Invoice` for this email.
|
| 77 |
+
*/
|
| 78 |
+
public function init_form_fields() {
|
| 79 |
+
parent::init_form_fields();
|
| 80 |
+
$base_fields = $this->form_fields;
|
| 81 |
+
|
| 82 |
+
$this->form_fields = array(
|
| 83 |
+
'enabled' => array(
|
| 84 |
+
'title' => _x( 'Enable/Disable', 'an email notification', 'woocommerce-gateway-stripe' ),
|
| 85 |
+
'type' => 'checkbox',
|
| 86 |
+
'label' => __( 'Enable this email notification', 'woocommerce-gateway-stripe' ),
|
| 87 |
+
'default' => 'yes',
|
| 88 |
+
),
|
| 89 |
+
|
| 90 |
+
'subject' => $base_fields['subject'],
|
| 91 |
+
'heading' => $base_fields['heading'],
|
| 92 |
+
'email_type' => $base_fields['email_type'],
|
| 93 |
+
);
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
/**
|
| 97 |
+
* Triggers the email.
|
| 98 |
+
*
|
| 99 |
+
* @param WC_Order $order The renewal order whose payment failed.
|
| 100 |
+
*/
|
| 101 |
+
public function trigger( $order ) {
|
| 102 |
+
if ( ! $this->is_enabled() ) {
|
| 103 |
+
return;
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
$this->object = $order;
|
| 107 |
+
|
| 108 |
+
if ( method_exists( $order, 'get_billing_email' ) ) {
|
| 109 |
+
$this->recipient = $order->get_billing_email();
|
| 110 |
+
} else {
|
| 111 |
+
$this->recipient = $order->billing_email;
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
$this->find['order_date'] = '{order_date}';
|
| 115 |
+
if ( function_exists( 'wc_format_datetime' ) ) { // WC 3.0+
|
| 116 |
+
$this->replace['order_date'] = wc_format_datetime( $order->get_date_created() );
|
| 117 |
+
} else { // WC < 3.0
|
| 118 |
+
$this->replace['order_date'] = $order->date_created->date_i18n( wc_date_format() );
|
| 119 |
+
}
|
| 120 |
+
|
| 121 |
+
$this->find['order_number'] = '{order_number}';
|
| 122 |
+
$this->replace['order_number'] = $order->get_order_number();
|
| 123 |
+
|
| 124 |
+
$this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );
|
| 125 |
+
}
|
| 126 |
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
| 3 |
+
exit; // Exit if accessed directly.
|
| 4 |
+
}
|
| 5 |
+
|
| 6 |
+
/**
|
| 7 |
+
* Failed Renewal/Pre-Order Authentication Notification
|
| 8 |
+
*
|
| 9 |
+
* @extends WC_Stripe_Email_Failed_Authentication
|
| 10 |
+
*/
|
| 11 |
+
class WC_Stripe_Email_Failed_Preorder_Authentication extends WC_Stripe_Email_Failed_Authentication {
|
| 12 |
+
/**
|
| 13 |
+
* Holds the message, which is entered by admins when sending the email.
|
| 14 |
+
*
|
| 15 |
+
* @var string
|
| 16 |
+
*/
|
| 17 |
+
protected $custom_message;
|
| 18 |
+
|
| 19 |
+
/**
|
| 20 |
+
* Constructor.
|
| 21 |
+
*
|
| 22 |
+
* @param WC_Email[] $email_classes All existing instances of WooCommerce emails.
|
| 23 |
+
*/
|
| 24 |
+
public function __construct( $email_classes = array() ) {
|
| 25 |
+
$this->id = 'failed_preorder_sca_authentication';
|
| 26 |
+
$this->title = __( 'Pre-order Payment Action Needed', 'woocommerce-gateway-stripe' );
|
| 27 |
+
$this->description = __( 'This is an order notification sent to the customer once a pre-order is complete, but additional payment steps are required.', 'woocommerce-gateway-stripe' );
|
| 28 |
+
$this->customer_email = true;
|
| 29 |
+
|
| 30 |
+
$this->template_html = 'emails/failed-preorder-authentication.php';
|
| 31 |
+
$this->template_plain = 'emails/plain/failed-preorder-authentication.php';
|
| 32 |
+
$this->template_base = plugin_dir_path( WC_STRIPE_MAIN_FILE ) . 'templates/';
|
| 33 |
+
|
| 34 |
+
// Use the "authentication required" hook to add the correct, later hook.
|
| 35 |
+
add_action( 'wc_gateway_stripe_process_payment_authentication_required', array( $this, 'trigger' ) );
|
| 36 |
+
|
| 37 |
+
if ( isset( $email_classes['WC_Pre_Orders_Email_Pre_Order_Available'] ) ) {
|
| 38 |
+
$this->original_email = $email_classes['WC_Pre_Orders_Email_Pre_Order_Available'];
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
// We want all the parent's methods, with none of its properties, so call its parent's constructor, rather than my parent constructor.
|
| 42 |
+
parent::__construct();
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
/**
|
| 46 |
+
* When autnentication is required, this adds another action to `wc_pre_orders_pre_order_completed`
|
| 47 |
+
* in order to send the authentication required email when the custom pre-orders message is available.
|
| 48 |
+
*
|
| 49 |
+
* @param WC_Order $order The order whose payment is failing.
|
| 50 |
+
*/
|
| 51 |
+
public function trigger( $order ) {
|
| 52 |
+
if ( class_exists( 'WC_Pre_Orders_Order' ) && WC_Pre_Orders_Order::order_contains_pre_order( $order->get_id() ) ) {
|
| 53 |
+
if ( isset( $this->original_email ) ) {
|
| 54 |
+
remove_action( 'wc_pre_order_status_completed_notification', array( $this->original_email, 'trigger' ), 10, 2 );
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
add_action( 'wc_pre_orders_pre_order_completed', array( $this, 'send_email' ), 10, 2 );
|
| 58 |
+
}
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
/**
|
| 62 |
+
* Triggers the email while also disconnecting the original Pre-Orders email.
|
| 63 |
+
*
|
| 64 |
+
* @param WC_Order $order The order that is being paid.
|
| 65 |
+
* @param string $message The message, which should be added to the email.
|
| 66 |
+
*/
|
| 67 |
+
public function send_email( $order, $message ) {
|
| 68 |
+
$this->custom_message = $message;
|
| 69 |
+
|
| 70 |
+
parent::trigger( $order );
|
| 71 |
+
|
| 72 |
+
// Restore the action of the original email for other bulk actions.
|
| 73 |
+
if ( isset( $this->original_email ) ) {
|
| 74 |
+
add_action( 'wc_pre_order_status_completed_notification', array( $this->original_email, 'trigger' ), 10, 2 );
|
| 75 |
+
}
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
/**
|
| 79 |
+
* Returns the default subject of the email (modifyable in settings).
|
| 80 |
+
*
|
| 81 |
+
* @return string
|
| 82 |
+
*/
|
| 83 |
+
public function get_default_subject() {
|
| 84 |
+
return __( 'Payment authorization needed for pre-order {order_number}', 'woocommerce-gateway-stripe' );
|
| 85 |
+
}
|
| 86 |
+
|
| 87 |
+
/**
|
| 88 |
+
* Returns the default heading of the email (modifyable in settings).
|
| 89 |
+
*
|
| 90 |
+
* @return string
|
| 91 |
+
*/
|
| 92 |
+
public function get_default_heading() {
|
| 93 |
+
return __( 'Payment authorization needed for pre-order {order_number}', 'woocommerce-gateway-stripe' );
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
/**
|
| 97 |
+
* Returns the custom message, entered by the admin.
|
| 98 |
+
*
|
| 99 |
+
* @return string
|
| 100 |
+
*/
|
| 101 |
+
public function get_custom_message() {
|
| 102 |
+
return $this->custom_message;
|
| 103 |
+
}
|
| 104 |
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
| 3 |
+
exit; // Exit if accessed directly.
|
| 4 |
+
}
|
| 5 |
+
|
| 6 |
+
/**
|
| 7 |
+
* Failed Renewal/Pre-Order Authentication Notification
|
| 8 |
+
*
|
| 9 |
+
* @extends WC_Email_Customer_Invoice
|
| 10 |
+
*/
|
| 11 |
+
class WC_Stripe_Email_Failed_Renewal_Authentication extends WC_Stripe_Email_Failed_Authentication {
|
| 12 |
+
/**
|
| 13 |
+
* Constructor.
|
| 14 |
+
*
|
| 15 |
+
* @param WC_Email[] $email_classes All existing instances of WooCommerce emails.
|
| 16 |
+
*/
|
| 17 |
+
public function __construct( $email_classes = array() ) {
|
| 18 |
+
$this->id = 'failed_renewal_authentication';
|
| 19 |
+
$this->title = __( 'Failed Subscription Renewal SCA Authentication', 'woocommerce-gateway-stripe' );
|
| 20 |
+
$this->description = __( 'Sent to a customer when a renewal fails because the transaction requires an SCA verification. The email contains renewal order information and payment links.', 'woocommerce-gateway-stripe' );
|
| 21 |
+
$this->customer_email = true;
|
| 22 |
+
|
| 23 |
+
$this->template_html = 'emails/failed-renewal-authentication.php';
|
| 24 |
+
$this->template_plain = 'emails/plain/failed-renewal-authentication.php';
|
| 25 |
+
$this->template_base = plugin_dir_path( WC_STRIPE_MAIN_FILE ) . 'templates/';
|
| 26 |
+
|
| 27 |
+
// Triggers the email at the correct hook.
|
| 28 |
+
add_action( 'wc_gateway_stripe_process_payment_authentication_required', array( $this, 'trigger' ) );
|
| 29 |
+
|
| 30 |
+
if ( isset( $email_classes['WCS_Email_Customer_Renewal_Invoice'] ) ) {
|
| 31 |
+
$this->original_email = $email_classes['WCS_Email_Customer_Renewal_Invoice'];
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
// We want all the parent's methods, with none of its properties, so call its parent's constructor, rather than my parent constructor.
|
| 35 |
+
parent::__construct();
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
/**
|
| 39 |
+
* Triggers the email while also disconnecting the original Subscriptions email.
|
| 40 |
+
*
|
| 41 |
+
* @param WC_Order $order The order that is being paid.
|
| 42 |
+
*/
|
| 43 |
+
public function trigger( $order ) {
|
| 44 |
+
if ( function_exists( 'wcs_order_contains_subscription' ) && ( wcs_order_contains_subscription( $order->get_id() ) || wcs_is_subscription( $order->get_id() ) || wcs_order_contains_renewal( $order->get_id() ) ) ) {
|
| 45 |
+
parent::trigger( $order );
|
| 46 |
+
|
| 47 |
+
// Prevent the renewal email from WooCommerce Subscriptions from being sent.
|
| 48 |
+
if ( isset( $this->original_email ) ) {
|
| 49 |
+
remove_action( 'woocommerce_generated_manual_renewal_order_renewal_notification', array( $this->original_email, 'trigger' ) );
|
| 50 |
+
remove_action( 'woocommerce_order_status_failed_renewal_notification', array( $this->original_email, 'trigger' ) );
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
// Prevent the retry email from WooCommerce Subscriptions from being sent.
|
| 54 |
+
add_filter( 'wcs_get_retry_rule_raw', array( $this, 'prevent_retry_notification_email' ), 100, 3 );
|
| 55 |
+
|
| 56 |
+
// Send email to store owner indicating communication is happening with the customer to request authentication.
|
| 57 |
+
add_filter( 'wcs_get_retry_rule_raw', array( $this, 'set_store_owner_custom_email' ), 100, 3 );
|
| 58 |
+
}
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
/**
|
| 62 |
+
* Returns the default subject of the email (modifyable in settings).
|
| 63 |
+
*
|
| 64 |
+
* @return string
|
| 65 |
+
*/
|
| 66 |
+
public function get_default_subject() {
|
| 67 |
+
return __( 'Payment authorization needed for renewal of {site_title} order {order_number}', 'woocommerce-gateway-stripe' );
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
/**
|
| 71 |
+
* Returns the default heading of the email (modifyable in settings).
|
| 72 |
+
*
|
| 73 |
+
* @return string
|
| 74 |
+
*/
|
| 75 |
+
public function get_default_heading() {
|
| 76 |
+
return __( 'Payment authorization needed for renewal of order {order_number}', 'woocommerce-gateway-stripe' );
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
/**
|
| 80 |
+
* Prevent all customer-facing retry notifications from being sent after this email.
|
| 81 |
+
*
|
| 82 |
+
* @param array $rule_array The raw details about the retry rule.
|
| 83 |
+
* @param int $retry_number The number of the retry.
|
| 84 |
+
* @param int $order_id The ID of the order that needs payment.
|
| 85 |
+
* @return array
|
| 86 |
+
*/
|
| 87 |
+
public function prevent_retry_notification_email( $rule_array, $retry_number, $order_id ) {
|
| 88 |
+
if ( wcs_get_objects_property( $this->object, 'id' ) === $order_id ) {
|
| 89 |
+
$rule_array['email_template_customer'] = '';
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
return $rule_array;
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
/**
|
| 96 |
+
* Send store owner a different email when the retry is related to an authentication required error.
|
| 97 |
+
*
|
| 98 |
+
* @param array $rule_array The raw details about the retry rule.
|
| 99 |
+
* @param int $retry_number The number of the retry.
|
| 100 |
+
* @param int $order_id The ID of the order that needs payment.
|
| 101 |
+
* @return array
|
| 102 |
+
*/
|
| 103 |
+
public function set_store_owner_custom_email( $rule_array, $retry_number, $order_id ) {
|
| 104 |
+
if (
|
| 105 |
+
wcs_get_objects_property( $this->object, 'id' ) === $order_id &&
|
| 106 |
+
'' !== $rule_array['email_template_admin'] // Only send our email if a retry admin email was already going to be sent.
|
| 107 |
+
) {
|
| 108 |
+
$rule_array['email_template_admin'] = 'WC_Stripe_Email_Failed_Authentication_Retry';
|
| 109 |
+
}
|
| 110 |
+
|
| 111 |
+
return $rule_array;
|
| 112 |
+
}
|
| 113 |
+
}
|
|
@@ -28,19 +28,15 @@ class WC_Stripe_Pre_Orders_Compat extends WC_Stripe_Payment_Gateway {
|
|
| 28 |
* @param object $order
|
| 29 |
*/
|
| 30 |
public function remove_order_source_before_retry( $order ) {
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
*/
|
| 41 |
-
public function remove_order_customer_before_retry( $order ) {
|
| 42 |
-
$order_id = WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $order->id : $order->get_id();
|
| 43 |
-
delete_post_meta( $order_id, '_stripe_customer_id' );
|
| 44 |
}
|
| 45 |
|
| 46 |
/**
|
|
@@ -61,19 +57,29 @@ class WC_Stripe_Pre_Orders_Compat extends WC_Stripe_Payment_Gateway {
|
|
| 61 |
throw new WC_Stripe_Exception( __( 'Unable to store payment details. Please try again.', 'woocommerce-gateway-stripe' ) );
|
| 62 |
}
|
| 63 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
$this->save_source_to_order( $order, $prepared_source );
|
| 65 |
|
| 66 |
-
//
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
WC()->cart->empty_cart();
|
| 68 |
|
| 69 |
// Is pre ordered!
|
| 70 |
WC_Pre_Orders_Order::mark_order_as_pre_ordered( $order );
|
| 71 |
|
| 72 |
// Return thank you page redirect
|
| 73 |
-
return
|
| 74 |
-
'result' => 'success',
|
| 75 |
-
'redirect' => $this->get_return_url( $order ),
|
| 76 |
-
);
|
| 77 |
} catch ( WC_Stripe_Exception $e ) {
|
| 78 |
wc_add_notice( $e->getLocalizedMessage(), 'error' );
|
| 79 |
WC_Stripe_Logger::log( 'Pre Orders Error: ' . $e->getMessage() );
|
|
@@ -87,37 +93,49 @@ class WC_Stripe_Pre_Orders_Compat extends WC_Stripe_Payment_Gateway {
|
|
| 87 |
|
| 88 |
/**
|
| 89 |
* Process a pre-order payment when the pre-order is released.
|
|
|
|
| 90 |
* @param WC_Order $order
|
|
|
|
|
|
|
| 91 |
* @return void
|
| 92 |
*/
|
| 93 |
-
public function process_pre_order_release_payment( $order ) {
|
| 94 |
try {
|
| 95 |
-
|
| 96 |
-
$
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
);
|
| 100 |
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
if ( ! empty( $response->error ) ) {
|
| 106 |
-
if ( 0 === sizeof( $retry_callbacks ) ) {
|
| 107 |
-
throw new Exception( $response->error->message );
|
| 108 |
-
} else {
|
| 109 |
-
$retry_callback = array_shift( $retry_callbacks );
|
| 110 |
-
call_user_func( array( $this, $retry_callback ), $order );
|
| 111 |
-
}
|
| 112 |
-
} else {
|
| 113 |
-
// Successful
|
| 114 |
-
$this->process_response( $response, $order );
|
| 115 |
-
break;
|
| 116 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 117 |
}
|
| 118 |
} catch ( Exception $e ) {
|
|
|
|
| 119 |
/* translators: error message */
|
| 120 |
-
$order_note = sprintf( __( 'Stripe Transaction Failed (%s)', 'woocommerce-gateway-stripe' ), $
|
| 121 |
|
| 122 |
// Mark order as failed if not already set,
|
| 123 |
// otherwise, make sure we add the order note so we can detect when someone fails to check out multiple times
|
| 28 |
* @param object $order
|
| 29 |
*/
|
| 30 |
public function remove_order_source_before_retry( $order ) {
|
| 31 |
+
if ( WC_Stripe_Helper::is_wc_lt( '3.0' ) ) {
|
| 32 |
+
delete_post_meta( $order->id, '_stripe_source_id' );
|
| 33 |
+
// For BW compat will remove in the future.
|
| 34 |
+
delete_post_meta( $order->id, '_stripe_card_id' );
|
| 35 |
+
} else {
|
| 36 |
+
$order->delete_meta_data( '_stripe_source_id' );
|
| 37 |
+
$order->delete_meta_data( '_stripe_card_id' );
|
| 38 |
+
$order->save();
|
| 39 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
}
|
| 41 |
|
| 42 |
/**
|
| 57 |
throw new WC_Stripe_Exception( __( 'Unable to store payment details. Please try again.', 'woocommerce-gateway-stripe' ) );
|
| 58 |
}
|
| 59 |
|
| 60 |
+
// Setup the response early to allow later modifications.
|
| 61 |
+
$response = array(
|
| 62 |
+
'result' => 'success',
|
| 63 |
+
'redirect' => $this->get_return_url( $order ),
|
| 64 |
+
);
|
| 65 |
+
|
| 66 |
$this->save_source_to_order( $order, $prepared_source );
|
| 67 |
|
| 68 |
+
// Try setting up a payment intent.
|
| 69 |
+
$intent_secret = $this->setup_intent( $order, $prepared_source );
|
| 70 |
+
if ( ! empty( $intent_secret ) ) {
|
| 71 |
+
$response['setup_intent_secret'] = $intent_secret;
|
| 72 |
+
return $response;
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
// Remove cart.
|
| 76 |
WC()->cart->empty_cart();
|
| 77 |
|
| 78 |
// Is pre ordered!
|
| 79 |
WC_Pre_Orders_Order::mark_order_as_pre_ordered( $order );
|
| 80 |
|
| 81 |
// Return thank you page redirect
|
| 82 |
+
return $response;
|
|
|
|
|
|
|
|
|
|
| 83 |
} catch ( WC_Stripe_Exception $e ) {
|
| 84 |
wc_add_notice( $e->getLocalizedMessage(), 'error' );
|
| 85 |
WC_Stripe_Logger::log( 'Pre Orders Error: ' . $e->getMessage() );
|
| 93 |
|
| 94 |
/**
|
| 95 |
* Process a pre-order payment when the pre-order is released.
|
| 96 |
+
*
|
| 97 |
* @param WC_Order $order
|
| 98 |
+
* @param bool $retry
|
| 99 |
+
*
|
| 100 |
* @return void
|
| 101 |
*/
|
| 102 |
+
public function process_pre_order_release_payment( $order, $retry = true ) {
|
| 103 |
try {
|
| 104 |
+
$source = $this->prepare_order_source( $order );
|
| 105 |
+
$response = $this->create_and_confirm_intent_for_off_session( $order, $source );
|
| 106 |
+
|
| 107 |
+
$is_authentication_required = $this->is_authentication_required_for_payment( $response );
|
|
|
|
| 108 |
|
| 109 |
+
if ( ! empty( $response->error ) && ! $is_authentication_required ) {
|
| 110 |
+
if ( ! $retry ) {
|
| 111 |
+
throw new Exception( $response->error->message );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 112 |
}
|
| 113 |
+
$this->remove_order_source_before_retry( $order );
|
| 114 |
+
$this->process_pre_order_release_payment( $order, false );
|
| 115 |
+
} else if ( $is_authentication_required ) {
|
| 116 |
+
$charge = end( $response->error->payment_intent->charges->data );
|
| 117 |
+
$id = $charge->id;
|
| 118 |
+
$order_id = WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $order->id : $order->get_id();
|
| 119 |
+
|
| 120 |
+
WC_Stripe_Helper::is_wc_lt( '3.0' ) ? update_post_meta( $order_id, '_transaction_id', $id ) : $order->set_transaction_id( $id );
|
| 121 |
+
$order->update_status( 'failed', sprintf( __( 'Stripe charge awaiting authentication by user: %s.', 'woocommerce-gateway-stripe' ), $id ) );
|
| 122 |
+
if ( is_callable( array( $order, 'save' ) ) ) {
|
| 123 |
+
$order->save();
|
| 124 |
+
}
|
| 125 |
+
|
| 126 |
+
WC_Emails::instance();
|
| 127 |
+
|
| 128 |
+
do_action( 'wc_gateway_stripe_process_payment_authentication_required', $order );
|
| 129 |
+
|
| 130 |
+
throw new WC_Stripe_Exception( print_r( $response, true ), $response->error->message );
|
| 131 |
+
} else {
|
| 132 |
+
// Successful
|
| 133 |
+
$this->process_response( end( $response->charges->data ), $order );
|
| 134 |
}
|
| 135 |
} catch ( Exception $e ) {
|
| 136 |
+
$error_message = is_callable( array( $e, 'getLocalizedMessage' ) ) ? $e->getLocalizedMessage() : $e->getMessage();
|
| 137 |
/* translators: error message */
|
| 138 |
+
$order_note = sprintf( __( 'Stripe Transaction Failed (%s)', 'woocommerce-gateway-stripe' ), $error_message );
|
| 139 |
|
| 140 |
// Mark order as failed if not already set,
|
| 141 |
// otherwise, make sure we add the order note so we can detect when someone fails to check out multiple times
|
|
@@ -30,6 +30,15 @@ class WC_Stripe_Subs_Compat extends WC_Gateway_Stripe {
|
|
| 30 |
add_filter( 'woocommerce_subscription_payment_meta', array( $this, 'add_subscription_payment_meta' ), 10, 2 );
|
| 31 |
add_filter( 'woocommerce_subscription_validate_payment_meta', array( $this, 'validate_subscription_payment_meta' ), 10, 2 );
|
| 32 |
add_filter( 'wc_stripe_display_save_payment_method_checkbox', array( $this, 'maybe_hide_save_checkbox' ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
}
|
| 34 |
}
|
| 35 |
|
|
@@ -124,19 +133,9 @@ class WC_Stripe_Subs_Compat extends WC_Gateway_Stripe {
|
|
| 124 |
try {
|
| 125 |
$subscription = wc_get_order( $order_id );
|
| 126 |
$prepared_source = $this->prepare_source( get_current_user_id(), true );
|
| 127 |
-
$source_object = $prepared_source->source_object;
|
| 128 |
-
|
| 129 |
-
// Check if we don't allow prepaid credit cards.
|
| 130 |
-
if ( ! apply_filters( 'wc_stripe_allow_prepaid_card', true ) && $this->is_prepaid_card( $source_object ) ) {
|
| 131 |
-
$localized_message = __( 'Sorry, we\'re not accepting prepaid cards at this time. Your credit card has not been charge. Please try with alternative payment method.', 'woocommerce-gateway-stripe' );
|
| 132 |
-
throw new WC_Stripe_Exception( print_r( $source_object, true ), $localized_message );
|
| 133 |
-
}
|
| 134 |
-
|
| 135 |
-
if ( empty( $prepared_source->source ) ) {
|
| 136 |
-
$localized_message = __( 'Payment processing failed. Please retry.', 'woocommerce-gateway-stripe' );
|
| 137 |
-
throw new WC_Stripe_Exception( print_r( $prepared_source, true ), $localized_message );
|
| 138 |
-
}
|
| 139 |
|
|
|
|
|
|
|
| 140 |
$this->save_source_to_order( $subscription, $prepared_source );
|
| 141 |
|
| 142 |
do_action( 'wc_stripe_change_subs_payment_method_success', $prepared_source->source, $prepared_source );
|
|
@@ -169,6 +168,28 @@ class WC_Stripe_Subs_Compat extends WC_Gateway_Stripe {
|
|
| 169 |
}
|
| 170 |
}
|
| 171 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 172 |
/**
|
| 173 |
* Scheduled_subscription_payment function.
|
| 174 |
*
|
|
@@ -199,6 +220,11 @@ class WC_Stripe_Subs_Compat extends WC_Gateway_Stripe {
|
|
| 199 |
|
| 200 |
$order_id = WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $renewal_order->id : $renewal_order->get_id();
|
| 201 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 202 |
// Get source from order
|
| 203 |
$prepared_source = $this->prepare_order_source( $renewal_order );
|
| 204 |
$source_object = $prepared_source->source_object;
|
|
@@ -221,9 +247,13 @@ class WC_Stripe_Subs_Compat extends WC_Gateway_Stripe {
|
|
| 221 |
$prepared_source->source = '';
|
| 222 |
}
|
| 223 |
|
| 224 |
-
$response = $this->
|
|
|
|
|
|
|
| 225 |
|
| 226 |
-
if
|
|
|
|
|
|
|
| 227 |
// We want to retry.
|
| 228 |
if ( $this->is_retryable_error( $response->error ) ) {
|
| 229 |
if ( $retry ) {
|
|
@@ -257,10 +287,29 @@ class WC_Stripe_Subs_Compat extends WC_Gateway_Stripe {
|
|
| 257 |
throw new WC_Stripe_Exception( print_r( $response, true ), $localized_message );
|
| 258 |
}
|
| 259 |
|
| 260 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 261 |
|
|
|
|
|
|
|
|
|
|
| 262 |
|
| 263 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 264 |
} catch ( WC_Stripe_Exception $e ) {
|
| 265 |
WC_Stripe_Logger::log( 'Error: ' . $e->getMessage() );
|
| 266 |
|
|
@@ -271,57 +320,6 @@ class WC_Stripe_Subs_Compat extends WC_Gateway_Stripe {
|
|
| 271 |
}
|
| 272 |
}
|
| 273 |
|
| 274 |
-
/**
|
| 275 |
-
* Create and confirm a new PaymentIntent.
|
| 276 |
-
*
|
| 277 |
-
* @param float $amount The amount to charge.
|
| 278 |
-
* @param WC_Order $order The order that is being paid for.
|
| 279 |
-
* @param object $prepared_source The source that is used for the payment.
|
| 280 |
-
* @return object An intent or an error.
|
| 281 |
-
*/
|
| 282 |
-
public function create_and_confirm_intent_for_renewal( $amount, $order, $prepared_source ) {
|
| 283 |
-
// The request for a charge contains metadata for the intent.
|
| 284 |
-
$full_request = $this->generate_payment_request( $order, $prepared_source );
|
| 285 |
-
|
| 286 |
-
$request = array(
|
| 287 |
-
'amount' => WC_Stripe_Helper::get_stripe_amount( $amount, $full_request['currency'] ),
|
| 288 |
-
'currency' => $full_request['currency'],
|
| 289 |
-
'description' => $full_request['description'],
|
| 290 |
-
'metadata' => $full_request['metadata'],
|
| 291 |
-
'payment_method_types' => array(
|
| 292 |
-
'card',
|
| 293 |
-
),
|
| 294 |
-
'off_session' => 'true',
|
| 295 |
-
'confirm' => 'true',
|
| 296 |
-
'confirmation_method' => 'automatic',
|
| 297 |
-
);
|
| 298 |
-
|
| 299 |
-
if ( isset( $full_request['statement_descriptor'] ) ) {
|
| 300 |
-
$request['statement_descriptor'] = $full_request['statement_descriptor'];
|
| 301 |
-
}
|
| 302 |
-
|
| 303 |
-
if ( isset( $full_request['customer'] ) ) {
|
| 304 |
-
$request['customer'] = $full_request['customer'];
|
| 305 |
-
}
|
| 306 |
-
|
| 307 |
-
if ( isset( $full_request['source'] ) ) {
|
| 308 |
-
$request['source'] = $full_request['source'];
|
| 309 |
-
}
|
| 310 |
-
|
| 311 |
-
$intent = WC_Stripe_API::request( $request, 'payment_intents' );
|
| 312 |
-
if ( ! empty( $intent->error ) ) {
|
| 313 |
-
return $intent;
|
| 314 |
-
}
|
| 315 |
-
|
| 316 |
-
$order_id = WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $order->id : $order->get_id();
|
| 317 |
-
WC_Stripe_Logger::log( "Stripe PaymentIntent $intent->id initiated for order $order_id" );
|
| 318 |
-
|
| 319 |
-
// Save the intent ID to the order.
|
| 320 |
-
$this->save_intent_to_order( $order, $intent );
|
| 321 |
-
|
| 322 |
-
return $intent;
|
| 323 |
-
}
|
| 324 |
-
|
| 325 |
/**
|
| 326 |
* Updates other subscription sources.
|
| 327 |
*
|
|
@@ -551,4 +549,62 @@ class WC_Stripe_Subs_Compat extends WC_Gateway_Stripe {
|
|
| 551 |
|
| 552 |
return $payment_method_to_display;
|
| 553 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 554 |
}
|
| 30 |
add_filter( 'woocommerce_subscription_payment_meta', array( $this, 'add_subscription_payment_meta' ), 10, 2 );
|
| 31 |
add_filter( 'woocommerce_subscription_validate_payment_meta', array( $this, 'validate_subscription_payment_meta' ), 10, 2 );
|
| 32 |
add_filter( 'wc_stripe_display_save_payment_method_checkbox', array( $this, 'maybe_hide_save_checkbox' ) );
|
| 33 |
+
|
| 34 |
+
/*
|
| 35 |
+
* WC subscriptions hooks into the "template_redirect" hook with priority 100.
|
| 36 |
+
* If the screen is "Pay for order" and the order is a subscription renewal, it redirects to the plain checkout.
|
| 37 |
+
* See: https://github.com/woocommerce/woocommerce-subscriptions/blob/99a75687e109b64cbc07af6e5518458a6305f366/includes/class-wcs-cart-renewal.php#L165
|
| 38 |
+
* If we are in the "You just need to authorize SCA" flow, we don't want that redirection to happen.
|
| 39 |
+
*/
|
| 40 |
+
add_action( 'template_redirect', array( $this, 'remove_order_pay_var' ), 99 );
|
| 41 |
+
add_action( 'template_redirect', array( $this, 'restore_order_pay_var' ), 101 );
|
| 42 |
}
|
| 43 |
}
|
| 44 |
|
| 133 |
try {
|
| 134 |
$subscription = wc_get_order( $order_id );
|
| 135 |
$prepared_source = $this->prepare_source( get_current_user_id(), true );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 136 |
|
| 137 |
+
$this->maybe_disallow_prepaid_card( $prepared_source );
|
| 138 |
+
$this->check_source( $prepared_source );
|
| 139 |
$this->save_source_to_order( $subscription, $prepared_source );
|
| 140 |
|
| 141 |
do_action( 'wc_stripe_change_subs_payment_method_success', $prepared_source->source, $prepared_source );
|
| 168 |
}
|
| 169 |
}
|
| 170 |
|
| 171 |
+
/**
|
| 172 |
+
* Overloads WC_Stripe_Payment_Gateway::generate_create_intent_request() in order to
|
| 173 |
+
* include additional flags, used when setting payment intents up for off-session usage.
|
| 174 |
+
*
|
| 175 |
+
* @param WC_Order $order The order that is being paid for.
|
| 176 |
+
* @param object $prepared_source The source that is used for the payment.
|
| 177 |
+
* @return array The arguments for the request.
|
| 178 |
+
*/
|
| 179 |
+
public function generate_create_intent_request( $order, $prepared_source ) {
|
| 180 |
+
$request = parent::generate_create_intent_request( $order, $prepared_source );
|
| 181 |
+
|
| 182 |
+
// Non-subscription orders do not need any additional parameters.
|
| 183 |
+
if ( ! $this->has_subscription( $order ) ) {
|
| 184 |
+
return $request;
|
| 185 |
+
}
|
| 186 |
+
|
| 187 |
+
// Let Stripe know that the payment should be prepared for future usage.
|
| 188 |
+
$request['setup_future_usage'] = 'off_session';
|
| 189 |
+
|
| 190 |
+
return $request;
|
| 191 |
+
}
|
| 192 |
+
|
| 193 |
/**
|
| 194 |
* Scheduled_subscription_payment function.
|
| 195 |
*
|
| 220 |
|
| 221 |
$order_id = WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $renewal_order->id : $renewal_order->get_id();
|
| 222 |
|
| 223 |
+
// Check for an existing intent, which is associated with the order.
|
| 224 |
+
if ( $this->has_authentication_already_failed( $renewal_order ) ) {
|
| 225 |
+
return;
|
| 226 |
+
}
|
| 227 |
+
|
| 228 |
// Get source from order
|
| 229 |
$prepared_source = $this->prepare_order_source( $renewal_order );
|
| 230 |
$source_object = $prepared_source->source_object;
|
| 247 |
$prepared_source->source = '';
|
| 248 |
}
|
| 249 |
|
| 250 |
+
$response = $this->create_and_confirm_intent_for_off_session( $renewal_order, $prepared_source, $amount );
|
| 251 |
+
|
| 252 |
+
$is_authentication_required = $this->is_authentication_required_for_payment( $response );
|
| 253 |
|
| 254 |
+
// It's only a failed payment if it's an error and it's not of the type 'authentication_required'.
|
| 255 |
+
// If it's 'authentication_required', then we should email the user and ask them to authenticate.
|
| 256 |
+
if ( ! empty( $response->error ) && ! $is_authentication_required ) {
|
| 257 |
// We want to retry.
|
| 258 |
if ( $this->is_retryable_error( $response->error ) ) {
|
| 259 |
if ( $retry ) {
|
| 287 |
throw new WC_Stripe_Exception( print_r( $response, true ), $localized_message );
|
| 288 |
}
|
| 289 |
|
| 290 |
+
// Either the charge was successfully captured, or it requires further authentication.
|
| 291 |
+
|
| 292 |
+
if ( $is_authentication_required ) {
|
| 293 |
+
do_action( 'wc_gateway_stripe_process_payment_authentication_required', $renewal_order, $response );
|
| 294 |
+
|
| 295 |
+
$error_message = __( 'This transaction requires authentication.', 'woocommerce-gateway-stripe' );
|
| 296 |
+
$renewal_order->add_order_note( $error_message );
|
| 297 |
|
| 298 |
+
$charge = end( $response->error->payment_intent->charges->data );
|
| 299 |
+
$id = $charge->id;
|
| 300 |
+
$order_id = WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $renewal_order->id : $renewal_order->get_id();
|
| 301 |
|
| 302 |
+
WC_Stripe_Helper::is_wc_lt( '3.0' ) ? update_post_meta( $order_id, '_transaction_id', $id ) : $renewal_order->set_transaction_id( $id );
|
| 303 |
+
$renewal_order->update_status( 'failed', sprintf( __( 'Stripe charge awaiting authentication by user: %s.', 'woocommerce-gateway-stripe' ), $id ) );
|
| 304 |
+
if ( is_callable( array( $renewal_order, 'save' ) ) ) {
|
| 305 |
+
$renewal_order->save();
|
| 306 |
+
}
|
| 307 |
+
} else {
|
| 308 |
+
// The charge was successfully captured
|
| 309 |
+
do_action( 'wc_gateway_stripe_process_payment', $response, $renewal_order );
|
| 310 |
+
|
| 311 |
+
$this->process_response( end( $response->charges->data ), $renewal_order );
|
| 312 |
+
}
|
| 313 |
} catch ( WC_Stripe_Exception $e ) {
|
| 314 |
WC_Stripe_Logger::log( 'Error: ' . $e->getMessage() );
|
| 315 |
|
| 320 |
}
|
| 321 |
}
|
| 322 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 323 |
/**
|
| 324 |
* Updates other subscription sources.
|
| 325 |
*
|
| 549 |
|
| 550 |
return $payment_method_to_display;
|
| 551 |
}
|
| 552 |
+
|
| 553 |
+
/**
|
| 554 |
+
* If this is the "Pass the SCA challenge" flow, remove a variable that is checked by WC Subscriptions
|
| 555 |
+
* so WC Subscriptions doesn't redirect to the checkout
|
| 556 |
+
*/
|
| 557 |
+
public function remove_order_pay_var() {
|
| 558 |
+
global $wp;
|
| 559 |
+
if ( isset( $_GET['wc-stripe-confirmation'] ) ) {
|
| 560 |
+
$this->order_pay_var = $wp->query_vars['order-pay'];
|
| 561 |
+
$wp->query_vars['order-pay'] = null;
|
| 562 |
+
}
|
| 563 |
+
}
|
| 564 |
+
|
| 565 |
+
/**
|
| 566 |
+
* Restore the variable that was removed in remove_order_pay_var()
|
| 567 |
+
*/
|
| 568 |
+
public function restore_order_pay_var() {
|
| 569 |
+
global $wp;
|
| 570 |
+
if ( isset( $this->order_pay_var ) ) {
|
| 571 |
+
$wp->query_vars['order-pay'] = $this->order_pay_var;
|
| 572 |
+
}
|
| 573 |
+
}
|
| 574 |
+
|
| 575 |
+
/**
|
| 576 |
+
* Checks if a renewal already failed because a manual authentication is required.
|
| 577 |
+
*
|
| 578 |
+
* @param WC_Order $renewal_order The renewal order.
|
| 579 |
+
* @return boolean
|
| 580 |
+
*/
|
| 581 |
+
public function has_authentication_already_failed( $renewal_order ) {
|
| 582 |
+
$existing_intent = $this->get_intent_from_order( $renewal_order );
|
| 583 |
+
|
| 584 |
+
if (
|
| 585 |
+
! $existing_intent
|
| 586 |
+
|| 'requires_payment_method' !== $existing_intent->status
|
| 587 |
+
|| empty( $existing_intent->last_payment_error )
|
| 588 |
+
|| 'authentication_required' !== $existing_intent->last_payment_error->code
|
| 589 |
+
) {
|
| 590 |
+
return false;
|
| 591 |
+
}
|
| 592 |
+
|
| 593 |
+
// Make sure all emails are instantiated.
|
| 594 |
+
WC_Emails::instance();
|
| 595 |
+
|
| 596 |
+
/**
|
| 597 |
+
* A payment attempt failed because SCA authentication is required.
|
| 598 |
+
*
|
| 599 |
+
* @param WC_Order $renewal_order The order that is being renewed.
|
| 600 |
+
*/
|
| 601 |
+
do_action( 'wc_gateway_stripe_process_payment_authentication_required', $renewal_order );
|
| 602 |
+
|
| 603 |
+
// Fail the payment attempt (order would be currently pending because of retry rules).
|
| 604 |
+
$charge = end( $existing_intent->charges->data );
|
| 605 |
+
$charge_id = $charge->id;
|
| 606 |
+
$renewal_order->update_status( 'failed', sprintf( __( 'Stripe charge awaiting authentication by user: %s.', 'woocommerce-gateway-stripe' ), $charge_id ) );
|
| 607 |
+
|
| 608 |
+
return true;
|
| 609 |
+
}
|
| 610 |
}
|
|
@@ -2,10 +2,9 @@
|
|
| 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 |
-
"Report-Msgid-Bugs-To: "
|
| 7 |
-
"
|
| 8 |
-
"POT-Creation-Date: 2019-10-02 17:24:17+00:00\n"
|
| 9 |
"MIME-Version: 1.0\n"
|
| 10 |
"Content-Type: text/plain; charset=utf-8\n"
|
| 11 |
"Content-Transfer-Encoding: 8bit\n"
|
|
@@ -28,72 +27,71 @@ msgstr ""
|
|
| 28 |
msgid "Save payment information to my account for future purchases."
|
| 29 |
msgstr ""
|
| 30 |
|
| 31 |
-
#: includes/abstracts/abstract-wc-stripe-payment-gateway.php:
|
| 32 |
#: includes/compat/class-wc-stripe-sepa-subs-compat.php:216
|
| 33 |
-
#: includes/compat/class-wc-stripe-subs-compat.php:
|
| 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."
|
| 37 |
msgstr ""
|
| 38 |
|
| 39 |
-
#: includes/abstracts/abstract-wc-stripe-payment-gateway.php:
|
| 40 |
#. translators: 1) blog name 2) order number
|
| 41 |
msgid "%1$s - Order %2$s"
|
| 42 |
msgstr ""
|
| 43 |
|
| 44 |
-
#: includes/abstracts/abstract-wc-stripe-payment-gateway.php:
|
| 45 |
msgid "customer_name"
|
| 46 |
msgstr ""
|
| 47 |
|
| 48 |
-
#: includes/abstracts/abstract-wc-stripe-payment-gateway.php:
|
| 49 |
msgid "customer_email"
|
| 50 |
msgstr ""
|
| 51 |
|
| 52 |
-
#: includes/abstracts/abstract-wc-stripe-payment-gateway.php:
|
| 53 |
#. translators: transaction id
|
| 54 |
msgid "Stripe charge awaiting payment: %s."
|
| 55 |
msgstr ""
|
| 56 |
|
| 57 |
-
#: includes/abstracts/abstract-wc-stripe-payment-gateway.php:
|
| 58 |
#: includes/class-wc-stripe-order-handler.php:296
|
| 59 |
-
#: includes/class-wc-stripe-webhook-handler.php:
|
| 60 |
-
#: includes/class-wc-stripe-webhook-handler.php:
|
| 61 |
#. translators: transaction id
|
| 62 |
msgid "Stripe charge complete (Charge ID: %s)"
|
| 63 |
msgstr ""
|
| 64 |
|
| 65 |
-
#: includes/abstracts/abstract-wc-stripe-payment-gateway.php:
|
| 66 |
-
#: includes/class-wc-gateway-stripe.php:
|
| 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:
|
| 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:
|
| 80 |
msgid "Invalid payment method. Please input a new card number."
|
| 81 |
msgstr ""
|
| 82 |
|
| 83 |
-
#: includes/abstracts/abstract-wc-stripe-payment-gateway.php:
|
| 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:
|
| 89 |
msgid "Pre-Authorization Released"
|
| 90 |
msgstr ""
|
| 91 |
|
| 92 |
-
#: includes/abstracts/abstract-wc-stripe-payment-gateway.php:
|
| 93 |
msgid "There was a problem adding the payment method."
|
| 94 |
msgstr ""
|
| 95 |
|
| 96 |
-
#: includes/admin/class-wc-stripe-admin-notices.php:
|
| 97 |
#. translators: 1) A URL that explains Stripe Radar.
|
| 98 |
msgid ""
|
| 99 |
"WooCommerce Stripe - We see that you had the \"Require 3D secure when "
|
|
@@ -102,42 +100,42 @@ msgid ""
|
|
| 102 |
"href=\"%s\" target=\"_blank\">here</a>."
|
| 103 |
msgstr ""
|
| 104 |
|
| 105 |
-
#: includes/admin/class-wc-stripe-admin-notices.php:
|
| 106 |
#. translators: 1) int version 2) int version
|
| 107 |
msgid ""
|
| 108 |
"WooCommerce Stripe - We recently made changes to Stripe that may impact the "
|
| 109 |
"appearance of your checkout. If your checkout has changed unexpectedly, "
|
| 110 |
"please follow these <a "
|
| 111 |
-
"href=\"https://docs.woocommerce.com/document/stripe/#
|
| 112 |
"target=\"_blank\">instructions</a> to fix."
|
| 113 |
msgstr ""
|
| 114 |
|
| 115 |
-
#: includes/admin/class-wc-stripe-admin-notices.php:
|
| 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:
|
| 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:
|
| 130 |
msgid "WooCommerce Stripe - cURL is not installed."
|
| 131 |
msgstr ""
|
| 132 |
|
| 133 |
-
#: includes/admin/class-wc-stripe-admin-notices.php:
|
| 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:
|
| 141 |
#. translators: 1) link
|
| 142 |
msgid ""
|
| 143 |
"Stripe is in test mode however your test keys may not be valid. Test keys "
|
|
@@ -145,7 +143,7 @@ msgid ""
|
|
| 145 |
"<a href=\"%s\">set your Stripe account keys</a>."
|
| 146 |
msgstr ""
|
| 147 |
|
| 148 |
-
#: includes/admin/class-wc-stripe-admin-notices.php:
|
| 149 |
#. translators: 1) link
|
| 150 |
msgid ""
|
| 151 |
"Stripe is in live mode however your test keys may not be valid. Live keys "
|
|
@@ -153,7 +151,7 @@ msgid ""
|
|
| 153 |
"<a href=\"%s\">set your Stripe account keys</a>."
|
| 154 |
msgstr ""
|
| 155 |
|
| 156 |
-
#: includes/admin/class-wc-stripe-admin-notices.php:
|
| 157 |
#. translators: 1) link
|
| 158 |
msgid ""
|
| 159 |
"Stripe is enabled, but a SSL certificate is not detected. Your checkout may "
|
|
@@ -161,16 +159,22 @@ msgid ""
|
|
| 161 |
"target=\"_blank\">SSL certificate</a>"
|
| 162 |
msgstr ""
|
| 163 |
|
| 164 |
-
#: includes/admin/class-wc-stripe-admin-notices.php:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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:
|
| 170 |
msgid "Action failed. Please refresh the page and retry."
|
| 171 |
msgstr ""
|
| 172 |
|
| 173 |
-
#: includes/admin/class-wc-stripe-admin-notices.php:
|
| 174 |
msgid "Cheatin’ huh?"
|
| 175 |
msgstr ""
|
| 176 |
|
|
@@ -206,8 +210,8 @@ 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:
|
| 210 |
-
#: includes/compat/class-wc-stripe-subs-compat.php:
|
| 211 |
msgid "N/A"
|
| 212 |
msgstr ""
|
| 213 |
|
|
@@ -761,22 +765,14 @@ msgid ""
|
|
| 761 |
"your Stripe account keys</a>."
|
| 762 |
msgstr ""
|
| 763 |
|
| 764 |
-
#: includes/class-wc-gateway-stripe.php:
|
| 765 |
#. translators: 1) Opening anchor tag 2) closing anchor tag
|
| 766 |
msgid ""
|
| 767 |
"If your billing address has been changed for saved payment methods, be sure "
|
| 768 |
"to remove any %1$ssaved payment methods%2$s on file and re-add them."
|
| 769 |
msgstr ""
|
| 770 |
|
| 771 |
-
#: includes/class-wc-gateway-stripe.php:
|
| 772 |
-
msgid "Add Card"
|
| 773 |
-
msgstr ""
|
| 774 |
-
|
| 775 |
-
#: includes/class-wc-gateway-stripe.php:257
|
| 776 |
-
msgid "Change Payment Method"
|
| 777 |
-
msgstr ""
|
| 778 |
-
|
| 779 |
-
#: includes/class-wc-gateway-stripe.php:278
|
| 780 |
#. translators: link to Stripe testing page
|
| 781 |
msgid ""
|
| 782 |
"TEST MODE ENABLED. In test mode, you can use the card number "
|
|
@@ -785,84 +781,84 @@ msgid ""
|
|
| 785 |
"card numbers."
|
| 786 |
msgstr ""
|
| 787 |
|
| 788 |
-
#: includes/class-wc-gateway-stripe.php:
|
| 789 |
msgid "Credit or debit card"
|
| 790 |
msgstr ""
|
| 791 |
|
| 792 |
-
#: includes/class-wc-gateway-stripe.php:
|
| 793 |
msgid "Card Number"
|
| 794 |
msgstr ""
|
| 795 |
|
| 796 |
-
#: includes/class-wc-gateway-stripe.php:
|
| 797 |
msgid "Expiry Date"
|
| 798 |
msgstr ""
|
| 799 |
|
| 800 |
-
#: includes/class-wc-gateway-stripe.php:
|
| 801 |
msgid "Card Code (CVC)"
|
| 802 |
msgstr ""
|
| 803 |
|
| 804 |
-
#: includes/class-wc-gateway-stripe.php:
|
| 805 |
msgid "Please accept the terms and conditions first"
|
| 806 |
msgstr ""
|
| 807 |
|
| 808 |
-
#: includes/class-wc-gateway-stripe.php:
|
| 809 |
msgid "Please fill in required checkout fields first"
|
| 810 |
msgstr ""
|
| 811 |
|
| 812 |
-
#: includes/class-wc-gateway-stripe.php:
|
| 813 |
-
#: includes/class-wc-gateway-stripe.php:
|
| 814 |
msgid ""
|
| 815 |
"Sorry, we're not accepting prepaid cards at this time. Your credit card has "
|
| 816 |
"not been charged. Please try with alternative payment method."
|
| 817 |
msgstr ""
|
| 818 |
|
| 819 |
-
#: includes/class-wc-gateway-stripe.php:
|
| 820 |
msgid "Please enter your IBAN account name."
|
| 821 |
msgstr ""
|
| 822 |
|
| 823 |
-
#: includes/class-wc-gateway-stripe.php:
|
| 824 |
msgid "Please enter your IBAN account number."
|
| 825 |
msgstr ""
|
| 826 |
|
| 827 |
-
#: includes/class-wc-gateway-stripe.php:
|
| 828 |
msgid "We couldn't initiate the payment. Please try again."
|
| 829 |
msgstr ""
|
| 830 |
|
| 831 |
-
#: includes/class-wc-gateway-stripe.php:
|
| 832 |
msgid "Billing First Name and Last Name are required."
|
| 833 |
msgstr ""
|
| 834 |
|
| 835 |
-
#: includes/class-wc-gateway-stripe.php:
|
| 836 |
#. translators: error message
|
| 837 |
msgid "This represents the fee Stripe collects for the transaction."
|
| 838 |
msgstr ""
|
| 839 |
|
| 840 |
-
#: includes/class-wc-gateway-stripe.php:
|
| 841 |
msgid "Stripe Fee:"
|
| 842 |
msgstr ""
|
| 843 |
|
| 844 |
-
#: includes/class-wc-gateway-stripe.php:
|
| 845 |
msgid ""
|
| 846 |
"This represents the net total that will be credited to your Stripe bank "
|
| 847 |
"account. This may be in the currency that is set in your Stripe account."
|
| 848 |
msgstr ""
|
| 849 |
|
| 850 |
-
#: includes/class-wc-gateway-stripe.php:
|
| 851 |
msgid "Stripe Payout:"
|
| 852 |
msgstr ""
|
| 853 |
|
| 854 |
-
#: includes/class-wc-gateway-stripe.php:
|
| 855 |
#: includes/class-wc-stripe-order-handler.php:162
|
| 856 |
-
#: includes/class-wc-stripe-webhook-handler.php:
|
| 857 |
#: includes/compat/class-wc-stripe-sepa-subs-compat.php:263
|
| 858 |
-
#: includes/compat/class-wc-stripe-subs-compat.php:
|
| 859 |
#: includes/payment-methods/class-wc-gateway-stripe-sepa.php:373
|
| 860 |
msgid ""
|
| 861 |
"Sorry, we are unable to process your payment at this time. Please retry "
|
| 862 |
"later."
|
| 863 |
msgstr ""
|
| 864 |
|
| 865 |
-
#: includes/class-wc-gateway-stripe.php:
|
| 866 |
msgid ""
|
| 867 |
"Almost there!\n"
|
| 868 |
"\n"
|
|
@@ -870,13 +866,14 @@ msgid ""
|
|
| 870 |
"done is for you to authorize the payment with your bank."
|
| 871 |
msgstr ""
|
| 872 |
|
| 873 |
-
#: includes/class-wc-gateway-stripe.php:
|
| 874 |
-
#: includes/class-wc-stripe-webhook-handler.php:
|
|
|
|
| 875 |
#. translators: 1) The error message that was received from Stripe.
|
| 876 |
msgid "Stripe SCA authentication failed. Reason: %s"
|
| 877 |
msgstr ""
|
| 878 |
|
| 879 |
-
#: includes/class-wc-gateway-stripe.php:
|
| 880 |
msgid "Stripe SCA authentication failed."
|
| 881 |
msgstr ""
|
| 882 |
|
|
@@ -909,15 +906,17 @@ msgid ""
|
|
| 909 |
"the issue. (Logging must be enabled to see recorded logs)"
|
| 910 |
msgstr ""
|
| 911 |
|
| 912 |
-
#: includes/class-wc-stripe-customer.php:
|
| 913 |
-
|
|
|
|
| 914 |
msgstr ""
|
| 915 |
|
| 916 |
-
#: includes/class-wc-stripe-customer.php:
|
| 917 |
-
|
|
|
|
| 918 |
msgstr ""
|
| 919 |
|
| 920 |
-
#: includes/class-wc-stripe-customer.php:
|
| 921 |
msgid "Unable to add payment source."
|
| 922 |
msgstr ""
|
| 923 |
|
|
@@ -1008,7 +1007,7 @@ msgid "Payment verification error: %s"
|
|
| 1008 |
msgstr ""
|
| 1009 |
|
| 1010 |
#: includes/class-wc-stripe-order-handler.php:144
|
| 1011 |
-
#: includes/class-wc-stripe-webhook-handler.php:
|
| 1012 |
#: includes/payment-methods/class-wc-gateway-stripe-sepa.php:353
|
| 1013 |
msgid "This card is no longer available and has been removed."
|
| 1014 |
msgstr ""
|
|
@@ -1035,7 +1034,7 @@ msgstr ""
|
|
| 1035 |
msgid "SEPA IBAN ending in %s"
|
| 1036 |
msgstr ""
|
| 1037 |
|
| 1038 |
-
#: includes/class-wc-stripe-webhook-handler.php:
|
| 1039 |
#. translators: 1) The URL to the order.
|
| 1040 |
msgid ""
|
| 1041 |
"A dispute was created for this order. Response is needed. Please go to your "
|
|
@@ -1043,34 +1042,34 @@ msgid ""
|
|
| 1043 |
"Dashboard</a> to review this dispute."
|
| 1044 |
msgstr ""
|
| 1045 |
|
| 1046 |
-
#: includes/class-wc-stripe-webhook-handler.php:
|
| 1047 |
#. translators: partial captured amount
|
| 1048 |
msgid "This charge was partially captured via Stripe Dashboard in the amount of: %s"
|
| 1049 |
msgstr ""
|
| 1050 |
|
| 1051 |
-
#: includes/class-wc-stripe-webhook-handler.php:
|
| 1052 |
msgid "This payment failed to clear."
|
| 1053 |
msgstr ""
|
| 1054 |
|
| 1055 |
-
#: includes/class-wc-stripe-webhook-handler.php:
|
| 1056 |
msgid "This payment has cancelled."
|
| 1057 |
msgstr ""
|
| 1058 |
|
| 1059 |
-
#: includes/class-wc-stripe-webhook-handler.php:
|
| 1060 |
msgid "Refunded via Stripe Dashboard"
|
| 1061 |
msgstr ""
|
| 1062 |
|
| 1063 |
-
#: includes/class-wc-stripe-webhook-handler.php:
|
| 1064 |
-
#: includes/class-wc-stripe-webhook-handler.php:
|
| 1065 |
msgid "Pre-Authorization Released via Stripe Dashboard"
|
| 1066 |
msgstr ""
|
| 1067 |
|
| 1068 |
-
#: includes/class-wc-stripe-webhook-handler.php:
|
| 1069 |
#. translators: 1) dollar amount 2) transaction id 3) refund message
|
| 1070 |
msgid "Refunded %1$s - Refund ID: %2$s - %3$s"
|
| 1071 |
msgstr ""
|
| 1072 |
|
| 1073 |
-
#: includes/class-wc-stripe-webhook-handler.php:
|
| 1074 |
#. translators: 1) The URL to the order. 2) The reason type.
|
| 1075 |
msgid ""
|
| 1076 |
"A review has been opened for this order. Action is needed. Please go to "
|
|
@@ -1078,47 +1077,116 @@ msgid ""
|
|
| 1078 |
"Dashboard</a> to review the issue. Reason: (%2$s)"
|
| 1079 |
msgstr ""
|
| 1080 |
|
| 1081 |
-
#: includes/class-wc-stripe-webhook-handler.php:
|
| 1082 |
#. translators: 1) The reason type.
|
| 1083 |
msgid "The opened review for this order is now closed. Reason: (%s)"
|
| 1084 |
msgstr ""
|
| 1085 |
|
| 1086 |
-
#: includes/compat/class-wc-stripe-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1087 |
msgid "Unable to store payment details. Please try again."
|
| 1088 |
msgstr ""
|
| 1089 |
|
| 1090 |
-
#: includes/compat/class-wc-stripe-pre-orders-compat.php:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1091 |
#. translators: error message
|
| 1092 |
msgid "Stripe Transaction Failed (%s)"
|
| 1093 |
msgstr ""
|
| 1094 |
|
| 1095 |
#: includes/compat/class-wc-stripe-sepa-subs-compat.php:88
|
| 1096 |
-
#: includes/compat/class-wc-stripe-subs-compat.php:
|
| 1097 |
msgid ""
|
| 1098 |
"Update the Payment Method used for all of my active subscriptions "
|
| 1099 |
"(optional)."
|
| 1100 |
msgstr ""
|
| 1101 |
|
| 1102 |
#: includes/compat/class-wc-stripe-sepa-subs-compat.php:226
|
| 1103 |
-
#: includes/compat/class-wc-stripe-subs-compat.php:
|
| 1104 |
msgid "Customer not found"
|
| 1105 |
msgstr ""
|
| 1106 |
|
| 1107 |
#: includes/compat/class-wc-stripe-sepa-subs-compat.php:386
|
| 1108 |
-
#: includes/compat/class-wc-stripe-subs-compat.php:
|
| 1109 |
#. translators: error message
|
| 1110 |
msgid "A \"Stripe Customer ID\" value is required."
|
| 1111 |
msgstr ""
|
| 1112 |
|
| 1113 |
#: includes/compat/class-wc-stripe-sepa-subs-compat.php:388
|
| 1114 |
-
#: includes/compat/class-wc-stripe-subs-compat.php:
|
| 1115 |
msgid ""
|
| 1116 |
"Invalid customer ID. A valid \"Stripe Customer ID\" must begin with "
|
| 1117 |
"\"cus_\"."
|
| 1118 |
msgstr ""
|
| 1119 |
|
| 1120 |
#: includes/compat/class-wc-stripe-sepa-subs-compat.php:397
|
| 1121 |
-
#: includes/compat/class-wc-stripe-subs-compat.php:
|
| 1122 |
msgid ""
|
| 1123 |
"Invalid source ID. A valid source \"Stripe Source ID\" must begin with "
|
| 1124 |
"\"src_\" or \"card_\"."
|
|
@@ -1129,19 +1197,17 @@ msgstr ""
|
|
| 1129 |
msgid "Via SEPA Direct Debit ending in %1$s"
|
| 1130 |
msgstr ""
|
| 1131 |
|
| 1132 |
-
#: includes/compat/class-wc-stripe-subs-compat.php:
|
| 1133 |
-
msgid ""
|
| 1134 |
-
"Sorry, we're not accepting prepaid cards at this time. Your credit card has "
|
| 1135 |
-
"not been charge. Please try with alternative payment method."
|
| 1136 |
msgstr ""
|
| 1137 |
|
| 1138 |
-
#: includes/compat/class-wc-stripe-subs-compat.php:
|
| 1139 |
#. translators: 1) card brand 2) last 4 digits
|
| 1140 |
msgid "Via %1$s card ending in %2$s"
|
| 1141 |
msgstr ""
|
| 1142 |
|
| 1143 |
#: includes/payment-methods/class-wc-gateway-stripe-alipay.php:60
|
| 1144 |
-
#: woocommerce-gateway-stripe.php:
|
| 1145 |
msgid "Stripe Alipay"
|
| 1146 |
msgstr ""
|
| 1147 |
|
|
@@ -1170,27 +1236,27 @@ msgid "Add Payment"
|
|
| 1170 |
msgstr ""
|
| 1171 |
|
| 1172 |
#: includes/payment-methods/class-wc-gateway-stripe-bancontact.php:60
|
| 1173 |
-
#: woocommerce-gateway-stripe.php:
|
| 1174 |
msgid "Stripe Bancontact"
|
| 1175 |
msgstr ""
|
| 1176 |
|
| 1177 |
#: includes/payment-methods/class-wc-gateway-stripe-eps.php:60
|
| 1178 |
-
#: woocommerce-gateway-stripe.php:
|
| 1179 |
msgid "Stripe EPS"
|
| 1180 |
msgstr ""
|
| 1181 |
|
| 1182 |
#: includes/payment-methods/class-wc-gateway-stripe-giropay.php:60
|
| 1183 |
-
#: woocommerce-gateway-stripe.php:
|
| 1184 |
msgid "Stripe Giropay"
|
| 1185 |
msgstr ""
|
| 1186 |
|
| 1187 |
#: includes/payment-methods/class-wc-gateway-stripe-ideal.php:60
|
| 1188 |
-
#: woocommerce-gateway-stripe.php:
|
| 1189 |
msgid "Stripe iDeal"
|
| 1190 |
msgstr ""
|
| 1191 |
|
| 1192 |
#: includes/payment-methods/class-wc-gateway-stripe-multibanco.php:60
|
| 1193 |
-
#: woocommerce-gateway-stripe.php:
|
| 1194 |
msgid "Stripe Multibanco"
|
| 1195 |
msgstr ""
|
| 1196 |
|
|
@@ -1219,12 +1285,12 @@ msgid "Awaiting Multibanco payment"
|
|
| 1219 |
msgstr ""
|
| 1220 |
|
| 1221 |
#: includes/payment-methods/class-wc-gateway-stripe-p24.php:60
|
| 1222 |
-
#: woocommerce-gateway-stripe.php:
|
| 1223 |
msgid "Stripe P24"
|
| 1224 |
msgstr ""
|
| 1225 |
|
| 1226 |
#: includes/payment-methods/class-wc-gateway-stripe-sepa.php:75
|
| 1227 |
-
#: woocommerce-gateway-stripe.php:
|
| 1228 |
msgid "Stripe SEPA Direct Debit"
|
| 1229 |
msgstr ""
|
| 1230 |
|
|
@@ -1251,7 +1317,7 @@ msgid ""
|
|
| 1251 |
msgstr ""
|
| 1252 |
|
| 1253 |
#: includes/payment-methods/class-wc-gateway-stripe-sofort.php:60
|
| 1254 |
-
#: woocommerce-gateway-stripe.php:
|
| 1255 |
msgid "Stripe SOFORT"
|
| 1256 |
msgstr ""
|
| 1257 |
|
|
@@ -1309,6 +1375,23 @@ msgstr ""
|
|
| 1309 |
msgid "Discount"
|
| 1310 |
msgstr ""
|
| 1311 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1312 |
#: woocommerce-gateway-stripe.php:32
|
| 1313 |
#. translators: 1. URL link.
|
| 1314 |
msgid ""
|
|
@@ -1316,15 +1399,15 @@ msgid ""
|
|
| 1316 |
"here."
|
| 1317 |
msgstr ""
|
| 1318 |
|
| 1319 |
-
#: woocommerce-gateway-stripe.php:
|
| 1320 |
msgid "Settings"
|
| 1321 |
msgstr ""
|
| 1322 |
|
| 1323 |
-
#: woocommerce-gateway-stripe.php:
|
| 1324 |
msgid "Docs"
|
| 1325 |
msgstr ""
|
| 1326 |
|
| 1327 |
-
#: woocommerce-gateway-stripe.php:
|
| 1328 |
msgid "Support"
|
| 1329 |
msgstr ""
|
| 1330 |
|
|
@@ -1346,4 +1429,51 @@ msgstr ""
|
|
| 1346 |
|
| 1347 |
#. Author URI of the plugin/theme
|
| 1348 |
msgid "https://woocommerce.com/"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1349 |
msgstr ""
|
| 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.3.0\n"
|
| 6 |
+
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/stripe-git\n"
|
| 7 |
+
"POT-Creation-Date: 2019-10-17 20:55:54+00:00\n"
|
|
|
|
| 8 |
"MIME-Version: 1.0\n"
|
| 9 |
"Content-Type: text/plain; charset=utf-8\n"
|
| 10 |
"Content-Transfer-Encoding: 8bit\n"
|
| 27 |
msgid "Save payment information to my account for future purchases."
|
| 28 |
msgstr ""
|
| 29 |
|
| 30 |
+
#: includes/abstracts/abstract-wc-stripe-payment-gateway.php:230
|
| 31 |
#: includes/compat/class-wc-stripe-sepa-subs-compat.php:216
|
| 32 |
+
#: includes/compat/class-wc-stripe-subs-compat.php:218
|
| 33 |
#. translators: 1) dollar amount
|
| 34 |
#. translators: minimum amount
|
| 35 |
msgid "Sorry, the minimum allowed order total is %1$s to use this payment method."
|
| 36 |
msgstr ""
|
| 37 |
|
| 38 |
+
#: includes/abstracts/abstract-wc-stripe-payment-gateway.php:326
|
| 39 |
#. translators: 1) blog name 2) order number
|
| 40 |
msgid "%1$s - Order %2$s"
|
| 41 |
msgstr ""
|
| 42 |
|
| 43 |
+
#: includes/abstracts/abstract-wc-stripe-payment-gateway.php:353
|
| 44 |
msgid "customer_name"
|
| 45 |
msgstr ""
|
| 46 |
|
| 47 |
+
#: includes/abstracts/abstract-wc-stripe-payment-gateway.php:354
|
| 48 |
msgid "customer_email"
|
| 49 |
msgstr ""
|
| 50 |
|
| 51 |
+
#: includes/abstracts/abstract-wc-stripe-payment-gateway.php:417
|
| 52 |
#. translators: transaction id
|
| 53 |
msgid "Stripe charge awaiting payment: %s."
|
| 54 |
msgstr ""
|
| 55 |
|
| 56 |
+
#: includes/abstracts/abstract-wc-stripe-payment-gateway.php:424
|
| 57 |
#: includes/class-wc-stripe-order-handler.php:296
|
| 58 |
+
#: includes/class-wc-stripe-webhook-handler.php:347
|
| 59 |
+
#: includes/class-wc-stripe-webhook-handler.php:399
|
| 60 |
#. translators: transaction id
|
| 61 |
msgid "Stripe charge complete (Charge ID: %s)"
|
| 62 |
msgstr ""
|
| 63 |
|
| 64 |
+
#: includes/abstracts/abstract-wc-stripe-payment-gateway.php:429
|
| 65 |
+
#: includes/class-wc-gateway-stripe.php:495
|
| 66 |
#: includes/compat/class-wc-stripe-sepa-subs-compat.php:173
|
|
|
|
| 67 |
msgid "Payment processing failed. Please retry."
|
| 68 |
msgstr ""
|
| 69 |
|
| 70 |
+
#: includes/abstracts/abstract-wc-stripe-payment-gateway.php:441
|
| 71 |
#. translators: transaction id
|
| 72 |
msgid ""
|
| 73 |
"Stripe charge authorized (Charge ID: %s). Process order to take payment, or "
|
| 74 |
"cancel to remove the pre-authorization."
|
| 75 |
msgstr ""
|
| 76 |
|
| 77 |
+
#: includes/abstracts/abstract-wc-stripe-payment-gateway.php:615
|
| 78 |
msgid "Invalid payment method. Please input a new card number."
|
| 79 |
msgstr ""
|
| 80 |
|
| 81 |
+
#: includes/abstracts/abstract-wc-stripe-payment-gateway.php:895
|
| 82 |
#. translators: 1) dollar amount 2) transaction id 3) refund message
|
| 83 |
msgid "Refunded %1$s - Refund ID: %2$s - Reason: %3$s"
|
| 84 |
msgstr ""
|
| 85 |
|
| 86 |
+
#: includes/abstracts/abstract-wc-stripe-payment-gateway.php:895
|
| 87 |
msgid "Pre-Authorization Released"
|
| 88 |
msgstr ""
|
| 89 |
|
| 90 |
+
#: includes/abstracts/abstract-wc-stripe-payment-gateway.php:913
|
| 91 |
msgid "There was a problem adding the payment method."
|
| 92 |
msgstr ""
|
| 93 |
|
| 94 |
+
#: includes/admin/class-wc-stripe-admin-notices.php:124
|
| 95 |
#. translators: 1) A URL that explains Stripe Radar.
|
| 96 |
msgid ""
|
| 97 |
"WooCommerce Stripe - We see that you had the \"Require 3D secure when "
|
| 100 |
"href=\"%s\" target=\"_blank\">here</a>."
|
| 101 |
msgstr ""
|
| 102 |
|
| 103 |
+
#: includes/admin/class-wc-stripe-admin-notices.php:131
|
| 104 |
#. translators: 1) int version 2) int version
|
| 105 |
msgid ""
|
| 106 |
"WooCommerce Stripe - We recently made changes to Stripe that may impact the "
|
| 107 |
"appearance of your checkout. If your checkout has changed unexpectedly, "
|
| 108 |
"please follow these <a "
|
| 109 |
+
"href=\"https://docs.woocommerce.com/document/stripe/#styling\" "
|
| 110 |
"target=\"_blank\">instructions</a> to fix."
|
| 111 |
msgstr ""
|
| 112 |
|
| 113 |
+
#: includes/admin/class-wc-stripe-admin-notices.php:141
|
| 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:152
|
| 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:162
|
| 128 |
msgid "WooCommerce Stripe - cURL is not installed."
|
| 129 |
msgstr ""
|
| 130 |
|
| 131 |
+
#: includes/admin/class-wc-stripe-admin-notices.php:172
|
| 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:183
|
| 139 |
#. translators: 1) link
|
| 140 |
msgid ""
|
| 141 |
"Stripe is in test mode however your test keys may not be valid. Test keys "
|
| 143 |
"<a href=\"%s\">set your Stripe account keys</a>."
|
| 144 |
msgstr ""
|
| 145 |
|
| 146 |
+
#: includes/admin/class-wc-stripe-admin-notices.php:192
|
| 147 |
#. translators: 1) link
|
| 148 |
msgid ""
|
| 149 |
"Stripe is in live mode however your test keys may not be valid. Live keys "
|
| 151 |
"<a href=\"%s\">set your Stripe account keys</a>."
|
| 152 |
msgstr ""
|
| 153 |
|
| 154 |
+
#: includes/admin/class-wc-stripe-admin-notices.php:201
|
| 155 |
#. translators: 1) link
|
| 156 |
msgid ""
|
| 157 |
"Stripe is enabled, but a SSL certificate is not detected. Your checkout may "
|
| 159 |
"target=\"_blank\">SSL certificate</a>"
|
| 160 |
msgstr ""
|
| 161 |
|
| 162 |
+
#: includes/admin/class-wc-stripe-admin-notices.php:206
|
| 163 |
+
msgid ""
|
| 164 |
+
"Stripe is now ready for Strong Customer Authentication (SCA) and 3D Secure "
|
| 165 |
+
"2! <a href=\"%1$s\" target=\"_blank\">Read about SCA</a>"
|
| 166 |
+
msgstr ""
|
| 167 |
+
|
| 168 |
+
#: includes/admin/class-wc-stripe-admin-notices.php:229
|
| 169 |
#. translators: %1$s Payment method, %2$s List of supported currencies
|
| 170 |
msgid "%1$s is enabled - it requires store currency to be set to %2$s"
|
| 171 |
msgstr ""
|
| 172 |
|
| 173 |
+
#: includes/admin/class-wc-stripe-admin-notices.php:243
|
| 174 |
msgid "Action failed. Please refresh the page and retry."
|
| 175 |
msgstr ""
|
| 176 |
|
| 177 |
+
#: includes/admin/class-wc-stripe-admin-notices.php:247
|
| 178 |
msgid "Cheatin’ huh?"
|
| 179 |
msgstr ""
|
| 180 |
|
| 210 |
|
| 211 |
#: includes/admin/class-wc-stripe-privacy.php:41
|
| 212 |
#: includes/compat/class-wc-stripe-sepa-subs-compat.php:463
|
| 213 |
+
#: includes/compat/class-wc-stripe-subs-compat.php:527
|
| 214 |
+
#: includes/compat/class-wc-stripe-subs-compat.php:542
|
| 215 |
msgid "N/A"
|
| 216 |
msgstr ""
|
| 217 |
|
| 765 |
"your Stripe account keys</a>."
|
| 766 |
msgstr ""
|
| 767 |
|
| 768 |
+
#: includes/class-wc-gateway-stripe.php:191
|
| 769 |
#. translators: 1) Opening anchor tag 2) closing anchor tag
|
| 770 |
msgid ""
|
| 771 |
"If your billing address has been changed for saved payment methods, be sure "
|
| 772 |
"to remove any %1$ssaved payment methods%2$s on file and re-add them."
|
| 773 |
msgstr ""
|
| 774 |
|
| 775 |
+
#: includes/class-wc-gateway-stripe.php:267
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 776 |
#. translators: link to Stripe testing page
|
| 777 |
msgid ""
|
| 778 |
"TEST MODE ENABLED. In test mode, you can use the card number "
|
| 781 |
"card numbers."
|
| 782 |
msgstr ""
|
| 783 |
|
| 784 |
+
#: includes/class-wc-gateway-stripe.php:306
|
| 785 |
msgid "Credit or debit card"
|
| 786 |
msgstr ""
|
| 787 |
|
| 788 |
+
#: includes/class-wc-gateway-stripe.php:314
|
| 789 |
msgid "Card Number"
|
| 790 |
msgstr ""
|
| 791 |
|
| 792 |
+
#: includes/class-wc-gateway-stripe.php:325
|
| 793 |
msgid "Expiry Date"
|
| 794 |
msgstr ""
|
| 795 |
|
| 796 |
+
#: includes/class-wc-gateway-stripe.php:333
|
| 797 |
msgid "Card Code (CVC)"
|
| 798 |
msgstr ""
|
| 799 |
|
| 800 |
+
#: includes/class-wc-gateway-stripe.php:408
|
| 801 |
msgid "Please accept the terms and conditions first"
|
| 802 |
msgstr ""
|
| 803 |
|
| 804 |
+
#: includes/class-wc-gateway-stripe.php:409
|
| 805 |
msgid "Please fill in required checkout fields first"
|
| 806 |
msgstr ""
|
| 807 |
|
| 808 |
+
#: includes/class-wc-gateway-stripe.php:438
|
| 809 |
+
#: includes/class-wc-gateway-stripe.php:482
|
| 810 |
msgid ""
|
| 811 |
"Sorry, we're not accepting prepaid cards at this time. Your credit card has "
|
| 812 |
"not been charged. Please try with alternative payment method."
|
| 813 |
msgstr ""
|
| 814 |
|
| 815 |
+
#: includes/class-wc-gateway-stripe.php:439
|
| 816 |
msgid "Please enter your IBAN account name."
|
| 817 |
msgstr ""
|
| 818 |
|
| 819 |
+
#: includes/class-wc-gateway-stripe.php:440
|
| 820 |
msgid "Please enter your IBAN account number."
|
| 821 |
msgstr ""
|
| 822 |
|
| 823 |
+
#: includes/class-wc-gateway-stripe.php:441
|
| 824 |
msgid "We couldn't initiate the payment. Please try again."
|
| 825 |
msgstr ""
|
| 826 |
|
| 827 |
+
#: includes/class-wc-gateway-stripe.php:452
|
| 828 |
msgid "Billing First Name and Last Name are required."
|
| 829 |
msgstr ""
|
| 830 |
|
| 831 |
+
#: includes/class-wc-gateway-stripe.php:716
|
| 832 |
#. translators: error message
|
| 833 |
msgid "This represents the fee Stripe collects for the transaction."
|
| 834 |
msgstr ""
|
| 835 |
|
| 836 |
+
#: includes/class-wc-gateway-stripe.php:717
|
| 837 |
msgid "Stripe Fee:"
|
| 838 |
msgstr ""
|
| 839 |
|
| 840 |
+
#: includes/class-wc-gateway-stripe.php:753
|
| 841 |
msgid ""
|
| 842 |
"This represents the net total that will be credited to your Stripe bank "
|
| 843 |
"account. This may be in the currency that is set in your Stripe account."
|
| 844 |
msgstr ""
|
| 845 |
|
| 846 |
+
#: includes/class-wc-gateway-stripe.php:754
|
| 847 |
msgid "Stripe Payout:"
|
| 848 |
msgstr ""
|
| 849 |
|
| 850 |
+
#: includes/class-wc-gateway-stripe.php:801
|
| 851 |
#: includes/class-wc-stripe-order-handler.php:162
|
| 852 |
+
#: includes/class-wc-stripe-webhook-handler.php:238
|
| 853 |
#: includes/compat/class-wc-stripe-sepa-subs-compat.php:263
|
| 854 |
+
#: includes/compat/class-wc-stripe-subs-compat.php:271
|
| 855 |
#: includes/payment-methods/class-wc-gateway-stripe-sepa.php:373
|
| 856 |
msgid ""
|
| 857 |
"Sorry, we are unable to process your payment at this time. Please retry "
|
| 858 |
"later."
|
| 859 |
msgstr ""
|
| 860 |
|
| 861 |
+
#: includes/class-wc-gateway-stripe.php:854
|
| 862 |
msgid ""
|
| 863 |
"Almost there!\n"
|
| 864 |
"\n"
|
| 866 |
"done is for you to authorize the payment with your bank."
|
| 867 |
msgstr ""
|
| 868 |
|
| 869 |
+
#: includes/class-wc-gateway-stripe.php:1066
|
| 870 |
+
#: includes/class-wc-stripe-webhook-handler.php:685
|
| 871 |
+
#: includes/class-wc-stripe-webhook-handler.php:724
|
| 872 |
#. translators: 1) The error message that was received from Stripe.
|
| 873 |
msgid "Stripe SCA authentication failed. Reason: %s"
|
| 874 |
msgstr ""
|
| 875 |
|
| 876 |
+
#: includes/class-wc-gateway-stripe.php:1067
|
| 877 |
msgid "Stripe SCA authentication failed."
|
| 878 |
msgstr ""
|
| 879 |
|
| 906 |
"the issue. (Logging must be enabled to see recorded logs)"
|
| 907 |
msgstr ""
|
| 908 |
|
| 909 |
+
#: includes/class-wc-stripe-customer.php:120
|
| 910 |
+
#. translators: %1$s First name, %2$s Second name, %3$s Username.
|
| 911 |
+
msgid "Name: %1$s %2$s, Username: %s"
|
| 912 |
msgstr ""
|
| 913 |
|
| 914 |
+
#: includes/class-wc-stripe-customer.php:131
|
| 915 |
+
#. translators: %1$s First name, %2$s Second name.
|
| 916 |
+
msgid "Name: %1$s %2$s, Guest"
|
| 917 |
msgstr ""
|
| 918 |
|
| 919 |
+
#: includes/class-wc-stripe-customer.php:209
|
| 920 |
msgid "Unable to add payment source."
|
| 921 |
msgstr ""
|
| 922 |
|
| 1007 |
msgstr ""
|
| 1008 |
|
| 1009 |
#: includes/class-wc-stripe-order-handler.php:144
|
| 1010 |
+
#: includes/class-wc-stripe-webhook-handler.php:219
|
| 1011 |
#: includes/payment-methods/class-wc-gateway-stripe-sepa.php:353
|
| 1012 |
msgid "This card is no longer available and has been removed."
|
| 1013 |
msgstr ""
|
| 1034 |
msgid "SEPA IBAN ending in %s"
|
| 1035 |
msgstr ""
|
| 1036 |
|
| 1037 |
+
#: includes/class-wc-stripe-webhook-handler.php:296
|
| 1038 |
#. translators: 1) The URL to the order.
|
| 1039 |
msgid ""
|
| 1040 |
"A dispute was created for this order. Response is needed. Please go to your "
|
| 1042 |
"Dashboard</a> to review this dispute."
|
| 1043 |
msgstr ""
|
| 1044 |
|
| 1045 |
+
#: includes/class-wc-stripe-webhook-handler.php:342
|
| 1046 |
#. translators: partial captured amount
|
| 1047 |
msgid "This charge was partially captured via Stripe Dashboard in the amount of: %s"
|
| 1048 |
msgstr ""
|
| 1049 |
|
| 1050 |
+
#: includes/class-wc-stripe-webhook-handler.php:428
|
| 1051 |
msgid "This payment failed to clear."
|
| 1052 |
msgstr ""
|
| 1053 |
|
| 1054 |
+
#: includes/class-wc-stripe-webhook-handler.php:461
|
| 1055 |
msgid "This payment has cancelled."
|
| 1056 |
msgstr ""
|
| 1057 |
|
| 1058 |
+
#: includes/class-wc-stripe-webhook-handler.php:496
|
| 1059 |
msgid "Refunded via Stripe Dashboard"
|
| 1060 |
msgstr ""
|
| 1061 |
|
| 1062 |
+
#: includes/class-wc-stripe-webhook-handler.php:496
|
| 1063 |
+
#: includes/class-wc-stripe-webhook-handler.php:524
|
| 1064 |
msgid "Pre-Authorization Released via Stripe Dashboard"
|
| 1065 |
msgstr ""
|
| 1066 |
|
| 1067 |
+
#: includes/class-wc-stripe-webhook-handler.php:524
|
| 1068 |
#. translators: 1) dollar amount 2) transaction id 3) refund message
|
| 1069 |
msgid "Refunded %1$s - Refund ID: %2$s - %3$s"
|
| 1070 |
msgstr ""
|
| 1071 |
|
| 1072 |
+
#: includes/class-wc-stripe-webhook-handler.php:555
|
| 1073 |
#. translators: 1) The URL to the order. 2) The reason type.
|
| 1074 |
msgid ""
|
| 1075 |
"A review has been opened for this order. Action is needed. Please go to "
|
| 1077 |
"Dashboard</a> to review the issue. Reason: (%2$s)"
|
| 1078 |
msgstr ""
|
| 1079 |
|
| 1080 |
+
#: includes/class-wc-stripe-webhook-handler.php:588
|
| 1081 |
#. translators: 1) The reason type.
|
| 1082 |
msgid "The opened review for this order is now closed. Reason: (%s)"
|
| 1083 |
msgstr ""
|
| 1084 |
|
| 1085 |
+
#: includes/compat/class-wc-stripe-email-failed-authentication-retry.php:29
|
| 1086 |
+
msgid "Payment Authentication Requested Email"
|
| 1087 |
+
msgstr ""
|
| 1088 |
+
|
| 1089 |
+
#: includes/compat/class-wc-stripe-email-failed-authentication-retry.php:30
|
| 1090 |
+
msgid ""
|
| 1091 |
+
"Payment authentication requested emails are sent to chosen recipient(s) "
|
| 1092 |
+
"when an attempt to automatically process a subscription renewal payment "
|
| 1093 |
+
"fails because the transaction requires an SCA verification, the customer is "
|
| 1094 |
+
"requested to authenticate the payment, and a retry rule has been applied to "
|
| 1095 |
+
"notify the customer again within a certain time period."
|
| 1096 |
+
msgstr ""
|
| 1097 |
+
|
| 1098 |
+
#: includes/compat/class-wc-stripe-email-failed-authentication-retry.php:32
|
| 1099 |
+
msgid "Automatic renewal payment failed due to authentication required"
|
| 1100 |
+
msgstr ""
|
| 1101 |
+
|
| 1102 |
+
#: includes/compat/class-wc-stripe-email-failed-authentication-retry.php:33
|
| 1103 |
+
msgid ""
|
| 1104 |
+
"[{site_title}] Automatic payment failed for {order_number}. Customer asked "
|
| 1105 |
+
"to authenticate payment and will be notified again {retry_time}"
|
| 1106 |
+
msgstr ""
|
| 1107 |
+
|
| 1108 |
+
#: includes/compat/class-wc-stripe-email-failed-authentication.php:86
|
| 1109 |
+
msgid "Enable this email notification"
|
| 1110 |
+
msgstr ""
|
| 1111 |
+
|
| 1112 |
+
#: includes/compat/class-wc-stripe-email-failed-preorder-authentication.php:26
|
| 1113 |
+
msgid "Pre-order Payment Action Needed"
|
| 1114 |
+
msgstr ""
|
| 1115 |
+
|
| 1116 |
+
#: includes/compat/class-wc-stripe-email-failed-preorder-authentication.php:27
|
| 1117 |
+
msgid ""
|
| 1118 |
+
"This is an order notification sent to the customer once a pre-order is "
|
| 1119 |
+
"complete, but additional payment steps are required."
|
| 1120 |
+
msgstr ""
|
| 1121 |
+
|
| 1122 |
+
#: includes/compat/class-wc-stripe-email-failed-preorder-authentication.php:84
|
| 1123 |
+
#: includes/compat/class-wc-stripe-email-failed-preorder-authentication.php:93
|
| 1124 |
+
msgid "Payment authorization needed for pre-order {order_number}"
|
| 1125 |
+
msgstr ""
|
| 1126 |
+
|
| 1127 |
+
#: includes/compat/class-wc-stripe-email-failed-renewal-authentication.php:19
|
| 1128 |
+
msgid "Failed Subscription Renewal SCA Authentication"
|
| 1129 |
+
msgstr ""
|
| 1130 |
+
|
| 1131 |
+
#: includes/compat/class-wc-stripe-email-failed-renewal-authentication.php:20
|
| 1132 |
+
msgid ""
|
| 1133 |
+
"Sent to a customer when a renewal fails because the transaction requires an "
|
| 1134 |
+
"SCA verification. The email contains renewal order information and payment "
|
| 1135 |
+
"links."
|
| 1136 |
+
msgstr ""
|
| 1137 |
+
|
| 1138 |
+
#: includes/compat/class-wc-stripe-email-failed-renewal-authentication.php:67
|
| 1139 |
+
msgid ""
|
| 1140 |
+
"Payment authorization needed for renewal of {site_title} order "
|
| 1141 |
+
"{order_number}"
|
| 1142 |
+
msgstr ""
|
| 1143 |
+
|
| 1144 |
+
#: includes/compat/class-wc-stripe-email-failed-renewal-authentication.php:76
|
| 1145 |
+
msgid "Payment authorization needed for renewal of order {order_number}"
|
| 1146 |
+
msgstr ""
|
| 1147 |
+
|
| 1148 |
+
#: includes/compat/class-wc-stripe-pre-orders-compat.php:57
|
| 1149 |
msgid "Unable to store payment details. Please try again."
|
| 1150 |
msgstr ""
|
| 1151 |
|
| 1152 |
+
#: includes/compat/class-wc-stripe-pre-orders-compat.php:121
|
| 1153 |
+
#: includes/compat/class-wc-stripe-subs-compat.php:303
|
| 1154 |
+
#: includes/compat/class-wc-stripe-subs-compat.php:606
|
| 1155 |
+
msgid "Stripe charge awaiting authentication by user: %s."
|
| 1156 |
+
msgstr ""
|
| 1157 |
+
|
| 1158 |
+
#: includes/compat/class-wc-stripe-pre-orders-compat.php:138
|
| 1159 |
#. translators: error message
|
| 1160 |
msgid "Stripe Transaction Failed (%s)"
|
| 1161 |
msgstr ""
|
| 1162 |
|
| 1163 |
#: includes/compat/class-wc-stripe-sepa-subs-compat.php:88
|
| 1164 |
+
#: includes/compat/class-wc-stripe-subs-compat.php:97
|
| 1165 |
msgid ""
|
| 1166 |
"Update the Payment Method used for all of my active subscriptions "
|
| 1167 |
"(optional)."
|
| 1168 |
msgstr ""
|
| 1169 |
|
| 1170 |
#: includes/compat/class-wc-stripe-sepa-subs-compat.php:226
|
| 1171 |
+
#: includes/compat/class-wc-stripe-subs-compat.php:233
|
| 1172 |
msgid "Customer not found"
|
| 1173 |
msgstr ""
|
| 1174 |
|
| 1175 |
#: includes/compat/class-wc-stripe-sepa-subs-compat.php:386
|
| 1176 |
+
#: includes/compat/class-wc-stripe-subs-compat.php:450
|
| 1177 |
#. translators: error message
|
| 1178 |
msgid "A \"Stripe Customer ID\" value is required."
|
| 1179 |
msgstr ""
|
| 1180 |
|
| 1181 |
#: includes/compat/class-wc-stripe-sepa-subs-compat.php:388
|
| 1182 |
+
#: includes/compat/class-wc-stripe-subs-compat.php:452
|
| 1183 |
msgid ""
|
| 1184 |
"Invalid customer ID. A valid \"Stripe Customer ID\" must begin with "
|
| 1185 |
"\"cus_\"."
|
| 1186 |
msgstr ""
|
| 1187 |
|
| 1188 |
#: includes/compat/class-wc-stripe-sepa-subs-compat.php:397
|
| 1189 |
+
#: includes/compat/class-wc-stripe-subs-compat.php:461
|
| 1190 |
msgid ""
|
| 1191 |
"Invalid source ID. A valid source \"Stripe Source ID\" must begin with "
|
| 1192 |
"\"src_\" or \"card_\"."
|
| 1197 |
msgid "Via SEPA Direct Debit ending in %1$s"
|
| 1198 |
msgstr ""
|
| 1199 |
|
| 1200 |
+
#: includes/compat/class-wc-stripe-subs-compat.php:295
|
| 1201 |
+
msgid "This transaction requires authentication."
|
|
|
|
|
|
|
| 1202 |
msgstr ""
|
| 1203 |
|
| 1204 |
+
#: includes/compat/class-wc-stripe-subs-compat.php:542
|
| 1205 |
#. translators: 1) card brand 2) last 4 digits
|
| 1206 |
msgid "Via %1$s card ending in %2$s"
|
| 1207 |
msgstr ""
|
| 1208 |
|
| 1209 |
#: includes/payment-methods/class-wc-gateway-stripe-alipay.php:60
|
| 1210 |
+
#: woocommerce-gateway-stripe.php:256
|
| 1211 |
msgid "Stripe Alipay"
|
| 1212 |
msgstr ""
|
| 1213 |
|
| 1236 |
msgstr ""
|
| 1237 |
|
| 1238 |
#: includes/payment-methods/class-wc-gateway-stripe-bancontact.php:60
|
| 1239 |
+
#: woocommerce-gateway-stripe.php:250
|
| 1240 |
msgid "Stripe Bancontact"
|
| 1241 |
msgstr ""
|
| 1242 |
|
| 1243 |
#: includes/payment-methods/class-wc-gateway-stripe-eps.php:60
|
| 1244 |
+
#: woocommerce-gateway-stripe.php:253
|
| 1245 |
msgid "Stripe EPS"
|
| 1246 |
msgstr ""
|
| 1247 |
|
| 1248 |
#: includes/payment-methods/class-wc-gateway-stripe-giropay.php:60
|
| 1249 |
+
#: woocommerce-gateway-stripe.php:252
|
| 1250 |
msgid "Stripe Giropay"
|
| 1251 |
msgstr ""
|
| 1252 |
|
| 1253 |
#: includes/payment-methods/class-wc-gateway-stripe-ideal.php:60
|
| 1254 |
+
#: woocommerce-gateway-stripe.php:254
|
| 1255 |
msgid "Stripe iDeal"
|
| 1256 |
msgstr ""
|
| 1257 |
|
| 1258 |
#: includes/payment-methods/class-wc-gateway-stripe-multibanco.php:60
|
| 1259 |
+
#: woocommerce-gateway-stripe.php:258
|
| 1260 |
msgid "Stripe Multibanco"
|
| 1261 |
msgstr ""
|
| 1262 |
|
| 1285 |
msgstr ""
|
| 1286 |
|
| 1287 |
#: includes/payment-methods/class-wc-gateway-stripe-p24.php:60
|
| 1288 |
+
#: woocommerce-gateway-stripe.php:255
|
| 1289 |
msgid "Stripe P24"
|
| 1290 |
msgstr ""
|
| 1291 |
|
| 1292 |
#: includes/payment-methods/class-wc-gateway-stripe-sepa.php:75
|
| 1293 |
+
#: woocommerce-gateway-stripe.php:257
|
| 1294 |
msgid "Stripe SEPA Direct Debit"
|
| 1295 |
msgstr ""
|
| 1296 |
|
| 1317 |
msgstr ""
|
| 1318 |
|
| 1319 |
#: includes/payment-methods/class-wc-gateway-stripe-sofort.php:60
|
| 1320 |
+
#: woocommerce-gateway-stripe.php:251
|
| 1321 |
msgid "Stripe SOFORT"
|
| 1322 |
msgstr ""
|
| 1323 |
|
| 1375 |
msgid "Discount"
|
| 1376 |
msgstr ""
|
| 1377 |
|
| 1378 |
+
#: templates/emails/failed-preorder-authentication.php:20
|
| 1379 |
+
msgid "Authorize the payment now »"
|
| 1380 |
+
msgstr ""
|
| 1381 |
+
|
| 1382 |
+
#: templates/emails/failed-preorder-authentication.php:56
|
| 1383 |
+
msgid "Thanks for shopping with us."
|
| 1384 |
+
msgstr ""
|
| 1385 |
+
|
| 1386 |
+
#: templates/emails/failed-renewal-authentication-requested.php:35
|
| 1387 |
+
#: templates/emails/plain/failed-renewal-authentication-requested.php:26
|
| 1388 |
+
msgid "The renewal order is as follows:"
|
| 1389 |
+
msgstr ""
|
| 1390 |
+
|
| 1391 |
+
#: templates/emails/failed-renewal-authentication.php:12
|
| 1392 |
+
msgid "Authorize the payment »"
|
| 1393 |
+
msgstr ""
|
| 1394 |
+
|
| 1395 |
#: woocommerce-gateway-stripe.php:32
|
| 1396 |
#. translators: 1. URL link.
|
| 1397 |
msgid ""
|
| 1399 |
"here."
|
| 1400 |
msgstr ""
|
| 1401 |
|
| 1402 |
+
#: woocommerce-gateway-stripe.php:197
|
| 1403 |
msgid "Settings"
|
| 1404 |
msgstr ""
|
| 1405 |
|
| 1406 |
+
#: woocommerce-gateway-stripe.php:198
|
| 1407 |
msgid "Docs"
|
| 1408 |
msgstr ""
|
| 1409 |
|
| 1410 |
+
#: woocommerce-gateway-stripe.php:199
|
| 1411 |
msgid "Support"
|
| 1412 |
msgstr ""
|
| 1413 |
|
| 1429 |
|
| 1430 |
#. Author URI of the plugin/theme
|
| 1431 |
msgid "https://woocommerce.com/"
|
| 1432 |
+
msgstr ""
|
| 1433 |
+
|
| 1434 |
+
#: includes/compat/class-wc-stripe-email-failed-authentication.php:84
|
| 1435 |
+
msgctxt "an email notification"
|
| 1436 |
+
msgid "Enable/Disable"
|
| 1437 |
+
msgstr ""
|
| 1438 |
+
|
| 1439 |
+
#: templates/emails/failed-preorder-authentication.php:19
|
| 1440 |
+
#. translators: %s is a link to the payment re-authentication URL.
|
| 1441 |
+
msgctxt "In failed SCA authentication for a pre-order."
|
| 1442 |
+
msgid ""
|
| 1443 |
+
"Your pre-order is now available, but payment cannot be completed "
|
| 1444 |
+
"automatically. %s"
|
| 1445 |
+
msgstr ""
|
| 1446 |
+
|
| 1447 |
+
#: templates/emails/failed-renewal-authentication-requested.php:23
|
| 1448 |
+
#: templates/emails/plain/failed-renewal-authentication-requested.php:17
|
| 1449 |
+
#. translators: %1$s: an order number, %2$s: the customer's full name, %3$s:
|
| 1450 |
+
#. lowercase human time diff in the form returned by wcs_get_human_time_diff(),
|
| 1451 |
+
#. e.g. 'in 12 hours'.
|
| 1452 |
+
msgctxt "In admin renewal failed email"
|
| 1453 |
+
msgid ""
|
| 1454 |
+
"The automatic recurring payment for order %1$s from %2$s has failed. The "
|
| 1455 |
+
"customer was sent an email requesting authentication of payment. If the "
|
| 1456 |
+
"customer does not authenticate the payment, they will be requested by email "
|
| 1457 |
+
"again %3$s."
|
| 1458 |
+
msgstr ""
|
| 1459 |
+
|
| 1460 |
+
#: templates/emails/failed-renewal-authentication.php:12
|
| 1461 |
+
#: templates/emails/plain/failed-renewal-authentication.php:9
|
| 1462 |
+
#. translators: %1$s: name of the blog, %2$s: link to payment re-authentication
|
| 1463 |
+
#. URL, note: no full stop due to url at the end
|
| 1464 |
+
#. translators: %1$s: name of the blog, %2$s: link to checkout payment url,
|
| 1465 |
+
#. note: no full stop due to url at the end
|
| 1466 |
+
msgctxt "In failed renewal authentication email"
|
| 1467 |
+
msgid ""
|
| 1468 |
+
"The automatic payment to renew your subscription with %1$s has failed. To "
|
| 1469 |
+
"reactivate the subscription, please login and authorize the renewal from "
|
| 1470 |
+
"your account page: %2$s"
|
| 1471 |
+
msgstr ""
|
| 1472 |
+
|
| 1473 |
+
#: templates/emails/plain/failed-preorder-authentication.php:10
|
| 1474 |
+
#. translators: %s is a link to the payment re-authentication URL.
|
| 1475 |
+
msgctxt "woocommerce-gateway-stripe"
|
| 1476 |
+
msgid ""
|
| 1477 |
+
"Your pre-order is now available, but payment cannot be completed "
|
| 1478 |
+
"automatically. Please complete the payment now: %s"
|
| 1479 |
msgstr ""
|
|
@@ -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.2.
|
| 6 |
Requires PHP: 5.6
|
| 7 |
-
Stable tag: 4.
|
| 8 |
License: GPLv3
|
| 9 |
License URI: https://www.gnu.org/licenses/gpl-3.0.html
|
| 10 |
Attributions: thorsten-stripe
|
|
@@ -113,20 +113,19 @@ If you get stuck, you can ask for help in the Plugin Forum.
|
|
| 113 |
|
| 114 |
== Changelog ==
|
| 115 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 116 |
= 4.2.5 - 2019-10-02 =
|
| 117 |
* Fix - WooCommerce Subscriptions that use only the Stripe customer ID can again be renewed
|
| 118 |
|
| 119 |
-
= 4.2.4 - 2019-09-18 =
|
| 120 |
-
* Fix - Unclear error message when email address not completely filled in.
|
| 121 |
-
* Fix - Add payment request button compatibility with variable subscriptions
|
| 122 |
-
* Tweak - Do not show payment request button for shippable trial subscription products
|
| 123 |
-
* Fix - Do not copy the payment intent id when creating a subscription renewal
|
| 124 |
-
* Fix - Return early from check intent status if no order - props strayobject
|
| 125 |
-
* Fix - Extend webhook time window from 1 to 5 minutes to match Stripe client
|
| 126 |
-
* Update - WooCommerce 3.7 compatibility
|
| 127 |
-
* Update - Apple Pay Domain association file
|
| 128 |
-
* Update - Grandfather pre-SCA subscription renewals for SCA
|
| 129 |
-
|
| 130 |
[See changelog for all versions](https://raw.githubusercontent.com/woocommerce/woocommerce-gateway-stripe/master/changelog.txt).
|
| 131 |
|
| 132 |
== Upgrade Notice ==
|
| 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.4
|
| 6 |
Requires PHP: 5.6
|
| 7 |
+
Stable tag: 4.3.0
|
| 8 |
License: GPLv3
|
| 9 |
License URI: https://www.gnu.org/licenses/gpl-3.0.html
|
| 10 |
Attributions: thorsten-stripe
|
| 113 |
|
| 114 |
== Changelog ==
|
| 115 |
|
| 116 |
+
= 4.3.0 2019-10-17 =
|
| 117 |
+
* Add - For WooCommerce Subscriptions optimize the payment flow for subsequent subscription payments when authentication may be required by using the `setup_future_usage` parameter for the first subscription payment
|
| 118 |
+
* Add - Allow customer to authenticate payment even if they are not charged right away for WooCommerce Subscriptions and Pre-Orders, for example for a WooCommerce Subscription that has a free trial
|
| 119 |
+
* Add - When an off-session payment requires authentication, create a link for customers to come back to the store to authenticate the payment
|
| 120 |
+
* Add - Send an email to WooCommerce Subscription and Pre-Orders customers who need to authenticate a payment that was automatically tried on their behalf
|
| 121 |
+
* Add - When an off-session payment requires authentication, send an email to the admin
|
| 122 |
+
* Add - Admin notice about SCA-readiness
|
| 123 |
+
* Fix - Avoid idempotency key errors for Pre-Orders
|
| 124 |
+
* Fix - Use unique anchor for link about checkout styling changes
|
| 125 |
+
|
| 126 |
= 4.2.5 - 2019-10-02 =
|
| 127 |
* Fix - WooCommerce Subscriptions that use only the Stripe customer ID can again be renewed
|
| 128 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 129 |
[See changelog for all versions](https://raw.githubusercontent.com/woocommerce/woocommerce-gateway-stripe/master/changelog.txt).
|
| 130 |
|
| 131 |
== Upgrade Notice ==
|
|
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
| 3 |
+
exit; // Exit if accessed directly
|
| 4 |
+
}
|
| 5 |
+
?>
|
| 6 |
+
|
| 7 |
+
<?php do_action( 'woocommerce_email_header', $email_heading, $email ); ?>
|
| 8 |
+
|
| 9 |
+
<?php
|
| 10 |
+
$pre_wc_30 = version_compare( WC_VERSION, '3.0', '<' );
|
| 11 |
+
$billing_email = $pre_wc_30 ? $order->billing_email : $order->get_billing_email();
|
| 12 |
+
$billing_phone = $pre_wc_30 ? $order->billing_phone : $order->get_billing_phone();
|
| 13 |
+
|
| 14 |
+
?>
|
| 15 |
+
<p><?php
|
| 16 |
+
echo wp_kses(
|
| 17 |
+
sprintf(
|
| 18 |
+
// translators: %s is a link to the payment re-authentication URL.
|
| 19 |
+
_x( 'Your pre-order is now available, but payment cannot be completed automatically. %s', 'In failed SCA authentication for a pre-order.', 'woocommerce-gateway-stripe' ),
|
| 20 |
+
'<a href="' . esc_url( $authorization_url ) . '">' . esc_html__( 'Authorize the payment now »', 'woocommerce-gateway-stripe' ) . '</a>'
|
| 21 |
+
),
|
| 22 |
+
array( 'a' => array( 'href' => true ) )
|
| 23 |
+
);
|
| 24 |
+
?></p>
|
| 25 |
+
|
| 26 |
+
<?php if ( $email->get_custom_message() ) : ?>
|
| 27 |
+
<blockquote><?php echo wpautop( wptexturize( $email->get_custom_message() ) ); ?></blockquote>
|
| 28 |
+
<?php endif; ?>
|
| 29 |
+
|
| 30 |
+
<?php
|
| 31 |
+
do_action( 'woocommerce_email_before_order_table', $order, false, $plain_text, $email );
|
| 32 |
+
|
| 33 |
+
/*
|
| 34 |
+
* @hooked WC_Emails::order_details() Shows the order details table.
|
| 35 |
+
* @hooked WC_Structured_Data::generate_order_data() Generates structured data.
|
| 36 |
+
* @hooked WC_Structured_Data::output_structured_data() Outputs structured data.
|
| 37 |
+
* @since 2.5.0
|
| 38 |
+
*/
|
| 39 |
+
do_action( 'woocommerce_email_order_details', $order, $sent_to_admin, $plain_text, $email );
|
| 40 |
+
|
| 41 |
+
/*
|
| 42 |
+
* @hooked WC_Emails::order_meta() Shows order meta data.
|
| 43 |
+
*/
|
| 44 |
+
do_action( 'woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text, $email );
|
| 45 |
+
|
| 46 |
+
do_action( 'woocommerce_email_after_order_table', $order, false, $plain_text, $email );
|
| 47 |
+
|
| 48 |
+
/*
|
| 49 |
+
* @hooked WC_Emails::customer_details() Shows customer details
|
| 50 |
+
* @hooked WC_Emails::email_address() Shows email address
|
| 51 |
+
*/
|
| 52 |
+
do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email );
|
| 53 |
+
|
| 54 |
+
?>
|
| 55 |
+
<p>
|
| 56 |
+
<?php esc_html_e( 'Thanks for shopping with us.', 'woocommerce-gateway-stripe' ); ?>
|
| 57 |
+
</p>
|
| 58 |
+
<?php
|
| 59 |
+
|
| 60 |
+
/*
|
| 61 |
+
* @hooked WC_Emails::email_footer() Output the email footer
|
| 62 |
+
*/
|
| 63 |
+
do_action( 'woocommerce_email_footer', $email );
|
|
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
/**
|
| 3 |
+
* Admin email about payment retry failed due to authentication
|
| 4 |
+
*
|
| 5 |
+
* @package WooCommerce_Stripe/Templates/Emails
|
| 6 |
+
* @version 4.3.0
|
| 7 |
+
*/
|
| 8 |
+
|
| 9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
| 10 |
+
exit;
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
/**
|
| 14 |
+
* Output the email header.
|
| 15 |
+
*/
|
| 16 |
+
do_action( 'woocommerce_email_header', $email_heading, $email ); ?>
|
| 17 |
+
|
| 18 |
+
<p>
|
| 19 |
+
<?php
|
| 20 |
+
echo esc_html(
|
| 21 |
+
sprintf(
|
| 22 |
+
// translators: %1$s: an order number, %2$s: the customer's full name, %3$s: lowercase human time diff in the form returned by wcs_get_human_time_diff(), e.g. 'in 12 hours'.
|
| 23 |
+
_x(
|
| 24 |
+
'The automatic recurring payment for order %1$s from %2$s has failed. The customer was sent an email requesting authentication of payment. If the customer does not authenticate the payment, they will be requested by email again %3$s.',
|
| 25 |
+
'In admin renewal failed email',
|
| 26 |
+
'woocommerce-gateway-stripe'
|
| 27 |
+
),
|
| 28 |
+
$order->get_order_number(),
|
| 29 |
+
$order->get_formatted_billing_full_name(),
|
| 30 |
+
wcs_get_human_time_diff( $retry->get_time() )
|
| 31 |
+
)
|
| 32 |
+
);
|
| 33 |
+
?>
|
| 34 |
+
</p>
|
| 35 |
+
<p><?php esc_html_e( 'The renewal order is as follows:', 'woocommerce-gateway-stripe' ); ?></p>
|
| 36 |
+
|
| 37 |
+
<?php
|
| 38 |
+
|
| 39 |
+
/**
|
| 40 |
+
* Shows the order details table.
|
| 41 |
+
*/
|
| 42 |
+
do_action( 'woocommerce_email_order_details', $order, $sent_to_admin, $plain_text, $email );
|
| 43 |
+
|
| 44 |
+
/**
|
| 45 |
+
* Shows order meta data.
|
| 46 |
+
*/
|
| 47 |
+
do_action( 'woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text, $email );
|
| 48 |
+
|
| 49 |
+
/**
|
| 50 |
+
* Shows customer details, and email address.
|
| 51 |
+
*/
|
| 52 |
+
do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email );
|
| 53 |
+
|
| 54 |
+
/**
|
| 55 |
+
* Output the email footer.
|
| 56 |
+
*/
|
| 57 |
+
do_action( 'woocommerce_email_footer', $email );
|
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
| 3 |
+
exit; // Exit if accessed directly
|
| 4 |
+
}
|
| 5 |
+
?>
|
| 6 |
+
|
| 7 |
+
<?php do_action( 'woocommerce_email_header', $email_heading, $email ); ?>
|
| 8 |
+
|
| 9 |
+
<p>
|
| 10 |
+
<?php
|
| 11 |
+
// translators: %1$s: name of the blog, %2$s: link to payment re-authentication URL, note: no full stop due to url at the end
|
| 12 |
+
echo wp_kses( sprintf( _x( 'The automatic payment to renew your subscription with %1$s has failed. To reactivate the subscription, please login and authorize the renewal from your account page: %2$s', 'In failed renewal authentication email', 'woocommerce-gateway-stripe' ), esc_html( get_bloginfo( 'name' ) ), '<a href="' . esc_url( $authorization_url ) . '">' . esc_html__( 'Authorize the payment »', 'woocommerce-gateway-stripe' ) . '</a>' ), array( 'a' => array( 'href' => true ) ) ); ?>
|
| 13 |
+
</p>
|
| 14 |
+
|
| 15 |
+
<?php do_action( 'woocommerce_subscriptions_email_order_details', $order, $sent_to_admin, $plain_text, $email ); ?>
|
| 16 |
+
|
| 17 |
+
<?php do_action( 'woocommerce_email_footer', $email ); ?>
|
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
| 3 |
+
exit; // Exit if accessed directly
|
| 4 |
+
}
|
| 5 |
+
|
| 6 |
+
echo $email_heading . "\n\n";
|
| 7 |
+
|
| 8 |
+
printf(
|
| 9 |
+
// translators: %s is a link to the payment re-authentication URL.
|
| 10 |
+
_x( 'Your pre-order is now available, but payment cannot be completed automatically. Please complete the payment now: %s', 'woocommerce-gateway-stripe' ),
|
| 11 |
+
$authorization_url
|
| 12 |
+
);
|
| 13 |
+
|
| 14 |
+
if ( $email->get_custom_message() ) :
|
| 15 |
+
|
| 16 |
+
echo "----------\n\n";
|
| 17 |
+
echo wptexturize( $email->get_custom_message() ) . "\n\n";
|
| 18 |
+
echo "----------\n\n";
|
| 19 |
+
|
| 20 |
+
endif;
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
echo "\n\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n";
|
| 24 |
+
|
| 25 |
+
do_action( 'woocommerce_subscriptions_email_order_details', $order, $sent_to_admin, $plain_text, $email );
|
| 26 |
+
|
| 27 |
+
echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n";
|
| 28 |
+
|
| 29 |
+
echo apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) );
|
|
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
/**
|
| 3 |
+
* Admin email about payment retry failed due to authentication
|
| 4 |
+
*
|
| 5 |
+
* @package WooCommerce_Stripe/Templates/Emails
|
| 6 |
+
* @version 4.3.0
|
| 7 |
+
*/
|
| 8 |
+
|
| 9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
| 10 |
+
exit;
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
echo '= ' . $email_heading . " =\n\n";
|
| 14 |
+
|
| 15 |
+
printf(
|
| 16 |
+
// translators: %1$s: an order number, %2$s: the customer's full name, %3$s: lowercase human time diff in the form returned by wcs_get_human_time_diff(), e.g. 'in 12 hours'.
|
| 17 |
+
_x(
|
| 18 |
+
'The automatic recurring payment for order %1$s from %2$s has failed. The customer was sent an email requesting authentication of payment. If the customer does not authenticate the payment, they will be requested by email again %3$s.',
|
| 19 |
+
'In admin renewal failed email',
|
| 20 |
+
'woocommerce-gateway-stripe'
|
| 21 |
+
),
|
| 22 |
+
$order->get_order_number(),
|
| 23 |
+
$order->get_formatted_billing_full_name(),
|
| 24 |
+
wcs_get_human_time_diff( $retry->get_time() )
|
| 25 |
+
) . "\n\n";
|
| 26 |
+
printf( __( 'The renewal order is as follows:', 'woocommerce-gateway-stripe' ) ) . "\n\n";
|
| 27 |
+
|
| 28 |
+
echo "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n";
|
| 29 |
+
|
| 30 |
+
/**
|
| 31 |
+
* Shows the order details table.
|
| 32 |
+
*/
|
| 33 |
+
do_action( 'woocommerce_email_order_details', $order, $sent_to_admin, $plain_text, $email );
|
| 34 |
+
|
| 35 |
+
echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n";
|
| 36 |
+
|
| 37 |
+
/**
|
| 38 |
+
* Shows order meta data.
|
| 39 |
+
*/
|
| 40 |
+
do_action( 'woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text, $email );
|
| 41 |
+
|
| 42 |
+
/**
|
| 43 |
+
* Shows customer details, and email address.
|
| 44 |
+
*/
|
| 45 |
+
do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email );
|
| 46 |
+
|
| 47 |
+
echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n";
|
| 48 |
+
|
| 49 |
+
echo apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) );
|
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
| 3 |
+
exit; // Exit if accessed directly
|
| 4 |
+
}
|
| 5 |
+
|
| 6 |
+
echo $email_heading . "\n\n";
|
| 7 |
+
|
| 8 |
+
// translators: %1$s: name of the blog, %2$s: link to checkout payment url, note: no full stop due to url at the end
|
| 9 |
+
printf( esc_html_x( 'The automatic payment to renew your subscription with %1$s has failed. To reactivate the subscription, please login and authorize the renewal from your account page: %2$s', 'In failed renewal authentication email', 'woocommerce-gateway-stripe' ), esc_html( get_bloginfo( 'name' ) ), esc_attr( $authorization_url ) );
|
| 10 |
+
|
| 11 |
+
echo "\n\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n";
|
| 12 |
+
|
| 13 |
+
do_action( 'woocommerce_subscriptions_email_order_details', $order, $sent_to_admin, $plain_text, $email );
|
| 14 |
+
|
| 15 |
+
echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n";
|
| 16 |
+
|
| 17 |
+
echo apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) );
|
|
@@ -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.
|
| 9 |
* Requires at least: 4.4
|
| 10 |
-
* Tested up to: 5.2.
|
| 11 |
* WC requires at least: 2.6
|
| 12 |
-
* WC tested up to: 3.7
|
| 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.
|
| 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__ );
|
|
@@ -145,6 +145,9 @@ function woocommerce_gateway_stripe_init() {
|
|
| 145 |
add_filter( 'woocommerce_payment_gateways', array( $this, 'add_gateways' ) );
|
| 146 |
add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( $this, 'plugin_action_links' ) );
|
| 147 |
|
|
|
|
|
|
|
|
|
|
| 148 |
if ( version_compare( WC_VERSION, '3.4', '<' ) ) {
|
| 149 |
add_filter( 'woocommerce_get_sections_checkout', array( $this, 'filter_gateway_order_admin' ) );
|
| 150 |
}
|
|
@@ -256,6 +259,26 @@ function woocommerce_gateway_stripe_init() {
|
|
| 256 |
|
| 257 |
return $sections;
|
| 258 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 259 |
}
|
| 260 |
|
| 261 |
WC_Stripe::get_instance();
|
| 5 |
* Description: Take credit card payments on your store using Stripe.
|
| 6 |
* Author: WooCommerce
|
| 7 |
* Author URI: https://woocommerce.com/
|
| 8 |
+
* Version: 4.3.0
|
| 9 |
* Requires at least: 4.4
|
| 10 |
+
* Tested up to: 5.2.4
|
| 11 |
* WC requires at least: 2.6
|
| 12 |
+
* WC tested up to: 3.7.1
|
| 13 |
* Text Domain: woocommerce-gateway-stripe
|
| 14 |
* Domain Path: /languages
|
| 15 |
*
|
| 46 |
/**
|
| 47 |
* Required minimums and constants
|
| 48 |
*/
|
| 49 |
+
define( 'WC_STRIPE_VERSION', '4.3.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__ );
|
| 145 |
add_filter( 'woocommerce_payment_gateways', array( $this, 'add_gateways' ) );
|
| 146 |
add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( $this, 'plugin_action_links' ) );
|
| 147 |
|
| 148 |
+
// Modify emails emails.
|
| 149 |
+
add_filter( 'woocommerce_email_classes', array( $this, 'add_emails' ), 20 );
|
| 150 |
+
|
| 151 |
if ( version_compare( WC_VERSION, '3.4', '<' ) ) {
|
| 152 |
add_filter( 'woocommerce_get_sections_checkout', array( $this, 'filter_gateway_order_admin' ) );
|
| 153 |
}
|
| 259 |
|
| 260 |
return $sections;
|
| 261 |
}
|
| 262 |
+
|
| 263 |
+
/**
|
| 264 |
+
* Adds the failed SCA auth email to WooCommerce.
|
| 265 |
+
*
|
| 266 |
+
* @param WC_Email[] $email_classes All existing emails.
|
| 267 |
+
* @return WC_Email[]
|
| 268 |
+
*/
|
| 269 |
+
public function add_emails( $email_classes ) {
|
| 270 |
+
require_once WC_STRIPE_PLUGIN_PATH . '/includes/compat/class-wc-stripe-email-failed-authentication.php';
|
| 271 |
+
require_once WC_STRIPE_PLUGIN_PATH . '/includes/compat/class-wc-stripe-email-failed-renewal-authentication.php';
|
| 272 |
+
require_once WC_STRIPE_PLUGIN_PATH . '/includes/compat/class-wc-stripe-email-failed-preorder-authentication.php';
|
| 273 |
+
require_once WC_STRIPE_PLUGIN_PATH . '/includes/compat/class-wc-stripe-email-failed-authentication-retry.php';
|
| 274 |
+
|
| 275 |
+
// Add all emails, generated by the gateway.
|
| 276 |
+
$email_classes['WC_Stripe_Email_Failed_Renewal_Authentication'] = new WC_Stripe_Email_Failed_Renewal_Authentication( $email_classes );
|
| 277 |
+
$email_classes['WC_Stripe_Email_Failed_Preorder_Authentication'] = new WC_Stripe_Email_Failed_Preorder_Authentication( $email_classes );
|
| 278 |
+
$email_classes['WC_Stripe_Email_Failed_Authentication_Retry'] = new WC_Stripe_Email_Failed_Authentication_Retry( $email_classes );
|
| 279 |
+
|
| 280 |
+
return $email_classes;
|
| 281 |
+
}
|
| 282 |
}
|
| 283 |
|
| 284 |
WC_Stripe::get_instance();
|
