WooCommerce Stripe Payment Gateway - Version 4.3.2

Version Description

2020-02-17 = * Fix - Add compatibility to payment request buttons with some of the WooCommerce Product Add-ons on the product page * Fix - Improved compatibility for free orders with other extensions * Add - Support for multisite when sites use different Stripe accounts * Fix - Display a localized error message when a customer tries to save a card during checkout, but there's an error * Add - Send level 3 credit card data for purchases when possible

Download this release

Release Info

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

Code changes from version 4.3.1 to 4.3.2

assets/js/stripe-payment-request.js CHANGED
@@ -58,7 +58,7 @@ jQuery( function( $ ) {
58
  'count' : count,
59
  'chosenCount': chosen,
60
  'data' : data
61
- };
62
  },
63
 
64
  processSource: function( source, paymentRequestType ) {
@@ -269,6 +269,23 @@ jQuery( function( $ ) {
269
  attributes: $( '.variations_form' ).length ? wc_stripe_payment_request.getAttributes().data : []
270
  };
271
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
272
  return $.ajax( {
273
  type: 'POST',
274
  data: data,
@@ -372,7 +389,7 @@ jQuery( function( $ ) {
372
  }
373
  } );
374
 
375
- $( document.body ).on( 'woocommerce_variation_has_changed', function() {
376
  $( '#wc-stripe-payment-request-button' ).block( { message: null } );
377
 
378
  $.when( wc_stripe_payment_request.getSelectedProductData() ).then( function( response ) {
@@ -428,7 +445,7 @@ jQuery( function( $ ) {
428
  if ( 'fail' === response.result ) {
429
  evt.updateWith( { status: 'fail' } );
430
  }
431
- } );
432
  } );
433
 
434
  paymentRequest.on( 'source', function( evt ) {
@@ -455,11 +472,15 @@ jQuery( function( $ ) {
455
  product_id = $( '.single_variation_wrap' ).find( 'input[name="product_id"]' ).val();
456
  }
457
 
 
 
 
458
  var data = {
459
  security: wc_stripe_payment_request_params.nonce.get_selected_product_data,
460
  product_id: product_id,
461
  qty: $( '.quantity .qty' ).val(),
462
- attributes: $( '.variations_form' ).length ? wc_stripe_payment_request.getAttributes().data : []
 
463
  };
464
 
465
  return $.ajax( {
58
  'count' : count,
59
  'chosenCount': chosen,
60
  'data' : data
61
+ };
62
  },
63
 
64
  processSource: function( source, paymentRequestType ) {
269
  attributes: $( '.variations_form' ).length ? wc_stripe_payment_request.getAttributes().data : []
270
  };
271
 
272
+ // add addons data to the POST body
273
+ var formData = $( 'form.cart' ).serializeArray();
274
+ $.each( formData, function( i, field ) {
275
+ if ( /^addon-/.test( field.name ) ) {
276
+ if ( /\[\]$/.test( field.name ) ) {
277
+ var fieldName = field.name.substring( 0, field.name.length - 2);
278
+ if ( data[ fieldName ] ) {
279
+ data[ fieldName ].push( field.value );
280
+ } else {
281
+ data[ fieldName ] = [ field.value ];
282
+ }
283
+ } else {
284
+ data[ field.name ] = field.value;
285
+ }
286
+ }
287
+ } );
288
+
289
  return $.ajax( {
290
  type: 'POST',
291
  data: data,
389
  }
390
  } );
391
 
392
+ $( document.body ).on( 'woocommerce_variation_has_changed updated_addons', function() {
393
  $( '#wc-stripe-payment-request-button' ).block( { message: null } );
394
 
395
  $.when( wc_stripe_payment_request.getSelectedProductData() ).then( function( response ) {
445
  if ( 'fail' === response.result ) {
446
  evt.updateWith( { status: 'fail' } );
447
  }
448
+ } );
449
  } );
450
 
451
  paymentRequest.on( 'source', function( evt ) {
472
  product_id = $( '.single_variation_wrap' ).find( 'input[name="product_id"]' ).val();
473
  }
474
 
475
+ var addons = $( '#product-addons-total' ).data('price_data') || [];
476
+ var addon_value = addons.reduce( function ( sum, addon ) { return sum + addon.cost; }, 0 );
477
+
478
  var data = {
479
  security: wc_stripe_payment_request_params.nonce.get_selected_product_data,
480
  product_id: product_id,
481
  qty: $( '.quantity .qty' ).val(),
482
+ attributes: $( '.variations_form' ).length ? wc_stripe_payment_request.getAttributes().data : [],
483
+ addon_value: addon_value,
484
  };
485
 
486
  return $.ajax( {
assets/js/stripe-payment-request.min.js CHANGED
@@ -1 +1 @@
1
- jQuery(function(i){"use strict";var s,p=Stripe(wc_stripe_payment_request_params.stripe.key),o={getAjaxURL:function(t){return wc_stripe_payment_request_params.ajax_url.toString().replace("%%endpoint%%","wc_stripe_"+t)},getCartDetails:function(){var t={security:wc_stripe_payment_request_params.nonce.payment};i.ajax({type:"POST",data:t,url:o.getAjaxURL("get_cart_details"),success:function(t){o.startPaymentRequest(t)}})},getAttributes:function(){var t=i(".variations_form").find(".variations select"),a={},n=0,r=0;return t.each(function(){var t=i(this).data("attribute_name")||i(this).attr("name"),e=i(this).val()||"";0<e.length&&r++,n++,a[t]=e}),{count:n,chosenCount:r,data:a}},processSource:function(t,e){var a=o.getOrderData(t,e);return i.ajax({type:"POST",data:a,dataType:"json",url:o.getAjaxURL("create_order")})},getOrderData:function(t,e){var a=t.source,n=a.owner.email,r=a.owner.phone,i=a.owner.address,s=a.owner.name,p=t.shippingAddress,o={_wpnonce:wc_stripe_payment_request_params.nonce.checkout,billing_first_name:null!==s?s.split(" ").slice(0,1).join(" "):"",billing_last_name:null!==s?s.split(" ").slice(1).join(" "):"",billing_company:"",billing_email:null!==n?n:t.payerEmail,billing_phone:null!==r?r:t.payerPhone.replace("/[() -]/g",""),billing_country:null!==i?i.country:"",billing_address_1:null!==i?i.line1:"",billing_address_2:null!==i?i.line2:"",billing_city:null!==i?i.city:"",billing_state:null!==i?i.state:"",billing_postcode:null!==i?i.postal_code:"",shipping_first_name:"",shipping_last_name:"",shipping_company:"",shipping_country:"",shipping_address_1:"",shipping_address_2:"",shipping_city:"",shipping_state:"",shipping_postcode:"",shipping_method:[null===t.shippingOption?null:t.shippingOption.id],order_comments:"",payment_method:"stripe",ship_to_different_address:1,terms:1,stripe_source:a.id,payment_request_type:e};return p&&(o.shipping_first_name=p.recipient.split(" ").slice(0,1).join(" "),o.shipping_last_name=p.recipient.split(" ").slice(1).join(" "),o.shipping_company=p.organization,o.shipping_country=p.country,o.shipping_address_1=void 0===p.addressLine[0]?"":p.addressLine[0],o.shipping_address_2=void 0===p.addressLine[1]?"":p.addressLine[1],o.shipping_city=p.city,o.shipping_state=p.region,o.shipping_postcode=p.postalCode),o},getErrorMessageHTML:function(t){return i('<div class="woocommerce-error" />').text(t)},abortPayment:function(t,e){if(t.complete("fail"),i(".woocommerce-error").remove(),wc_stripe_payment_request_params.is_product_page){var a=i(".product");a.before(e),i("html, body").animate({scrollTop:a.prev(".woocommerce-error").offset().top},600)}else{var n=i(".shop_table.cart").closest("form");n.before(e),i("html, body").animate({scrollTop:n.prev(".woocommerce-error").offset().top},600)}},completePayment:function(t,e){o.block(),t.complete("success"),window.location=e},block:function(){i.blockUI({message:null,overlayCSS:{background:"#fff",opacity:.6}})},updateShippingOptions:function(t,e){var a={security:wc_stripe_payment_request_params.nonce.shipping,country:e.country,state:e.region,postcode:e.postalCode,city:e.city,address:void 0===e.addressLine[0]?"":e.addressLine[0],address_2:void 0===e.addressLine[1]?"":e.addressLine[1],payment_request_type:s};return i.ajax({type:"POST",data:a,url:o.getAjaxURL("get_shipping_options")})},updateShippingDetails:function(t,e){var a={security:wc_stripe_payment_request_params.nonce.update_shipping,shipping_method:[e.id],payment_request_type:s};return i.ajax({type:"POST",data:a,url:o.getAjaxURL("update_shipping_method")})},addToCart:function(){var t=i(".single_add_to_cart_button").val();i(".single_variation_wrap").length&&(t=i(".single_variation_wrap").find('input[name="product_id"]').val());var e={security:wc_stripe_payment_request_params.nonce.add_to_cart,product_id:t,qty:i(".quantity .qty").val(),attributes:i(".variations_form").length?o.getAttributes().data:[]};return i.ajax({type:"POST",data:e,url:o.getAjaxURL("add_to_cart")})},clearCart:function(){var t={security:wc_stripe_payment_request_params.nonce.clear_cart};return i.ajax({type:"POST",data:t,url:o.getAjaxURL("clear_cart"),success:function(t){}})},getRequestOptionsFromLocal:function(){return{total:wc_stripe_payment_request_params.product.total,currency:wc_stripe_payment_request_params.checkout.currency_code,country:wc_stripe_payment_request_params.checkout.country_code,requestPayerName:!0,requestPayerEmail:!0,requestPayerPhone:!0,requestShipping:wc_stripe_payment_request_params.product.requestShipping,displayItems:wc_stripe_payment_request_params.product.displayItems}},startPaymentRequest:function(t){var a,e;a=wc_stripe_payment_request_params.is_product_page?e=o.getRequestOptionsFromLocal():(e={total:t.order_data.total,currency:t.order_data.currency,country:t.order_data.country_code,requestPayerName:!0,requestPayerEmail:!0,requestPayerPhone:!0,requestShipping:!!t.shipping_required,displayItems:t.order_data.displayItems},t.order_data);var n=p.paymentRequest(e),r=p.elements({locale:wc_stripe_payment_request_params.button.locale}).create("paymentRequestButton",{paymentRequest:n,style:{paymentRequestButton:{type:wc_stripe_payment_request_params.button.type,theme:wc_stripe_payment_request_params.button.theme,height:wc_stripe_payment_request_params.button.height+"px"}}});n.canMakePayment().then(function(t){var e=[];if(t){if(s=t.applePay?"apple_pay":"payment_request_api",wc_stripe_payment_request_params.is_product_page){var a=i(".single_add_to_cart_button");r.on("click",function(t){a.is(".disabled")?(t.preventDefault(),a.is(".wc-variation-is-unavailable")?window.alert(wc_add_to_cart_variation_params.i18n_unavailable_text):a.is(".wc-variation-selection-needed")&&window.alert(wc_add_to_cart_variation_params.i18n_make_a_selection_text)):0<e.length?(t.preventDefault(),window.alert(e)):o.addToCart()}),i(document.body).on("woocommerce_variation_has_changed",function(){i("#wc-stripe-payment-request-button").block({message:null}),i.when(o.getSelectedProductData()).then(function(t){i.when(n.update({total:t.total,displayItems:t.displayItems})).then(function(){i("#wc-stripe-payment-request-button").unblock()})})}),i(".quantity").on("keyup",".qty",function(){i("#wc-stripe-payment-request-button").block({message:null}),e=[],i.when(o.getSelectedProductData()).then(function(t){t.error?(e=[t.error],i("#wc-stripe-payment-request-button").unblock()):i.when(n.update({total:t.total,displayItems:t.displayItems})).then(function(){i("#wc-stripe-payment-request-button").unblock()})})})}i("#wc-stripe-payment-request-button").length&&(i("#wc-stripe-payment-request-wrapper, #wc-stripe-payment-request-button-separator").show(),r.mount("#wc-stripe-payment-request-button"))}}),n.on("shippingaddresschange",function(e){i.when(o.updateShippingOptions(a,e.shippingAddress)).then(function(t){e.updateWith({status:t.result,shippingOptions:t.shipping_options,total:t.total,displayItems:t.displayItems})})}),n.on("shippingoptionchange",function(e){i.when(o.updateShippingDetails(a,e.shippingOption)).then(function(t){"success"===t.result&&e.updateWith({status:"success",total:t.total,displayItems:t.displayItems}),"fail"===t.result&&e.updateWith({status:"fail"})})}),n.on("source",function(e){"no"===wc_stripe_payment_request_params.stripe.allow_prepaid_card&&"prepaid"===e.source.card.funding?o.abortPayment(e,o.getErrorMessageHTML(wc_stripe_payment_request_params.i18n.no_prepaid_card)):i.when(o.processSource(e,s)).then(function(t){"success"===t.result?o.completePayment(e,t.redirect):o.abortPayment(e,t.messages)})})},getSelectedProductData:function(){var t=i(".single_add_to_cart_button").val();i(".single_variation_wrap").length&&(t=i(".single_variation_wrap").find('input[name="product_id"]').val());var e={security:wc_stripe_payment_request_params.nonce.get_selected_product_data,product_id:t,qty:i(".quantity .qty").val(),attributes:i(".variations_form").length?o.getAttributes().data:[]};return i.ajax({type:"POST",data:e,url:o.getAjaxURL("get_selected_product_data")})},init:function(){wc_stripe_payment_request_params.is_product_page?o.startPaymentRequest(""):o.getCartDetails()}};o.init(),i(document.body).on("updated_cart_totals",function(){o.init()}),i(document.body).on("updated_checkout",function(){o.init()})});
1
+ jQuery(function(i){"use strict";var s,p=Stripe(wc_stripe_payment_request_params.stripe.key),o={getAjaxURL:function(t){return wc_stripe_payment_request_params.ajax_url.toString().replace("%%endpoint%%","wc_stripe_"+t)},getCartDetails:function(){var t={security:wc_stripe_payment_request_params.nonce.payment};i.ajax({type:"POST",data:t,url:o.getAjaxURL("get_cart_details"),success:function(t){o.startPaymentRequest(t)}})},getAttributes:function(){var t=i(".variations_form").find(".variations select"),a={},n=0,r=0;return t.each(function(){var t=i(this).data("attribute_name")||i(this).attr("name"),e=i(this).val()||"";0<e.length&&r++,n++,a[t]=e}),{count:n,chosenCount:r,data:a}},processSource:function(t,e){var a=o.getOrderData(t,e);return i.ajax({type:"POST",data:a,dataType:"json",url:o.getAjaxURL("create_order")})},getOrderData:function(t,e){var a=t.source,n=a.owner.email,r=a.owner.phone,i=a.owner.address,s=a.owner.name,p=t.shippingAddress,o={_wpnonce:wc_stripe_payment_request_params.nonce.checkout,billing_first_name:null!==s?s.split(" ").slice(0,1).join(" "):"",billing_last_name:null!==s?s.split(" ").slice(1).join(" "):"",billing_company:"",billing_email:null!==n?n:t.payerEmail,billing_phone:null!==r?r:t.payerPhone.replace("/[() -]/g",""),billing_country:null!==i?i.country:"",billing_address_1:null!==i?i.line1:"",billing_address_2:null!==i?i.line2:"",billing_city:null!==i?i.city:"",billing_state:null!==i?i.state:"",billing_postcode:null!==i?i.postal_code:"",shipping_first_name:"",shipping_last_name:"",shipping_company:"",shipping_country:"",shipping_address_1:"",shipping_address_2:"",shipping_city:"",shipping_state:"",shipping_postcode:"",shipping_method:[null===t.shippingOption?null:t.shippingOption.id],order_comments:"",payment_method:"stripe",ship_to_different_address:1,terms:1,stripe_source:a.id,payment_request_type:e};return p&&(o.shipping_first_name=p.recipient.split(" ").slice(0,1).join(" "),o.shipping_last_name=p.recipient.split(" ").slice(1).join(" "),o.shipping_company=p.organization,o.shipping_country=p.country,o.shipping_address_1=void 0===p.addressLine[0]?"":p.addressLine[0],o.shipping_address_2=void 0===p.addressLine[1]?"":p.addressLine[1],o.shipping_city=p.city,o.shipping_state=p.region,o.shipping_postcode=p.postalCode),o},getErrorMessageHTML:function(t){return i('<div class="woocommerce-error" />').text(t)},abortPayment:function(t,e){if(t.complete("fail"),i(".woocommerce-error").remove(),wc_stripe_payment_request_params.is_product_page){var a=i(".product");a.before(e),i("html, body").animate({scrollTop:a.prev(".woocommerce-error").offset().top},600)}else{var n=i(".shop_table.cart").closest("form");n.before(e),i("html, body").animate({scrollTop:n.prev(".woocommerce-error").offset().top},600)}},completePayment:function(t,e){o.block(),t.complete("success"),window.location=e},block:function(){i.blockUI({message:null,overlayCSS:{background:"#fff",opacity:.6}})},updateShippingOptions:function(t,e){var a={security:wc_stripe_payment_request_params.nonce.shipping,country:e.country,state:e.region,postcode:e.postalCode,city:e.city,address:void 0===e.addressLine[0]?"":e.addressLine[0],address_2:void 0===e.addressLine[1]?"":e.addressLine[1],payment_request_type:s};return i.ajax({type:"POST",data:a,url:o.getAjaxURL("get_shipping_options")})},updateShippingDetails:function(t,e){var a={security:wc_stripe_payment_request_params.nonce.update_shipping,shipping_method:[e.id],payment_request_type:s};return i.ajax({type:"POST",data:a,url:o.getAjaxURL("update_shipping_method")})},addToCart:function(){var t=i(".single_add_to_cart_button").val();i(".single_variation_wrap").length&&(t=i(".single_variation_wrap").find('input[name="product_id"]').val());var n={security:wc_stripe_payment_request_params.nonce.add_to_cart,product_id:t,qty:i(".quantity .qty").val(),attributes:i(".variations_form").length?o.getAttributes().data:[]},e=i("form.cart").serializeArray();return i.each(e,function(t,e){if(/^addon-/.test(e.name))if(/\[\]$/.test(e.name)){var a=e.name.substring(0,e.name.length-2);n[a]?n[a].push(e.value):n[a]=[e.value]}else n[e.name]=e.value}),i.ajax({type:"POST",data:n,url:o.getAjaxURL("add_to_cart")})},clearCart:function(){var t={security:wc_stripe_payment_request_params.nonce.clear_cart};return i.ajax({type:"POST",data:t,url:o.getAjaxURL("clear_cart"),success:function(t){}})},getRequestOptionsFromLocal:function(){return{total:wc_stripe_payment_request_params.product.total,currency:wc_stripe_payment_request_params.checkout.currency_code,country:wc_stripe_payment_request_params.checkout.country_code,requestPayerName:!0,requestPayerEmail:!0,requestPayerPhone:!0,requestShipping:wc_stripe_payment_request_params.product.requestShipping,displayItems:wc_stripe_payment_request_params.product.displayItems}},startPaymentRequest:function(t){var a,e;a=wc_stripe_payment_request_params.is_product_page?e=o.getRequestOptionsFromLocal():(e={total:t.order_data.total,currency:t.order_data.currency,country:t.order_data.country_code,requestPayerName:!0,requestPayerEmail:!0,requestPayerPhone:!0,requestShipping:!!t.shipping_required,displayItems:t.order_data.displayItems},t.order_data);var n=p.paymentRequest(e),r=p.elements({locale:wc_stripe_payment_request_params.button.locale}).create("paymentRequestButton",{paymentRequest:n,style:{paymentRequestButton:{type:wc_stripe_payment_request_params.button.type,theme:wc_stripe_payment_request_params.button.theme,height:wc_stripe_payment_request_params.button.height+"px"}}});n.canMakePayment().then(function(t){var e=[];if(t){if(s=t.applePay?"apple_pay":"payment_request_api",wc_stripe_payment_request_params.is_product_page){var a=i(".single_add_to_cart_button");r.on("click",function(t){a.is(".disabled")?(t.preventDefault(),a.is(".wc-variation-is-unavailable")?window.alert(wc_add_to_cart_variation_params.i18n_unavailable_text):a.is(".wc-variation-selection-needed")&&window.alert(wc_add_to_cart_variation_params.i18n_make_a_selection_text)):0<e.length?(t.preventDefault(),window.alert(e)):o.addToCart()}),i(document.body).on("woocommerce_variation_has_changed updated_addons",function(){i("#wc-stripe-payment-request-button").block({message:null}),i.when(o.getSelectedProductData()).then(function(t){i.when(n.update({total:t.total,displayItems:t.displayItems})).then(function(){i("#wc-stripe-payment-request-button").unblock()})})}),i(".quantity").on("keyup",".qty",function(){i("#wc-stripe-payment-request-button").block({message:null}),e=[],i.when(o.getSelectedProductData()).then(function(t){t.error?(e=[t.error],i("#wc-stripe-payment-request-button").unblock()):i.when(n.update({total:t.total,displayItems:t.displayItems})).then(function(){i("#wc-stripe-payment-request-button").unblock()})})})}i("#wc-stripe-payment-request-button").length&&(i("#wc-stripe-payment-request-wrapper, #wc-stripe-payment-request-button-separator").show(),r.mount("#wc-stripe-payment-request-button"))}}),n.on("shippingaddresschange",function(e){i.when(o.updateShippingOptions(a,e.shippingAddress)).then(function(t){e.updateWith({status:t.result,shippingOptions:t.shipping_options,total:t.total,displayItems:t.displayItems})})}),n.on("shippingoptionchange",function(e){i.when(o.updateShippingDetails(a,e.shippingOption)).then(function(t){"success"===t.result&&e.updateWith({status:"success",total:t.total,displayItems:t.displayItems}),"fail"===t.result&&e.updateWith({status:"fail"})})}),n.on("source",function(e){"no"===wc_stripe_payment_request_params.stripe.allow_prepaid_card&&"prepaid"===e.source.card.funding?o.abortPayment(e,o.getErrorMessageHTML(wc_stripe_payment_request_params.i18n.no_prepaid_card)):i.when(o.processSource(e,s)).then(function(t){"success"===t.result?o.completePayment(e,t.redirect):o.abortPayment(e,t.messages)})})},getSelectedProductData:function(){var t=i(".single_add_to_cart_button").val();i(".single_variation_wrap").length&&(t=i(".single_variation_wrap").find('input[name="product_id"]').val());var e=(i("#product-addons-total").data("price_data")||[]).reduce(function(t,e){return t+e.cost},0),a={security:wc_stripe_payment_request_params.nonce.get_selected_product_data,product_id:t,qty:i(".quantity .qty").val(),attributes:i(".variations_form").length?o.getAttributes().data:[],addon_value:e};return i.ajax({type:"POST",data:a,url:o.getAjaxURL("get_selected_product_data")})},init:function(){wc_stripe_payment_request_params.is_product_page?o.startPaymentRequest(""):o.getCartDetails()}};o.init(),i(document.body).on("updated_cart_totals",function(){o.init()}),i(document.body).on("updated_checkout",function(){o.init()})});
assets/js/stripe.js CHANGED
@@ -249,6 +249,9 @@ jQuery( function( $ ) {
249
  this.onSepaError
250
  );
251
 
 
 
 
252
  wc_stripe_form.createElements();
253
 
254
  // Listen for hash changes in order to handle payment intents
@@ -788,7 +791,33 @@ jQuery( function( $ ) {
788
  // Report back to the server.
789
  $.get( redirectURL + '&is_ajax' );
790
  } );
791
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
792
  };
793
 
794
  wc_stripe_form.init();
249
  this.onSepaError
250
  );
251
 
252
+ // Subscription early renewals modal.
253
+ $( '#early_renewal_modal_submit' ).on( 'click', this.onEarlyRenewalSubmit );
254
+
255
  wc_stripe_form.createElements();
256
 
257
  // Listen for hash changes in order to handle payment intents
791
  // Report back to the server.
792
  $.get( redirectURL + '&is_ajax' );
793
  } );
794
+ },
795
+
796
+ /**
797
+ * Prevents the standard behavior of the "Renew Now" button in the
798
+ * early renewals modal by using AJAX instead of a simple redirect.
799
+ *
800
+ * @param {Event} e The event that occured.
801
+ */
802
+ onEarlyRenewalSubmit: function( e ) {
803
+ e.preventDefault();
804
+
805
+ $.ajax( {
806
+ url: $( '#early_renewal_modal_submit' ).attr( 'href' ),
807
+ method: 'get',
808
+ success: function( html ) {
809
+ var response = $.parseJSON( html );
810
+
811
+ if ( response.stripe_sca_required ) {
812
+ wc_stripe_form.openIntentModal( response.intent_secret, response.redirect_url, true, false );
813
+ } else {
814
+ window.location = response.redirect_url;
815
+ }
816
+ },
817
+ } );
818
+
819
+ return false;
820
+ },
821
  };
822
 
823
  wc_stripe_form.init();
assets/js/stripe.min.js CHANGED
@@ -1 +1 @@
1
- jQuery(function(c){"use strict";try{var o=Stripe(wc_stripe_params.key)}catch(e){return void console.log(e)}var t,n,i,e=Object.keys(wc_stripe_params.elements_options).length?wc_stripe_params.elements_options:{},r=Object.keys(wc_stripe_params.sepa_elements_options).length?wc_stripe_params.sepa_elements_options:{},s=o.elements(e),a=s.create("iban",r),m={getAjaxURL:function(e){return wc_stripe_params.ajaxurl.toString().replace("%%endpoint%%","wc_stripe_"+e)},unmountElements:function(){"yes"===wc_stripe_params.inline_cc_form?t.unmount("#stripe-card-element"):(t.unmount("#stripe-card-element"),n.unmount("#stripe-exp-element"),i.unmount("#stripe-cvc-element"))},mountElements:function(){if(c("#stripe-card-element").length){if("yes"===wc_stripe_params.inline_cc_form)return t.mount("#stripe-card-element");t.mount("#stripe-card-element"),n.mount("#stripe-exp-element"),i.mount("#stripe-cvc-element")}},createElements:function(){var e={base:{iconColor:"#666EE8",color:"#31325F",fontSize:"15px","::placeholder":{color:"#CFD7E0"}}},r={focus:"focused",empty:"empty",invalid:"invalid"};e=wc_stripe_params.elements_styling?wc_stripe_params.elements_styling:e,r=wc_stripe_params.elements_classes?wc_stripe_params.elements_classes:r,"yes"===wc_stripe_params.inline_cc_form?(t=s.create("card",{style:e,hidePostalCode:!0})).addEventListener("change",function(e){m.onCCFormChange(),e.error&&c(document.body).trigger("stripeError",e)}):(t=s.create("cardNumber",{style:e,classes:r}),n=s.create("cardExpiry",{style:e,classes:r}),i=s.create("cardCvc",{style:e,classes:r}),t.addEventListener("change",function(e){m.onCCFormChange(),m.updateCardBrand(e.brand),e.error&&c(document.body).trigger("stripeError",e)}),n.addEventListener("change",function(e){m.onCCFormChange(),e.error&&c(document.body).trigger("stripeError",e)}),i.addEventListener("change",function(e){m.onCCFormChange(),e.error&&c(document.body).trigger("stripeError",e)})),"yes"===wc_stripe_params.is_checkout?c(document.body).on("updated_checkout",function(){c("#stripe-card-element").children().length||(t&&m.unmountElements(),m.mountElements(),c("#stripe-iban-element").length&&a.mount("#stripe-iban-element"))}):(c("form#add_payment_method").length||c("form#order_review").length)&&(m.mountElements(),c("#stripe-iban-element").length&&a.mount("#stripe-iban-element"))},updateCardBrand:function(e){var r={visa:"stripe-visa-brand",mastercard:"stripe-mastercard-brand",amex:"stripe-amex-brand",discover:"stripe-discover-brand",diners:"stripe-diners-brand",jcb:"stripe-jcb-brand",unknown:"stripe-credit-card-brand"},t=c(".stripe-card-brand"),n="stripe-credit-card-brand";e in r&&(n=r[e]),c.each(r,function(e,r){t.removeClass(r)}),t.addClass(n)},init:function(){"yes"!==wc_stripe_params.is_change_payment_page&&"yes"!==wc_stripe_params.is_pay_for_order_page||c(document.body).trigger("wc-credit-card-form-init"),c("form.woocommerce-checkout").length&&(this.form=c("form.woocommerce-checkout")),c("form.woocommerce-checkout").on("checkout_place_order_stripe checkout_place_order_stripe_bancontact checkout_place_order_stripe_sofort checkout_place_order_stripe_giropay checkout_place_order_stripe_ideal checkout_place_order_stripe_alipay checkout_place_order_stripe_sepa",this.onSubmit),c("form#order_review").length&&(this.form=c("form#order_review")),c("form#order_review, form#add_payment_method").on("submit",this.onSubmit),c("form#add_payment_method").length&&(this.form=c("form#add_payment_method")),c("form.woocommerce-checkout").on("change",this.reset),c(document).on("stripeError",this.onError).on("checkout_error",this.reset),a.on("change",this.onSepaError),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
+ 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:{},a=o.elements(e),s=a.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=a.create("card",{style:e,hidePostalCode:!0})).addEventListener("change",function(e){m.onCCFormChange(),e.error&&c(document.body).trigger("stripeError",e)}):(t=a.create("cardNumber",{style:e,classes:r}),n=a.create("cardExpiry",{style:e,classes:r}),i=a.create("cardCvc",{style:e,classes:r}),t.addEventListener("change",function(e){m.onCCFormChange(),m.updateCardBrand(e.brand),e.error&&c(document.body).trigger("stripeError",e)}),n.addEventListener("change",function(e){m.onCCFormChange(),e.error&&c(document.body).trigger("stripeError",e)}),i.addEventListener("change",function(e){m.onCCFormChange(),e.error&&c(document.body).trigger("stripeError",e)})),"yes"===wc_stripe_params.is_checkout?c(document.body).on("updated_checkout",function(){c("#stripe-card-element").children().length||(t&&m.unmountElements(),m.mountElements(),c("#stripe-iban-element").length&&s.mount("#stripe-iban-element"))}):(c("form#add_payment_method").length||c("form#order_review").length)&&(m.mountElements(),c("#stripe-iban-element").length&&s.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),s.on("change",this.onSepaError),c("#early_renewal_modal_submit").on("click",this.onEarlyRenewalSubmit),m.createElements(),window.addEventListener("hashchange",m.onHashChange),m.maybeConfirmIntent()},isStripeChosen:function(){return c("#payment_method_stripe, #payment_method_stripe_bancontact, #payment_method_stripe_sofort, #payment_method_stripe_giropay, #payment_method_stripe_ideal, #payment_method_stripe_alipay, #payment_method_stripe_sepa, #payment_method_stripe_eps, #payment_method_stripe_multibanco").is(":checked")||c("#payment_method_stripe").is(":checked")&&"new"===c('input[name="wc-stripe-payment-token"]:checked').val()||c("#payment_method_stripe_sepa").is(":checked")&&"new"===c('input[name="wc-stripe-payment-token"]:checked').val()},isStripeSaveCardChosen:function(){return c("#payment_method_stripe").is(":checked")&&c('input[name="wc-stripe-payment-token"]').is(":checked")&&"new"!==c('input[name="wc-stripe-payment-token"]:checked').val()||c("#payment_method_stripe_sepa").is(":checked")&&c('input[name="wc-stripe_sepa-payment-token"]').is(":checked")&&"new"!==c('input[name="wc-stripe_sepa-payment-token"]:checked').val()},isStripeCardChosen:function(){return c("#payment_method_stripe").is(":checked")},isBancontactChosen:function(){return c("#payment_method_stripe_bancontact").is(":checked")},isGiropayChosen:function(){return c("#payment_method_stripe_giropay").is(":checked")},isIdealChosen:function(){return c("#payment_method_stripe_ideal").is(":checked")},isSofortChosen:function(){return c("#payment_method_stripe_sofort").is(":checked")},isAlipayChosen:function(){return c("#payment_method_stripe_alipay").is(":checked")},isSepaChosen:function(){return c("#payment_method_stripe_sepa").is(":checked")},isP24Chosen:function(){return c("#payment_method_stripe_p24").is(":checked")},isEpsChosen:function(){return c("#payment_method_stripe_eps").is(":checked")},isMultibancoChosen:function(){return c("#payment_method_stripe_multibanco").is(":checked")},hasSource:function(){return 0<c("input.stripe-source").length},isMobile:function(){return!!/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)},block:function(){m.isMobile()||m.form.block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},unblock:function(){m.form&&m.form.unblock()},getSelectedPaymentElement:function(){return c('.payment_methods input[name="payment_method"]:checked')},getOwnerDetails:function(){var e=c("#billing_first_name").length?c("#billing_first_name").val():wc_stripe_params.billing_first_name,r=c("#billing_last_name").length?c("#billing_last_name").val():wc_stripe_params.billing_last_name,t={name:"",address:{},email:"",phone:""};return t.name=e,t.name=e&&r?e+" "+r:c("#stripe-payment-data").data("full-name"),t.email=c("#billing_email").val(),t.phone=c("#billing_phone").val(),(void 0===t.phone||t.phone.length<=0)&&delete t.phone,(void 0===t.email||t.email.length<=0)&&(c("#stripe-payment-data").data("email").length?t.email=c("#stripe-payment-data").data("email"):delete t.email),(void 0===t.name||t.name.length<=0)&&delete t.name,t.address.line1=c("#billing_address_1").val()||wc_stripe_params.billing_address_1,t.address.line2=c("#billing_address_2").val()||wc_stripe_params.billing_address_2,t.address.state=c("#billing_state").val()||wc_stripe_params.billing_state,t.address.city=c("#billing_city").val()||wc_stripe_params.billing_city,t.address.postal_code=c("#billing_postcode").val()||wc_stripe_params.billing_postcode,t.address.country=c("#billing_country").val()||wc_stripe_params.billing_country,{owner:t}},createSource:function(){var e=m.getOwnerDetails();return m.isSepaChosen()?(e.currency=c("#stripe-sepa_debit-payment-data").data("currency"),e.mandate={notification_method:wc_stripe_params.sepa_mandate_notification},e.type="sepa_debit",o.createSource(s,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 a=i.filter(":checked");t=a.closest(".woocommerce-SavedPaymentMethods-new").length?c("#wc-stripe-cc-form .stripe-source-errors"):a.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 s='<ul class="woocommerce-error"><li /></ul>';return s.find("li").text(wc_stripe_params[r.error.code]),m.submitError(s)}"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")})},onEarlyRenewalSubmit:function(e){return e.preventDefault(),c.ajax({url:c("#early_renewal_modal_submit").attr("href"),method:"get",success:function(e){var r=c.parseJSON(e);r.stripe_sca_required?m.openIntentModal(r.intent_secret,r.redirect_url,!0,!1):window.location=r.redirect_url}}),!1}};m.init()});
changelog.txt CHANGED
@@ -1,5 +1,12 @@
1
  *** Changelog ***
2
 
 
 
 
 
 
 
 
3
  = 4.3.1 2019-11-12 =
4
  * Fix - Overwrite the previous Apple Pay verification file if it has changed.
5
  * Fix - Avoid re-mounting card elements if they are already mounted in the DOM.
1
  *** Changelog ***
2
 
3
+ = 4.3.2 2020-02-17 =
4
+ * Fix - Add compatibility to payment request buttons with some of the WooCommerce Product Add-ons on the product page
5
+ * Fix - Improved compatibility for free orders with other extensions
6
+ * Add - Support for multisite when sites use different Stripe accounts
7
+ * Fix - Display a localized error message when a customer tries to save a card during checkout, but there's an error
8
+ * Add - Send level 3 credit card data for purchases when possible
9
+
10
  = 4.3.1 2019-11-12 =
11
  * Fix - Overwrite the previous Apple Pay verification file if it has changed.
12
  * Fix - Avoid re-mounting card elements if they are already mounted in the DOM.
includes/abstracts/abstract-wc-stripe-payment-gateway.php CHANGED
@@ -254,7 +254,7 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
254
  * @version 4.0.0
255
  */
256
  public function get_stripe_customer_id( $order ) {
257
- $customer = get_user_meta( WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $order->customer_user : $order->get_customer_id(), '_stripe_customer_id', true );
258
 
259
  if ( empty( $customer ) ) {
260
  // Try to get it via the order.
@@ -291,10 +291,10 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
291
  'order_id' => $order_id,
292
  );
293
 
294
- return esc_url_raw( add_query_arg( $args, $this->get_return_url( $order ) ) );
295
  }
296
 
297
- return esc_url_raw( add_query_arg( array( 'utm_nooverride' => '1' ), $this->get_return_url() ) );
298
  }
299
 
300
  /**
@@ -606,7 +606,7 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
606
  $response = $customer->add_source( $source_object->id );
607
 
608
  if ( ! empty( $response->error ) ) {
609
- throw new WC_Stripe_Exception( print_r( $response, true ), $response->error->message );
610
  }
611
  }
612
  } elseif ( $this->is_using_saved_payment_method() ) {
@@ -1055,6 +1055,66 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
1055
  return apply_filters( 'wc_stripe_generate_create_intent_request', $request, $order, $prepared_source );
1056
  }
1057
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1058
  /**
1059
  * Create a new PaymentIntent.
1060
  *
@@ -1108,7 +1168,13 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
1108
  return $intent;
1109
  }
1110
 
1111
- return WC_Stripe_API::request( $request, "payment_intents/$intent->id" );
 
 
 
 
 
 
1112
  }
1113
 
1114
  /**
@@ -1130,7 +1196,13 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
1130
  'source' => $prepared_source->source,
1131
  );
1132
 
1133
- $confirmed_intent = WC_Stripe_API::request( $confirm_request, "payment_intents/$intent->id/confirm" );
 
 
 
 
 
 
1134
 
1135
  if ( ! empty( $confirmed_intent->error ) ) {
1136
  return $confirmed_intent;
@@ -1315,7 +1387,13 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
1315
  $request['source'] = $full_request['source'];
1316
  }
1317
 
1318
- $intent = WC_Stripe_API::request( $request, 'payment_intents' );
 
 
 
 
 
 
1319
  $is_authentication_required = $this->is_authentication_required_for_payment( $intent );
1320
 
1321
  if ( ! empty( $intent->error ) && ! $is_authentication_required ) {
@@ -1338,4 +1416,14 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
1338
 
1339
  return $intent;
1340
  }
 
 
 
 
 
 
 
 
 
 
1341
  }
254
  * @version 4.0.0
255
  */
256
  public function get_stripe_customer_id( $order ) {
257
+ $customer = get_user_option( '_stripe_customer_id', WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $order->customer_user : $order->get_customer_id() );
258
 
259
  if ( empty( $customer ) ) {
260
  // Try to get it via the order.
291
  'order_id' => $order_id,
292
  );
293
 
294
+ return wp_sanitize_redirect( esc_url_raw( add_query_arg( $args, $this->get_return_url( $order ) ) ) );
295
  }
296
 
297
+ return wp_sanitize_redirect( esc_url_raw( add_query_arg( array( 'utm_nooverride' => '1' ), $this->get_return_url() ) ) );
298
  }
299
 
300
  /**
606
  $response = $customer->add_source( $source_object->id );
607
 
608
  if ( ! empty( $response->error ) ) {
609
+ throw new WC_Stripe_Exception( print_r( $response, true ), $this->get_localized_error_message_from_response( $response ) );
610
  }
611
  }
612
  } elseif ( $this->is_using_saved_payment_method() ) {
1055
  return apply_filters( 'wc_stripe_generate_create_intent_request', $request, $order, $prepared_source );
1056
  }
1057
 
1058
+ /**
1059
+ * Create the level 3 data array to send to Stripe when making a purchase.
1060
+ *
1061
+ * @param WC_Order $order The order that is being paid for.
1062
+ * @return array The level 3 data to send to Stripe.
1063
+ */
1064
+ public function get_level3_data_from_order( $order ) {
1065
+ // WC Versions before 3.0 don't support postcodes and are
1066
+ // incompatible with level3 data.
1067
+ if ( WC_Stripe_Helper::is_wc_lt( '3.0' ) ) {
1068
+ return array();
1069
+ }
1070
+
1071
+ // Get the order items. Don't need their keys, only their values.
1072
+ // Order item IDs are used as keys in the original order items array.
1073
+ $order_items = array_values( $order->get_items() );
1074
+ $currency = $order->get_currency();
1075
+
1076
+ $stripe_line_items = array_map(function( $item ) use ( $currency ) {
1077
+ $product_id = $item->get_variation_id()
1078
+ ? $item->get_variation_id()
1079
+ : $item->get_product_id();
1080
+ $product_description = substr( $item->get_name(), 0, 26 );
1081
+ $quantity = $item->get_quantity();
1082
+ $unit_cost = WC_Stripe_Helper::get_stripe_amount( ( $item->get_subtotal() / $quantity ), $currency );
1083
+ $tax_amount = WC_Stripe_Helper::get_stripe_amount( $item->get_total_tax(), $currency );
1084
+ $discount_amount = WC_Stripe_Helper::get_stripe_amount( $item->get_subtotal() - $item->get_total(), $currency );
1085
+
1086
+ return (object) array(
1087
+ 'product_code' => (string) $product_id, // Up to 12 characters that uniquely identify the product.
1088
+ 'product_description' => $product_description, // Up to 26 characters long describing the product.
1089
+ 'unit_cost' => $unit_cost, // Cost of the product, in cents, as a non-negative integer.
1090
+ 'quantity' => $quantity, // The number of items of this type sold, as a non-negative integer.
1091
+ 'tax_amount' => $tax_amount, // The amount of tax this item had added to it, in cents, as a non-negative integer.
1092
+ 'discount_amount' => $discount_amount, // The amount an item was discounted—if there was a sale,for example, as a non-negative integer.
1093
+ );
1094
+ }, $order_items);
1095
+
1096
+ $level3_data = array(
1097
+ 'merchant_reference' => $order->get_id(), // An alphanumeric string of up to characters in length. This unique value is assigned by the merchant to identify the order. Also known as an “Order ID”.
1098
+
1099
+ 'shipping_amount' => WC_Stripe_Helper::get_stripe_amount( $order->get_shipping_total() + $order->get_shipping_tax(), $currency), // The shipping cost, in cents, as a non-negative integer.
1100
+ 'line_items' => $stripe_line_items,
1101
+ );
1102
+
1103
+ // The customer’s U.S. shipping ZIP code.
1104
+ $shipping_address_zip = $order->get_shipping_postcode();
1105
+ if ( $this->is_valid_us_zip_code( $shipping_address_zip ) ) {
1106
+ $level3_data['shipping_address_zip'] = $shipping_address_zip;
1107
+ }
1108
+
1109
+ // The merchant’s U.S. shipping ZIP code.
1110
+ $store_postcode = get_option( 'woocommerce_store_postcode' );
1111
+ if ( $this->is_valid_us_zip_code( $store_postcode ) ) {
1112
+ $level3_data['shipping_from_zip'] = $store_postcode;
1113
+ }
1114
+
1115
+ return $level3_data;
1116
+ }
1117
+
1118
  /**
1119
  * Create a new PaymentIntent.
1120
  *
1168
  return $intent;
1169
  }
1170
 
1171
+ $level3_data = $this->get_level3_data_from_order( $order );
1172
+ return WC_Stripe_API::request_with_level3_data(
1173
+ $request,
1174
+ "payment_intents/$intent->id",
1175
+ $level3_data,
1176
+ $order
1177
+ );
1178
  }
1179
 
1180
  /**
1196
  'source' => $prepared_source->source,
1197
  );
1198
 
1199
+ $level3_data = $this->get_level3_data_from_order( $order );
1200
+ $confirmed_intent = WC_Stripe_API::request_with_level3_data(
1201
+ $confirm_request,
1202
+ "payment_intents/$intent->id/confirm",
1203
+ $level3_data,
1204
+ $order
1205
+ );
1206
 
1207
  if ( ! empty( $confirmed_intent->error ) ) {
1208
  return $confirmed_intent;
1387
  $request['source'] = $full_request['source'];
1388
  }
1389
 
1390
+ $level3_data = $this->get_level3_data_from_order( $order );
1391
+ $intent = WC_Stripe_API::request_with_level3_data(
1392
+ $request,
1393
+ 'payment_intents',
1394
+ $level3_data,
1395
+ $order
1396
+ );
1397
  $is_authentication_required = $this->is_authentication_required_for_payment( $intent );
1398
 
1399
  if ( ! empty( $intent->error ) && ! $is_authentication_required ) {
1416
 
1417
  return $intent;
1418
  }
1419
+
1420
+ /**
1421
+ * Verifies whether a certain ZIP code is valid for the US, incl. 4-digit extensions.
1422
+ *
1423
+ * @param string $zip The ZIP code to verify.
1424
+ * @return boolean
1425
+ */
1426
+ public function is_valid_us_zip_code( $zip ) {
1427
+ return ! empty( $zip ) && preg_match( '/^\d{5,5}(-\d{4,4})?$/', $zip );
1428
+ }
1429
  }
includes/admin/class-wc-stripe-admin-notices.php CHANGED
@@ -100,21 +100,22 @@ class WC_Stripe_Admin_Notices {
100
  * @version 4.0.0
101
  */
102
  public function stripe_check_environment() {
103
- $show_style_notice = get_option( 'wc_stripe_show_style_notice' );
104
- $show_ssl_notice = get_option( 'wc_stripe_show_ssl_notice' );
105
- $show_keys_notice = get_option( 'wc_stripe_show_keys_notice' );
106
- $show_3ds_notice = get_option( 'wc_stripe_show_3ds_notice' );
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'] : '';
114
- $test_secret_key = isset( $options['test_secret_key'] ) ? $options['test_secret_key'] : '';
115
- $live_pub_key = isset( $options['publishable_key'] ) ? $options['publishable_key'] : '';
116
- $live_secret_key = isset( $options['secret_key'] ) ? $options['secret_key'] : '';
117
- $three_d_secure = isset( $options['three_d_secure'] ) && 'yes' === $options['three_d_secure'];
 
118
 
119
  if ( isset( $options['enabled'] ) && 'yes' === $options['enabled'] ) {
120
  if ( empty( $show_3ds_notice ) && $three_d_secure ) {
@@ -205,6 +206,11 @@ class WC_Stripe_Admin_Notices {
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
 
@@ -301,6 +307,8 @@ class WC_Stripe_Admin_Notices {
301
  case 'sca':
302
  update_option( 'wc_stripe_show_sca_notice', 'no' );
303
  break;
 
 
304
  }
305
  }
306
  }
100
  * @version 4.0.0
101
  */
102
  public function stripe_check_environment() {
103
+ $show_style_notice = get_option( 'wc_stripe_show_style_notice' );
104
+ $show_ssl_notice = get_option( 'wc_stripe_show_ssl_notice' );
105
+ $show_keys_notice = get_option( 'wc_stripe_show_keys_notice' );
106
+ $show_3ds_notice = get_option( 'wc_stripe_show_3ds_notice' );
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
+ $changed_keys_notice = get_option( 'wc_stripe_show_changed_keys_notice' );
112
+ $options = get_option( 'woocommerce_stripe_settings' );
113
+ $testmode = ( isset( $options['testmode'] ) && 'yes' === $options['testmode'] ) ? true : false;
114
+ $test_pub_key = isset( $options['test_publishable_key'] ) ? $options['test_publishable_key'] : '';
115
+ $test_secret_key = isset( $options['test_secret_key'] ) ? $options['test_secret_key'] : '';
116
+ $live_pub_key = isset( $options['publishable_key'] ) ? $options['publishable_key'] : '';
117
+ $live_secret_key = isset( $options['secret_key'] ) ? $options['secret_key'] : '';
118
+ $three_d_secure = isset( $options['three_d_secure'] ) && 'yes' === $options['three_d_secure'];
119
 
120
  if ( isset( $options['enabled'] ) && 'yes' === $options['enabled'] ) {
121
  if ( empty( $show_3ds_notice ) && $three_d_secure ) {
206
  if ( empty( $show_sca_notice ) ) {
207
  $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 );
208
  }
209
+
210
+ if ( 'yes' === $changed_keys_notice ) {
211
+ // translators: %s is a the URL for the link.
212
+ $this->add_admin_notice( 'changed_keys', 'notice notice-warning', sprintf( __( 'The public and/or secret keys for the Stripe gateway have been changed. This might cause errors for existing customers and saved payment methods. <a href="%s" target="_blank">Click here to learn more</a>.', 'woocommerce-gateway-stripe' ), 'https://docs.woocommerce.com/document/stripe-fixing-customer-errors/' ), true );
213
+ }
214
  }
215
  }
216
 
307
  case 'sca':
308
  update_option( 'wc_stripe_show_sca_notice', 'no' );
309
  break;
310
+ case 'changed_keys':
311
+ update_option( 'wc_stripe_show_changed_keys_notice', 'no' );
312
  }
313
  }
314
  }
includes/admin/class-wc-stripe-privacy.php CHANGED
@@ -225,7 +225,7 @@ class WC_Stripe_Privacy extends WC_Abstract_Privacy {
225
  'data' => array(
226
  array(
227
  'name' => __( 'Stripe payment id', 'woocommerce-gateway-stripe' ),
228
- 'value' => get_user_meta( $user->ID, '_stripe_source_id', true ),
229
  ),
230
  array(
231
  'name' => __( 'Stripe customer id', 'woocommerce-gateway-stripe' ),
@@ -255,8 +255,8 @@ class WC_Stripe_Privacy extends WC_Abstract_Privacy {
255
  $stripe_source_id = '';
256
 
257
  if ( $user instanceof WP_User ) {
258
- $stripe_customer_id = get_user_meta( $user->ID, '_stripe_customer_id', true );
259
- $stripe_source_id = get_user_meta( $user->ID, '_stripe_source_id', true );
260
  }
261
 
262
  $items_removed = false;
@@ -264,8 +264,8 @@ class WC_Stripe_Privacy extends WC_Abstract_Privacy {
264
 
265
  if ( ! empty( $stripe_customer_id ) || ! empty( $stripe_source_id ) ) {
266
  $items_removed = true;
267
- delete_user_meta( $user->ID, '_stripe_customer_id' );
268
- delete_user_meta( $user->ID, '_stripe_source_id' );
269
  $messages[] = __( 'Stripe User Data Erased.', 'woocommerce-gateway-stripe' );
270
  }
271
 
225
  'data' => array(
226
  array(
227
  'name' => __( 'Stripe payment id', 'woocommerce-gateway-stripe' ),
228
+ 'value' => get_user_option( '_stripe_source_id', $user->ID ),
229
  ),
230
  array(
231
  'name' => __( 'Stripe customer id', 'woocommerce-gateway-stripe' ),
255
  $stripe_source_id = '';
256
 
257
  if ( $user instanceof WP_User ) {
258
+ $stripe_customer_id = get_user_option( '_stripe_customer_id', $user->ID );
259
+ $stripe_source_id = get_user_option( '_stripe_source_id', $user->ID );
260
  }
261
 
262
  $items_removed = false;
264
 
265
  if ( ! empty( $stripe_customer_id ) || ! empty( $stripe_source_id ) ) {
266
  $items_removed = true;
267
+ delete_user_option( $user->ID, '_stripe_customer_id' );
268
+ delete_user_option( $user->ID, '_stripe_source_id' );
269
  $messages[] = __( 'Stripe User Data Erased.', 'woocommerce-gateway-stripe' );
270
  }
271
 
includes/admin/stripe-eps-settings.php CHANGED
@@ -36,7 +36,7 @@ return apply_filters(
36
  'desc_tip' => true,
37
  ),
38
  'webhook' => array(
39
- 'title' => __( 'Webhook Enpoints', 'woocommerce-gateway-stripe' ),
40
  'type' => 'title',
41
  /* translators: webhook URL */
42
  'description' => $this->display_admin_settings_webhook_description(),
36
  'desc_tip' => true,
37
  ),
38
  'webhook' => array(
39
+ 'title' => __( 'Webhook Endpoints', 'woocommerce-gateway-stripe' ),
40
  'type' => 'title',
41
  /* translators: webhook URL */
42
  'description' => $this->display_admin_settings_webhook_description(),
includes/class-wc-gateway-stripe.php CHANGED
@@ -372,7 +372,16 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
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
 
@@ -511,10 +520,10 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
511
  }
512
 
513
  if ( WC_Stripe_Helper::is_wc_lt( '3.0' ) ) {
514
- delete_user_meta( $order->customer_user, '_stripe_customer_id' );
515
  delete_post_meta( $order->get_id(), '_stripe_customer_id' );
516
  } else {
517
- delete_user_meta( $order->get_customer_id(), '_stripe_customer_id' );
518
  $order->delete_meta_data( '_stripe_customer_id' );
519
  $order->save();
520
  }
@@ -532,17 +541,16 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
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
 
@@ -552,7 +560,10 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
552
  $order->payment_complete();
553
 
554
  // Return thank you page redirect.
555
- return $response;
 
 
 
556
  }
557
 
558
  /**
@@ -564,11 +575,12 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
564
  * @param bool $retry Should we retry on fail.
565
  * @param bool $force_save_source Force save the payment source.
566
  * @param mix $previous_error Any error message from previous request.
 
567
  *
568
  * @throws Exception If payment will not be accepted.
569
  * @return array|void
570
  */
571
- public function process_payment( $order_id, $retry = true, $force_save_source = false, $previous_error = false ) {
572
  try {
573
  $order = wc_get_order( $order_id );
574
 
@@ -589,7 +601,12 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
589
  $stripe_customer_id = $intent->customer;
590
  }
591
 
592
- $prepared_source = $this->prepare_source( get_current_user_id(), $force_save_source, $stripe_customer_id );
 
 
 
 
 
593
 
594
  $this->maybe_disallow_prepaid_card( $prepared_source );
595
  $this->check_source( $prepared_source );
@@ -621,7 +638,7 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
621
 
622
  // We want to retry.
623
  if ( $this->is_retryable_error( $intent->error ) ) {
624
- return $this->retry_after_error( $intent, $order, $retry, $force_save_source, $previous_error );
625
  }
626
 
627
  $this->unlock_order_payment( $order );
@@ -767,14 +784,15 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
767
  }
768
 
769
  /**
770
- * Generates a localized message for an error, adds it as a note and throws it.
771
  *
772
- * @since 4.2.0
773
- * @param stdClass $response The response from the Stripe API.
774
- * @param WC_Order $order The order to add a note to.
775
- * @throws WC_Stripe_Exception An exception with the right message.
 
776
  */
777
- public function throw_localized_message( $response, $order ) {
778
  $localized_messages = WC_Stripe_Helper::get_localized_messages();
779
 
780
  if ( 'card_error' === $response->error->type ) {
@@ -783,6 +801,20 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
783
  $localized_message = isset( $localized_messages[ $response->error->type ] ) ? $localized_messages[ $response->error->type ] : $response->error->message;
784
  }
785
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
786
  $order->add_order_note( $localized_message );
787
 
788
  throw new WC_Stripe_Exception( print_r( $response, true ), $localized_message );
@@ -796,11 +828,12 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
796
  * @param WC_Order $order An order that is being paid for.
797
  * @param bool $retry A flag that indicates whether another retry should be attempted.
798
  * @param bool $force_save_source Force save the payment source.
799
- * @param mixed $previous_error Any error message from previous request.
 
800
  * @throws WC_Stripe_Exception If the payment is not accepted.
801
  * @return array|void
802
  */
803
- public function retry_after_error( $response, $order, $retry, $force_save_source, $previous_error ) {
804
  if ( ! $retry ) {
805
  $localized_message = __( 'Sorry, we are unable to process your payment at this time. Please retry later.', 'woocommerce-gateway-stripe' );
806
  $order->add_order_note( $localized_message );
@@ -815,7 +848,7 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
815
  sleep( $this->retry_interval );
816
  $this->retry_interval++;
817
 
818
- return $this->process_payment( $order->get_id(), true, $force_save_source, $response->error, $previous_error );
819
  }
820
 
821
  /**
@@ -878,9 +911,16 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
878
 
879
  if ( 'requires_payment_method' === $intent->status && isset( $intent->last_payment_error )
880
  && 'authentication_required' === $intent->last_payment_error->code ) {
881
- $intent = WC_Stripe_API::request( array(
882
- 'payment_method' => $intent->last_payment_error->source->id,
883
- ), 'payment_intents/' . $intent->id . '/confirm' );
 
 
 
 
 
 
 
884
  if ( isset( $intent->error ) ) {
885
  throw new WC_Stripe_Exception( print_r( $intent, true ), $intent->error->message );
886
  }
@@ -1042,15 +1082,37 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
1042
  }
1043
  } else if ( 'succeeded' === $intent->status || 'requires_capture' === $intent->status ) {
1044
  // Proceed with the payment completion.
1045
- $this->process_response( end( $intent->charges->data ), $order );
1046
  } else if ( 'requires_payment_method' === $intent->status ) {
1047
  // `requires_payment_method` means that SCA got denied for the current payment method.
1048
- $this->failed_sca_auth( $order, $intent );
1049
  }
1050
 
1051
  $this->unlock_order_payment( $order );
1052
  }
1053
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1054
  /**
1055
  * Checks if the payment intent associated with an order failed and records the event.
1056
  *
@@ -1087,4 +1149,38 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
1087
  }
1088
  return $pay_url;
1089
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1090
  }
372
  * @version 4.0.0
373
  */
374
  public function payment_scripts() {
375
+ if (
376
+ ! is_product()
377
+ && ! is_cart()
378
+ && ! is_checkout()
379
+ && ! isset( $_GET['pay_for_order'] ) // wpcs: csrf ok.
380
+ && ! is_add_payment_method_page()
381
+ && ! isset( $_GET['change_payment_method'] ) // wpcs: csrf ok.
382
+ && ! ( ! empty( get_query_var( 'view-subscription' ) ) && class_exists( 'WCS_Early_Renewal_Manager' ) && WCS_Early_Renewal_Manager::is_early_renewal_via_modal_enabled() )
383
+ || ( is_order_received_page() )
384
+ ) {
385
  return;
386
  }
387
 
520
  }
521
 
522
  if ( WC_Stripe_Helper::is_wc_lt( '3.0' ) ) {
523
+ delete_user_option( $order->customer_user, '_stripe_customer_id' );
524
  delete_post_meta( $order->get_id(), '_stripe_customer_id' );
525
  } else {
526
+ delete_user_option( $order->get_customer_id(), '_stripe_customer_id' );
527
  $order->delete_meta_data( '_stripe_customer_id' );
528
  $order->save();
529
  }
541
  * @return array Redirection data for `process_payment`.
542
  */
543
  public function complete_free_order( $order, $prepared_source, $force_save_source ) {
 
 
 
 
 
544
  if ( $force_save_source ) {
545
  $intent_secret = $this->setup_intent( $order, $prepared_source );
546
 
547
  if ( ! empty( $intent_secret ) ) {
548
+ // `get_return_url()` must be called immediately before returning a value.
549
+ return array(
550
+ 'result' => 'success',
551
+ 'redirect' => $this->get_return_url( $order ),
552
+ 'setup_intent_secret' => $intent_secret,
553
+ );
554
  }
555
  }
556
 
560
  $order->payment_complete();
561
 
562
  // Return thank you page redirect.
563
+ return array(
564
+ 'result' => 'success',
565
+ 'redirect' => $this->get_return_url( $order ),
566
+ );
567
  }
568
 
569
  /**
575
  * @param bool $retry Should we retry on fail.
576
  * @param bool $force_save_source Force save the payment source.
577
  * @param mix $previous_error Any error message from previous request.
578
+ * @param bool $use_order_source Whether to use the source, which should already be attached to the order.
579
  *
580
  * @throws Exception If payment will not be accepted.
581
  * @return array|void
582
  */
583
+ public function process_payment( $order_id, $retry = true, $force_save_source = false, $previous_error = false, $use_order_source = false ) {
584
  try {
585
  $order = wc_get_order( $order_id );
586
 
601
  $stripe_customer_id = $intent->customer;
602
  }
603
 
604
+ // For some payments the source should already be present in the order.
605
+ if ( $use_order_source ) {
606
+ $prepared_source = $this->prepare_order_source( $order );
607
+ } else {
608
+ $prepared_source = $this->prepare_source( get_current_user_id(), $force_save_source, $stripe_customer_id );
609
+ }
610
 
611
  $this->maybe_disallow_prepaid_card( $prepared_source );
612
  $this->check_source( $prepared_source );
638
 
639
  // We want to retry.
640
  if ( $this->is_retryable_error( $intent->error ) ) {
641
+ return $this->retry_after_error( $intent, $order, $retry, $force_save_source, $previous_error, $use_order_source );
642
  }
643
 
644
  $this->unlock_order_payment( $order );
784
  }
785
 
786
  /**
787
+ * Generates a localized message for an error from a response.
788
  *
789
+ * @since 4.3.2
790
+ *
791
+ * @param stdClass $response The response from the Stripe API.
792
+ *
793
+ * @return string The localized error message.
794
  */
795
+ public function get_localized_error_message_from_response( $response ) {
796
  $localized_messages = WC_Stripe_Helper::get_localized_messages();
797
 
798
  if ( 'card_error' === $response->error->type ) {
801
  $localized_message = isset( $localized_messages[ $response->error->type ] ) ? $localized_messages[ $response->error->type ] : $response->error->message;
802
  }
803
 
804
+ return $localized_message;
805
+ }
806
+
807
+ /**
808
+ * Gets a localized message for an error from a response, adds it as a note to the order, and throws it.
809
+ *
810
+ * @since 4.2.0
811
+ * @param stdClass $response The response from the Stripe API.
812
+ * @param WC_Order $order The order to add a note to.
813
+ * @throws WC_Stripe_Exception An exception with the right message.
814
+ */
815
+ public function throw_localized_message( $response, $order ) {
816
+ $localized_message = $this->get_localized_error_message_from_response( $response );
817
+
818
  $order->add_order_note( $localized_message );
819
 
820
  throw new WC_Stripe_Exception( print_r( $response, true ), $localized_message );
828
  * @param WC_Order $order An order that is being paid for.
829
  * @param bool $retry A flag that indicates whether another retry should be attempted.
830
  * @param bool $force_save_source Force save the payment source.
831
+ * @param mixed $previous_error Any error message from previous request.
832
+ * @param bool $use_order_source Whether to use the source, which should already be attached to the order.
833
  * @throws WC_Stripe_Exception If the payment is not accepted.
834
  * @return array|void
835
  */
836
+ public function retry_after_error( $response, $order, $retry, $force_save_source, $previous_error, $use_order_source ) {
837
  if ( ! $retry ) {
838
  $localized_message = __( 'Sorry, we are unable to process your payment at this time. Please retry later.', 'woocommerce-gateway-stripe' );
839
  $order->add_order_note( $localized_message );
848
  sleep( $this->retry_interval );
849
  $this->retry_interval++;
850
 
851
+ return $this->process_payment( $order->get_id(), true, $force_save_source, $response->error, $previous_error, $use_order_source );
852
  }
853
 
854
  /**
911
 
912
  if ( 'requires_payment_method' === $intent->status && isset( $intent->last_payment_error )
913
  && 'authentication_required' === $intent->last_payment_error->code ) {
914
+ $level3_data = $this->get_level3_data_from_order( $order );
915
+ $intent = WC_Stripe_API::request_with_level3_data(
916
+ array(
917
+ 'payment_method' => $intent->last_payment_error->source->id,
918
+ ),
919
+ 'payment_intents/' . $intent->id . '/confirm',
920
+ $level3_data,
921
+ $order
922
+ );
923
+
924
  if ( isset( $intent->error ) ) {
925
  throw new WC_Stripe_Exception( print_r( $intent, true ), $intent->error->message );
926
  }
1082
  }
1083
  } else if ( 'succeeded' === $intent->status || 'requires_capture' === $intent->status ) {
1084
  // Proceed with the payment completion.
1085
+ $this->handle_intent_verification_success( $order, $intent );
1086
  } else if ( 'requires_payment_method' === $intent->status ) {
1087
  // `requires_payment_method` means that SCA got denied for the current payment method.
1088
+ $this->handle_intent_verification_failure( $order, $intent );
1089
  }
1090
 
1091
  $this->unlock_order_payment( $order );
1092
  }
1093
 
1094
+ /**
1095
+ * Called after an intent verification succeeds, this allows
1096
+ * specific APNs or children of this class to modify its behavior.
1097
+ *
1098
+ * @param WC_Order $order The order whose verification succeeded.
1099
+ * @param stdClass $intent The Payment Intent object.
1100
+ */
1101
+ protected function handle_intent_verification_success( $order, $intent ) {
1102
+ $this->process_response( end( $intent->charges->data ), $order );
1103
+ }
1104
+
1105
+ /**
1106
+ * Called after an intent verification fails, this allows
1107
+ * specific APNs or children of this class to modify its behavior.
1108
+ *
1109
+ * @param WC_Order $order The order whose verification failed.
1110
+ * @param stdClass $intent The Payment Intent object.
1111
+ */
1112
+ protected function handle_intent_verification_failure( $order, $intent ) {
1113
+ $this->failed_sca_auth( $order, $intent );
1114
+ }
1115
+
1116
  /**
1117
  * Checks if the payment intent associated with an order failed and records the event.
1118
  *
1149
  }
1150
  return $pay_url;
1151
  }
1152
+
1153
+ /**
1154
+ * Checks whether new keys are being entered when saving options.
1155
+ */
1156
+ public function process_admin_options() {
1157
+ // Load all old values before the new settings get saved.
1158
+ $old_publishable_key = $this->get_option( 'publishable_key' );
1159
+ $old_secret_key = $this->get_option( 'secret_key' );
1160
+ $old_test_publishable_key = $this->get_option( 'test_publishable_key' );
1161
+ $old_test_secret_key = $this->get_option( 'test_secret_key' );
1162
+
1163
+ parent::process_admin_options();
1164
+
1165
+ // Load all old values after the new settings have been saved.
1166
+ $new_publishable_key = $this->get_option( 'publishable_key' );
1167
+ $new_secret_key = $this->get_option( 'secret_key' );
1168
+ $new_test_publishable_key = $this->get_option( 'test_publishable_key' );
1169
+ $new_test_secret_key = $this->get_option( 'test_secret_key' );
1170
+
1171
+ // Checks whether a value has transitioned from a non-empty value to a new one.
1172
+ $has_changed = function( $old_value, $new_value ) {
1173
+ return ! empty( $old_value ) && ( $old_value !== $new_value );
1174
+ };
1175
+
1176
+ // Look for updates.
1177
+ if (
1178
+ $has_changed( $old_publishable_key, $new_publishable_key )
1179
+ || $has_changed( $old_secret_key, $new_secret_key )
1180
+ || $has_changed( $old_test_publishable_key, $new_test_publishable_key )
1181
+ || $has_changed( $old_test_secret_key, $new_test_secret_key )
1182
+ ) {
1183
+ update_option( 'wc_stripe_show_changed_keys_notice', 'yes' );
1184
+ }
1185
+ }
1186
  }
includes/class-wc-stripe-api.php CHANGED
@@ -176,4 +176,90 @@ class WC_Stripe_API {
176
 
177
  return json_decode( $response['body'] );
178
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
179
  }
176
 
177
  return json_decode( $response['body'] );
178
  }
179
+
180
+ /**
181
+ * Send the request to Stripe's API with level 3 data generated
182
+ * from the order. If the request fails due to an error related
183
+ * to level3 data, make the request again without it to allow
184
+ * the payment to go through.
185
+ *
186
+ * @since 4.3.2
187
+ * @version 4.3.2
188
+ *
189
+ * @param array $request Array with request parameters.
190
+ * @param string $api The API path for the request.
191
+ * @param array $level3_data The level 3 data for this request.
192
+ * @param WC_Order $order The order associated with the payment.
193
+ *
194
+ * @return stdClass|array The response
195
+ */
196
+ public static function request_with_level3_data( $request, $api, $level3_data, $order ) {
197
+ // Do not add level3 data it's the array is empty.
198
+ if ( empty( $level3_data ) ) {
199
+ return self::request(
200
+ $request,
201
+ $api
202
+ );
203
+ }
204
+
205
+ // If there's a transient indicating that level3 data was not accepted by
206
+ // Stripe in the past for this account, do not try to add level3 data.
207
+ if ( get_transient( 'wc_stripe_level3_not_allowed' ) ) {
208
+ return self::request(
209
+ $request,
210
+ $api
211
+ );
212
+ }
213
+
214
+ // Add level 3 data to the request.
215
+ $request['level3'] = $level3_data;
216
+
217
+ $result = self::request(
218
+ $request,
219
+ $api
220
+ );
221
+
222
+ $is_level3_param_not_allowed = (
223
+ isset( $result->error )
224
+ && isset( $result->error->code )
225
+ && 'parameter_unknown' === $result->error->code
226
+ && isset( $result->error->param )
227
+ && 'level3' === $result->error->param
228
+ );
229
+
230
+ $is_level_3data_incorrect = (
231
+ isset( $result->error )
232
+ && isset( $result->error->type )
233
+ && 'invalid_request_error' === $result->error->type
234
+ );
235
+
236
+ if ( $is_level3_param_not_allowed ) {
237
+ // Set a transient so that future requests do not add level 3 data.
238
+ // Transient is set to expire in 3 months, can be manually removed if needed.
239
+ set_transient( 'wc_stripe_level3_not_allowed', true, 3 * MONTH_IN_SECONDS );
240
+ } else if ( $is_level_3data_incorrect ) {
241
+ // Log the issue so we could debug it.
242
+ WC_Stripe_Logger::log(
243
+ 'Level3 data sum incorrect: ' . PHP_EOL
244
+ . print_r( $result->error->message, true ) . PHP_EOL
245
+ . print_r( 'Order line items: ', true ) . PHP_EOL
246
+ . print_r( $order->get_items(), true ) . PHP_EOL
247
+ . print_r( 'Order shipping amount: ', true ) . PHP_EOL
248
+ . print_r( $order->get_shipping_total(), true ) . PHP_EOL
249
+ . print_r( 'Order currency: ', true ) . PHP_EOL
250
+ . print_r( $order->get_currency(), true )
251
+ );
252
+ }
253
+
254
+ // Make the request again without level 3 data.
255
+ if ( $is_level3_param_not_allowed || $is_level_3data_incorrect ) {
256
+ unset( $request['level3'] );
257
+ return WC_Stripe_API::request(
258
+ $request,
259
+ $api
260
+ );
261
+ }
262
+
263
+ return $result;
264
+ }
265
  }
includes/class-wc-stripe-customer.php CHANGED
@@ -35,7 +35,7 @@ class WC_Stripe_Customer {
35
  public function __construct( $user_id = 0 ) {
36
  if ( $user_id ) {
37
  $this->set_user_id( $user_id );
38
- $this->set_id( get_user_meta( $user_id, '_stripe_customer_id', true ) );
39
  }
40
  }
41
 
@@ -56,7 +56,7 @@ class WC_Stripe_Customer {
56
  if ( is_array( $id ) && isset( $id['customer_id'] ) ) {
57
  $id = $id['customer_id'];
58
 
59
- update_user_meta( $this->get_user_id(), '_stripe_customer_id', $id );
60
  }
61
 
62
  $this->id = wc_clean( $id );
@@ -161,7 +161,7 @@ class WC_Stripe_Customer {
161
  $this->set_customer_data( $response );
162
 
163
  if ( $this->get_user_id() ) {
164
- update_user_meta( $this->get_user_id(), '_stripe_customer_id', $response->id );
165
  }
166
 
167
  do_action( 'woocommerce_stripe_add_customer', $args, $response );
@@ -175,15 +175,35 @@ class WC_Stripe_Customer {
175
  * @param array $args Additional arguments for the request (optional).
176
  */
177
  public function update_customer( $args = array() ) {
178
- if ( empty( $this->id ) ) {
179
  throw new WC_Stripe_Exception( 'id_required_to_update_user', __( 'Attempting to update a Stripe customer without a customer ID.', 'woocommerce-gateway-stripe' ) );
180
  }
181
 
182
  $args = $this->generate_customer_request( $args );
183
  $args = apply_filters( 'wc_stripe_update_customer_args', $args );
184
- $response = WC_Stripe_API::request( $args, 'customers/' . $this->id );
185
 
186
  if ( ! empty( $response->error ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
  throw new WC_Stripe_Exception( print_r( $response, true ), $response->error->message );
188
  }
189
 
@@ -232,7 +252,7 @@ class WC_Stripe_Customer {
232
  // but no longer exists. Instead of failing, lets try to create a
233
  // new customer.
234
  if ( $this->is_no_such_customer_error( $response->error ) ) {
235
- delete_user_meta( $this->get_user_id(), '_stripe_customer_id' );
236
  $this->create_customer();
237
  return $this->add_source( $source_id );
238
  } else {
@@ -374,4 +394,30 @@ class WC_Stripe_Customer {
374
  delete_transient( 'stripe_customer_' . $this->get_id() );
375
  $this->customer_data = array();
376
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
377
  }
35
  public function __construct( $user_id = 0 ) {
36
  if ( $user_id ) {
37
  $this->set_user_id( $user_id );
38
+ $this->set_id( $this->get_id_from_meta( $user_id ) );
39
  }
40
  }
41
 
56
  if ( is_array( $id ) && isset( $id['customer_id'] ) ) {
57
  $id = $id['customer_id'];
58
 
59
+ $this->update_id_in_meta( $id );
60
  }
61
 
62
  $this->id = wc_clean( $id );
161
  $this->set_customer_data( $response );
162
 
163
  if ( $this->get_user_id() ) {
164
+ $this->update_id_in_meta( $response->id );
165
  }
166
 
167
  do_action( 'woocommerce_stripe_add_customer', $args, $response );
175
  * @param array $args Additional arguments for the request (optional).
176
  */
177
  public function update_customer( $args = array() ) {
178
+ if ( empty( $this->get_id() ) ) {
179
  throw new WC_Stripe_Exception( 'id_required_to_update_user', __( 'Attempting to update a Stripe customer without a customer ID.', 'woocommerce-gateway-stripe' ) );
180
  }
181
 
182
  $args = $this->generate_customer_request( $args );
183
  $args = apply_filters( 'wc_stripe_update_customer_args', $args );
184
+ $response = WC_Stripe_API::request( $args, 'customers/' . $this->get_id() );
185
 
186
  if ( ! empty( $response->error ) ) {
187
+ if ( $this->is_no_such_customer_error( $response->error ) ) {
188
+ $message = $response->error->message;
189
+
190
+ if ( ! preg_match( '/similar object exists/i', $message ) ) {
191
+ $options = get_option( 'woocommerce_stripe_settings' );
192
+ $testmode = isset( $options['testmode'] ) && 'yes' === $options['testmode'];
193
+
194
+ $message = sprintf(
195
+ ( $testmode
196
+ // Translators: %s is a message, which states that no such customer exists, without a full stop at the end.
197
+ ? __( '%s. Was the customer created in live mode? ', 'woocommerce-gateway-stripe' )
198
+ // Translators: %s is a message, which states that no such customer exists, without a full stop at the end.
199
+ : __( '%s. Was the customer created in test mode? ', 'woocommerce-gateway-stripe' ) ),
200
+ $message
201
+ );
202
+ }
203
+
204
+ throw new WC_Stripe_Exception( print_r( $response, true ), $message );
205
+ }
206
+
207
  throw new WC_Stripe_Exception( print_r( $response, true ), $response->error->message );
208
  }
209
 
252
  // but no longer exists. Instead of failing, lets try to create a
253
  // new customer.
254
  if ( $this->is_no_such_customer_error( $response->error ) ) {
255
+ $this->delete_id_from_meta();
256
  $this->create_customer();
257
  return $this->add_source( $source_id );
258
  } else {
394
  delete_transient( 'stripe_customer_' . $this->get_id() );
395
  $this->customer_data = array();
396
  }
397
+
398
+ /**
399
+ * Retrieves the Stripe Customer ID from the user meta.
400
+ *
401
+ * @param int $user_id The ID of the WordPress user.
402
+ * @return string|bool Either the Stripe ID or false.
403
+ */
404
+ public function get_id_from_meta( $user_id ) {
405
+ return get_user_option( '_stripe_customer_id', $user_id );
406
+ }
407
+
408
+ /**
409
+ * Updates the current user with the right Stripe ID in the meta table.
410
+ *
411
+ * @param string $id The Stripe customer ID.
412
+ */
413
+ public function update_id_in_meta( $id ) {
414
+ update_user_option( $this->get_user_id(), '_stripe_customer_id', $id, false );
415
+ }
416
+
417
+ /**
418
+ * Deletes the user ID from the meta table with the right key.
419
+ */
420
+ public function delete_id_from_meta() {
421
+ delete_user_option( $this->get_user_id(), '_stripe_customer_id', false );
422
+ }
423
  }
includes/class-wc-stripe-order-handler.php CHANGED
@@ -128,10 +128,10 @@ class WC_Stripe_Order_Handler extends WC_Stripe_Payment_Gateway {
128
  // Customer param wrong? The user may have been deleted on stripe's end. Remove customer_id. Can be retried without.
129
  if ( $this->is_no_such_customer_error( $response->error ) ) {
130
  if ( WC_Stripe_Helper::is_wc_lt( '3.0' ) ) {
131
- delete_user_meta( $order->customer_user, '_stripe_customer_id' );
132
  delete_post_meta( $order_id, '_stripe_customer_id' );
133
  } else {
134
- delete_user_meta( $order->get_customer_id(), '_stripe_customer_id' );
135
  $order->delete_meta_data( '_stripe_customer_id' );
136
  $order->save();
137
  }
@@ -244,12 +244,15 @@ class WC_Stripe_Order_Handler extends WC_Stripe_Payment_Gateway {
244
  /* translators: error message */
245
  $order->add_order_note( sprintf( __( 'Unable to capture charge! %s', 'woocommerce-gateway-stripe' ), $intent->error->message ) );
246
  } elseif ( 'requires_capture' === $intent->status ) {
247
- $result = WC_Stripe_API::request(
 
248
  array(
249
  'amount' => WC_Stripe_Helper::get_stripe_amount( $order_total ),
250
  'expand[]' => 'charges.data.balance_transaction',
251
  ),
252
- 'payment_intents/' . $intent->id . '/capture'
 
 
253
  );
254
 
255
  if ( ! empty( $result->error ) ) {
@@ -272,12 +275,15 @@ class WC_Stripe_Order_Handler extends WC_Stripe_Payment_Gateway {
272
  /* translators: error message */
273
  $order->add_order_note( sprintf( __( 'Unable to capture charge! %s', 'woocommerce-gateway-stripe' ), $result->error->message ) );
274
  } elseif ( false === $result->captured ) {
275
- $result = WC_Stripe_API::request(
 
276
  array(
277
  'amount' => WC_Stripe_Helper::get_stripe_amount( $order_total ),
278
  'expand[]' => 'balance_transaction',
279
  ),
280
- 'charges/' . $charge . '/capture'
 
 
281
  );
282
 
283
  if ( ! empty( $result->error ) ) {
128
  // Customer param wrong? The user may have been deleted on stripe's end. Remove customer_id. Can be retried without.
129
  if ( $this->is_no_such_customer_error( $response->error ) ) {
130
  if ( WC_Stripe_Helper::is_wc_lt( '3.0' ) ) {
131
+ delete_user_option( $order->customer_user, '_stripe_customer_id' );
132
  delete_post_meta( $order_id, '_stripe_customer_id' );
133
  } else {
134
+ delete_user_option( $order->get_customer_id(), '_stripe_customer_id' );
135
  $order->delete_meta_data( '_stripe_customer_id' );
136
  $order->save();
137
  }
244
  /* translators: error message */
245
  $order->add_order_note( sprintf( __( 'Unable to capture charge! %s', 'woocommerce-gateway-stripe' ), $intent->error->message ) );
246
  } elseif ( 'requires_capture' === $intent->status ) {
247
+ $level3_data = $this->get_level3_data_from_order( $order );
248
+ $result = WC_Stripe_API::request_with_level3_data(
249
  array(
250
  'amount' => WC_Stripe_Helper::get_stripe_amount( $order_total ),
251
  'expand[]' => 'charges.data.balance_transaction',
252
  ),
253
+ 'payment_intents/' . $intent->id . '/capture',
254
+ $level3_data,
255
+ $order
256
  );
257
 
258
  if ( ! empty( $result->error ) ) {
275
  /* translators: error message */
276
  $order->add_order_note( sprintf( __( 'Unable to capture charge! %s', 'woocommerce-gateway-stripe' ), $result->error->message ) );
277
  } elseif ( false === $result->captured ) {
278
+ $level3_data = $this->get_level3_data_from_order( $order );
279
+ $result = WC_Stripe_API::request_with_level3_data(
280
  array(
281
  'amount' => WC_Stripe_Helper::get_stripe_amount( $order_total ),
282
  'expand[]' => 'balance_transaction',
283
  ),
284
+ 'charges/' . $charge . '/capture',
285
+ $level3_data,
286
+ $order
287
  );
288
 
289
  if ( ! empty( $result->error ) ) {
includes/class-wc-stripe-webhook-handler.php CHANGED
@@ -203,10 +203,10 @@ class WC_Stripe_Webhook_Handler extends WC_Stripe_Payment_Gateway {
203
  // Customer param wrong? The user may have been deleted on stripe's end. Remove customer_id. Can be retried without.
204
  if ( $this->is_no_such_customer_error( $response->error ) ) {
205
  if ( WC_Stripe_Helper::is_wc_lt( '3.0' ) ) {
206
- delete_user_meta( $order->customer_user, '_stripe_customer_id' );
207
  delete_post_meta( $order_id, '_stripe_customer_id' );
208
  } else {
209
- delete_user_meta( $order->get_customer_id(), '_stripe_customer_id' );
210
  $order->delete_meta_data( '_stripe_customer_id' );
211
  $order->save();
212
  }
203
  // Customer param wrong? The user may have been deleted on stripe's end. Remove customer_id. Can be retried without.
204
  if ( $this->is_no_such_customer_error( $response->error ) ) {
205
  if ( WC_Stripe_Helper::is_wc_lt( '3.0' ) ) {
206
+ delete_user_option( $order->customer_user, '_stripe_customer_id' );
207
  delete_post_meta( $order_id, '_stripe_customer_id' );
208
  } else {
209
+ delete_user_option( $order->get_customer_id(), '_stripe_customer_id' );
210
  $order->delete_meta_data( '_stripe_customer_id' );
211
  $order->save();
212
  }
includes/compat/class-wc-stripe-sepa-subs-compat.php CHANGED
@@ -102,13 +102,15 @@ class WC_Stripe_Sepa_Subs_Compat extends WC_Gateway_Stripe_Sepa {
102
  */
103
  public function handle_add_payment_method_success( $source_id, $source_object ) {
104
  if ( isset( $_POST[ 'wc-' . $this->id . '-update-subs-payment-method-card' ] ) ) {
105
- $all_subs = wcs_get_users_subscriptions();
106
- $subs_statuses = apply_filters( 'wc_stripe_update_subs_payment_method_card_statuses', array( 'active' ) );
 
107
 
108
  if ( ! empty( $all_subs ) ) {
109
  foreach ( $all_subs as $sub ) {
110
  if ( $sub->has_status( $subs_statuses ) ) {
111
  update_post_meta( $sub->get_id(), '_stripe_source_id', $source_id );
 
112
  update_post_meta( $sub->get_id(), '_payment_method', $this->id );
113
  update_post_meta( $sub->get_id(), '_payment_method_title', $this->method_title );
114
  }
@@ -435,15 +437,15 @@ class WC_Stripe_Sepa_Subs_Compat extends WC_Gateway_Stripe_Sepa {
435
  // If we couldn't find a Stripe customer linked to the subscription, fallback to the user meta data.
436
  if ( ! $stripe_customer_id || ! is_string( $stripe_customer_id ) ) {
437
  $user_id = $customer_user;
438
- $stripe_customer_id = get_user_meta( $user_id, '_stripe_customer_id', true );
439
- $stripe_source_id = get_user_meta( $user_id, '_stripe_source_id', true );
440
 
441
  // For BW compat will remove in future.
442
  if ( empty( $stripe_source_id ) ) {
443
- $stripe_source_id = get_user_meta( $user_id, '_stripe_card_id', true );
444
 
445
  // Take this opportunity to update the key name.
446
- update_user_meta( $user_id, '_stripe_source_id', $stripe_source_id );
447
  }
448
  }
449
 
102
  */
103
  public function handle_add_payment_method_success( $source_id, $source_object ) {
104
  if ( isset( $_POST[ 'wc-' . $this->id . '-update-subs-payment-method-card' ] ) ) {
105
+ $all_subs = wcs_get_users_subscriptions();
106
+ $subs_statuses = apply_filters( 'wc_stripe_update_subs_payment_method_card_statuses', array( 'active' ) );
107
+ $stripe_customer = new WC_Stripe_Customer( get_current_user_id() );
108
 
109
  if ( ! empty( $all_subs ) ) {
110
  foreach ( $all_subs as $sub ) {
111
  if ( $sub->has_status( $subs_statuses ) ) {
112
  update_post_meta( $sub->get_id(), '_stripe_source_id', $source_id );
113
+ update_post_meta( $sub->get_id(), '_stripe_customer_id', $stripe_customer->get_id() );
114
  update_post_meta( $sub->get_id(), '_payment_method', $this->id );
115
  update_post_meta( $sub->get_id(), '_payment_method_title', $this->method_title );
116
  }
437
  // If we couldn't find a Stripe customer linked to the subscription, fallback to the user meta data.
438
  if ( ! $stripe_customer_id || ! is_string( $stripe_customer_id ) ) {
439
  $user_id = $customer_user;
440
+ $stripe_customer_id = get_user_option( '_stripe_customer_id', $user_id );
441
+ $stripe_source_id = get_user_option( '_stripe_source_id', $user_id );
442
 
443
  // For BW compat will remove in future.
444
  if ( empty( $stripe_source_id ) ) {
445
+ $stripe_source_id = get_user_option( '_stripe_card_id', $user_id );
446
 
447
  // Take this opportunity to update the key name.
448
+ update_user_option( $user_id, '_stripe_source_id', $stripe_source_id, false );
449
  }
450
  }
451
 
includes/compat/class-wc-stripe-subs-compat.php CHANGED
@@ -111,13 +111,15 @@ class WC_Stripe_Subs_Compat extends WC_Gateway_Stripe {
111
  */
112
  public function handle_add_payment_method_success( $source_id, $source_object ) {
113
  if ( isset( $_POST[ 'wc-' . $this->id . '-update-subs-payment-method-card' ] ) ) {
114
- $all_subs = wcs_get_users_subscriptions();
115
- $subs_statuses = apply_filters( 'wc_stripe_update_subs_payment_method_card_statuses', array( 'active' ) );
 
116
 
117
  if ( ! empty( $all_subs ) ) {
118
  foreach ( $all_subs as $sub ) {
119
  if ( $sub->has_status( $subs_statuses ) ) {
120
  update_post_meta( $sub->get_id(), '_stripe_source_id', $source_id );
 
121
  update_post_meta( $sub->get_id(), '_payment_method', $this->id );
122
  update_post_meta( $sub->get_id(), '_payment_method_title', $this->method_title );
123
  }
@@ -159,16 +161,16 @@ class WC_Stripe_Subs_Compat extends WC_Gateway_Stripe {
159
  * @param int $order_id
160
  * @return array
161
  */
162
- public function process_payment( $order_id, $retry = true, $force_save_source = false, $previous_error = false ) {
163
  if ( $this->has_subscription( $order_id ) ) {
164
  if ( $this->is_subs_change_payment() ) {
165
  return $this->change_subs_payment_method( $order_id );
166
  }
167
 
168
  // Regular payment with force customer enabled
169
- return parent::process_payment( $order_id, $retry, true, $previous_error );
170
  } else {
171
- return parent::process_payment( $order_id, $retry, $force_save_source, $previous_error );
172
  }
173
  }
174
 
@@ -224,6 +226,37 @@ class WC_Stripe_Subs_Compat extends WC_Gateway_Stripe {
224
 
225
  $order_id = WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $renewal_order->id : $renewal_order->get_id();
226
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
  // Check for an existing intent, which is associated with the order.
228
  if ( $this->has_authentication_already_failed( $renewal_order ) ) {
229
  return;
@@ -502,15 +535,15 @@ class WC_Stripe_Subs_Compat extends WC_Gateway_Stripe {
502
  // If we couldn't find a Stripe customer linked to the subscription, fallback to the user meta data.
503
  if ( ! $stripe_customer_id || ! is_string( $stripe_customer_id ) ) {
504
  $user_id = $customer_user;
505
- $stripe_customer_id = get_user_meta( $user_id, '_stripe_customer_id', true );
506
- $stripe_source_id = get_user_meta( $user_id, '_stripe_source_id', true );
507
 
508
  // For BW compat will remove in future.
509
  if ( empty( $stripe_source_id ) ) {
510
- $stripe_source_id = get_user_meta( $user_id, '_stripe_card_id', true );
511
 
512
  // Take this opportunity to update the key name.
513
- update_user_meta( $user_id, '_stripe_source_id', $stripe_source_id );
514
  }
515
  }
516
 
@@ -614,4 +647,51 @@ class WC_Stripe_Subs_Compat extends WC_Gateway_Stripe {
614
 
615
  return true;
616
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
617
  }
111
  */
112
  public function handle_add_payment_method_success( $source_id, $source_object ) {
113
  if ( isset( $_POST[ 'wc-' . $this->id . '-update-subs-payment-method-card' ] ) ) {
114
+ $all_subs = wcs_get_users_subscriptions();
115
+ $subs_statuses = apply_filters( 'wc_stripe_update_subs_payment_method_card_statuses', array( 'active' ) );
116
+ $stripe_customer = new WC_Stripe_Customer( get_current_user_id() );
117
 
118
  if ( ! empty( $all_subs ) ) {
119
  foreach ( $all_subs as $sub ) {
120
  if ( $sub->has_status( $subs_statuses ) ) {
121
  update_post_meta( $sub->get_id(), '_stripe_source_id', $source_id );
122
+ update_post_meta( $sub->get_id(), '_stripe_customer_id', $stripe_customer->get_id() );
123
  update_post_meta( $sub->get_id(), '_payment_method', $this->id );
124
  update_post_meta( $sub->get_id(), '_payment_method_title', $this->method_title );
125
  }
161
  * @param int $order_id
162
  * @return array
163
  */
164
+ public function process_payment( $order_id, $retry = true, $force_save_source = false, $previous_error = false, $use_order_source = false ) {
165
  if ( $this->has_subscription( $order_id ) ) {
166
  if ( $this->is_subs_change_payment() ) {
167
  return $this->change_subs_payment_method( $order_id );
168
  }
169
 
170
  // Regular payment with force customer enabled
171
+ return parent::process_payment( $order_id, $retry, true, $previous_error, $use_order_source );
172
  } else {
173
+ return parent::process_payment( $order_id, $retry, $force_save_source, $previous_error, $use_order_source );
174
  }
175
  }
176
 
226
 
227
  $order_id = WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $renewal_order->id : $renewal_order->get_id();
228
 
229
+
230
+ // Unlike regular off-session subscription payments, early renewals are treated as on-session payments, involving the customer.
231
+ if ( isset( $_REQUEST['process_early_renewal'] ) ) { // wpcs: csrf ok.
232
+ $response = parent::process_payment( $order_id, true, false, $previous_error, true );
233
+
234
+ if( 'success' === $response['result'] && isset( $response['payment_intent_secret'] ) ) {
235
+ $verification_url = add_query_arg(
236
+ array(
237
+ 'order' => $order_id,
238
+ 'nonce' => wp_create_nonce( 'wc_stripe_confirm_pi' ),
239
+ 'redirect_to' => remove_query_arg( array( 'process_early_renewal', 'subscription_id', 'wcs_nonce' ) ),
240
+ 'early_renewal' => true,
241
+ ),
242
+ WC_AJAX::get_endpoint( 'wc_stripe_verify_intent' )
243
+ );
244
+
245
+ echo wp_json_encode( array(
246
+ 'stripe_sca_required' => true,
247
+ 'intent_secret' => $response['payment_intent_secret'],
248
+ 'redirect_url' => $verification_url,
249
+ ) );
250
+
251
+ exit;
252
+ }
253
+
254
+ // Hijack all other redirects in order to do the redirection in JavaScript.
255
+ add_action( 'wp_redirect', array( $this, 'redirect_after_early_renewal' ), 100 );
256
+
257
+ return;
258
+ }
259
+
260
  // Check for an existing intent, which is associated with the order.
261
  if ( $this->has_authentication_already_failed( $renewal_order ) ) {
262
  return;
535
  // If we couldn't find a Stripe customer linked to the subscription, fallback to the user meta data.
536
  if ( ! $stripe_customer_id || ! is_string( $stripe_customer_id ) ) {
537
  $user_id = $customer_user;
538
+ $stripe_customer_id = get_user_option( '_stripe_customer_id', $user_id );
539
+ $stripe_source_id = get_user_option( '_stripe_source_id', $user_id );
540
 
541
  // For BW compat will remove in future.
542
  if ( empty( $stripe_source_id ) ) {
543
+ $stripe_source_id = get_user_option( '_stripe_card_id', $user_id );
544
 
545
  // Take this opportunity to update the key name.
546
+ update_user_option( $user_id, '_stripe_source_id', $stripe_source_id, false );
547
  }
548
  }
549
 
647
 
648
  return true;
649
  }
650
+
651
+ /**
652
+ * Hijacks `wp_redirect` in order to generate a JS-friendly object with the URL.
653
+ *
654
+ * @param string $url The URL that Subscriptions attempts a redirect to.
655
+ * @return void
656
+ */
657
+ public function redirect_after_early_renewal( $url ) {
658
+ echo wp_json_encode(
659
+ array(
660
+ 'stripe_sca_required' => false,
661
+ 'redirect_url' => $url,
662
+ )
663
+ );
664
+
665
+ exit;
666
+ }
667
+
668
+ /**
669
+ * Once an intent has been verified, perform some final actions for early renewals.
670
+ *
671
+ * @param WC_Order $order The renewal order.
672
+ * @param stdClass $intent The Payment Intent object.
673
+ */
674
+ protected function handle_intent_verification_success( $order, $intent ) {
675
+ parent::handle_intent_verification_success( $order, $intent );
676
+
677
+ if ( isset( $_GET['early_renewal'] ) ) { // wpcs: csrf ok.
678
+ wcs_update_dates_after_early_renewal( wcs_get_subscription( $order->get_meta( '_subscription_renewal' ) ), $order );
679
+ wc_add_notice( __( 'Your early renewal order was successful.', 'woocommerce-gateway-stripe' ), 'success' );
680
+ }
681
+ }
682
+
683
+ /**
684
+ * During early renewals, instead of failing the renewal order, delete it and let Subs redirect to the checkout.
685
+ *
686
+ * @param WC_Order $order The renewal order.
687
+ * @param stdClass $intent The Payment Intent object (unused).
688
+ */
689
+ protected function handle_intent_verification_failure( $order, $intent ) {
690
+ if ( isset( $_GET['early_renewal'] ) ) {
691
+ $order->delete( true );
692
+ wc_add_notice( __( 'Payment authorization for the renewal order was unsuccessful, please try again.', 'woocommerce-gateway-stripe' ), 'error' );
693
+ $renewal_url = wcs_get_early_renewal_url( wcs_get_subscription( $order->get_meta( '_subscription_renewal' ) ) );
694
+ wp_redirect( $renewal_url ); exit;
695
+ }
696
+ }
697
  }
includes/payment-methods/class-wc-gateway-stripe-sepa.php CHANGED
@@ -337,10 +337,10 @@ class WC_Gateway_Stripe_Sepa extends WC_Stripe_Payment_Gateway {
337
  // Customer param wrong? The user may have been deleted on stripe's end. Remove customer_id. Can be retried without.
338
  if ( $this->is_no_such_customer_error( $response->error ) ) {
339
  if ( WC_Stripe_Helper::is_wc_lt( '3.0' ) ) {
340
- delete_user_meta( $order->customer_user, '_stripe_customer_id' );
341
  delete_post_meta( $order_id, '_stripe_customer_id' );
342
  } else {
343
- delete_user_meta( $order->get_customer_id(), '_stripe_customer_id' );
344
  $order->delete_meta_data( '_stripe_customer_id' );
345
  $order->save();
346
  }
337
  // Customer param wrong? The user may have been deleted on stripe's end. Remove customer_id. Can be retried without.
338
  if ( $this->is_no_such_customer_error( $response->error ) ) {
339
  if ( WC_Stripe_Helper::is_wc_lt( '3.0' ) ) {
340
+ delete_user_option( $order->customer_user, '_stripe_customer_id' );
341
  delete_post_meta( $order_id, '_stripe_customer_id' );
342
  } else {
343
+ delete_user_option( $order->get_customer_id(), '_stripe_customer_id' );
344
  $order->delete_meta_data( '_stripe_customer_id' );
345
  $order->save();
346
  }
includes/payment-methods/class-wc-stripe-payment-request.php CHANGED
@@ -147,14 +147,7 @@ class WC_Stripe_Payment_Request {
147
  return;
148
  }
149
 
150
- $session_class = apply_filters( 'woocommerce_session_handler', 'WC_Session_Handler' );
151
- $wc_session = new $session_class();
152
-
153
- if ( version_compare( WC_VERSION, '3.3', '>=' ) ) {
154
- $wc_session->init();
155
- }
156
-
157
- $wc_session->set_customer_session_cookie( true );
158
  }
159
 
160
  /**
@@ -467,18 +460,8 @@ class WC_Stripe_Payment_Request {
467
  return;
468
  }
469
 
470
- if ( is_product() ) {
471
- global $post;
472
-
473
- $product = wc_get_product( $post->ID );
474
-
475
- if ( ! is_object( $product ) || ! in_array( ( WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $product->product_type : $product->get_type() ), $this->supported_product_types() ) ) {
476
- return;
477
- }
478
-
479
- if ( apply_filters( 'wc_stripe_hide_payment_request_on_product_page', false, $post ) ) {
480
- return;
481
- }
482
  }
483
 
484
  $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
@@ -552,31 +535,12 @@ class WC_Stripe_Payment_Request {
552
  return;
553
  }
554
 
555
- if ( is_product() && apply_filters( 'wc_stripe_hide_payment_request_on_product_page', false, $post ) ) {
556
- return;
557
- }
558
-
559
  if ( is_checkout() && ! apply_filters( 'wc_stripe_show_payment_request_on_checkout', false, $post ) ) {
560
  return;
561
  }
562
 
563
- if ( is_product() ) {
564
- $product = wc_get_product( $post->ID );
565
-
566
- if ( ! is_object( $product ) || ! in_array( ( WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $product->product_type : $product->get_type() ), $this->supported_product_types() ) ) {
567
- return;
568
- }
569
-
570
- // Trial subscriptions with shipping are not supported
571
- if ( class_exists( 'WC_Subscriptions_Order' ) && $product->needs_shipping() && WC_Subscriptions_Product::get_trial_length( $product ) > 0 ) {
572
- return;
573
- }
574
-
575
- // Pre Orders charge upon release not supported.
576
- if ( class_exists( 'WC_Pre_Orders_Order' ) && WC_Pre_Orders_Product::product_is_charged_upon_release( $product ) ) {
577
- WC_Stripe_Logger::log( 'Pre Order charge upon release is not supported. ( Payment Request button disabled )' );
578
- return;
579
- }
580
  } else {
581
  if ( ! $this->allowed_items_in_cart() ) {
582
  WC_Stripe_Logger::log( 'Items in the cart has unsupported product type ( Payment Request button disabled )' );
@@ -611,31 +575,12 @@ class WC_Stripe_Payment_Request {
611
  return;
612
  }
613
 
614
- if ( is_product() && apply_filters( 'wc_stripe_hide_payment_request_on_product_page', false, $post ) ) {
615
- return;
616
- }
617
-
618
  if ( is_checkout() && ! apply_filters( 'wc_stripe_show_payment_request_on_checkout', false, $post ) ) {
619
  return;
620
  }
621
 
622
- if ( is_product() ) {
623
- $product = wc_get_product( $post->ID );
624
-
625
- if ( ! is_object( $product ) || ! in_array( ( WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $product->product_type : $product->get_type() ), $this->supported_product_types() ) ) {
626
- return;
627
- }
628
-
629
- // Trial subscriptions with shipping are not supported
630
- if ( class_exists( 'WC_Subscriptions_Order' ) && $product->needs_shipping() && WC_Subscriptions_Product::get_trial_length( $product ) > 0 ) {
631
- return;
632
- }
633
-
634
- // Pre Orders charge upon release not supported.
635
- if ( class_exists( 'WC_Pre_Orders_Order' ) && WC_Pre_Orders_Product::product_is_charged_upon_release( $product ) ) {
636
- WC_Stripe_Logger::log( 'Pre Order charge upon release is not supported. ( Payment Request button disabled )' );
637
- return;
638
- }
639
  } else {
640
  if ( ! $this->allowed_items_in_cart() ) {
641
  WC_Stripe_Logger::log( 'Items in the cart has unsupported product type ( Payment Request button disabled )' );
@@ -647,6 +592,52 @@ class WC_Stripe_Payment_Request {
647
  <?php
648
  }
649
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
650
  /**
651
  * Log errors coming from Payment Request
652
  *
@@ -815,6 +806,7 @@ class WC_Stripe_Payment_Request {
815
  try {
816
  $product_id = absint( $_POST['product_id'] );
817
  $qty = ! isset( $_POST['qty'] ) ? 1 : apply_filters( 'woocommerce_add_to_cart_quantity', absint( $_POST['qty'] ), $product_id );
 
818
  $product = wc_get_product( $product_id );
819
  $variation_id = null;
820
 
@@ -849,7 +841,7 @@ class WC_Stripe_Payment_Request {
849
  throw new Exception( sprintf( __( 'You cannot add that amount of "%1$s"; to the cart because there is not enough stock (%2$s remaining).', 'woocommerce-gateway-stripe' ), $product->get_name(), wc_format_stock_quantity_for_display( $product->get_stock_quantity(), $product ) ) );
850
  }
851
 
852
- $total = $qty * ( WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $product->price : $product->get_price() );
853
 
854
  $quantity_label = 1 < $qty ? ' (x' . $qty . ')' : '';
855
 
147
  return;
148
  }
149
 
150
+ WC()->session->set_customer_session_cookie( true );
 
 
 
 
 
 
 
151
  }
152
 
153
  /**
460
  return;
461
  }
462
 
463
+ if ( is_product() && ! $this->should_show_payment_button_on_product_page() ) {
464
+ return;
 
 
 
 
 
 
 
 
 
 
465
  }
466
 
467
  $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
535
  return;
536
  }
537
 
 
 
 
 
538
  if ( is_checkout() && ! apply_filters( 'wc_stripe_show_payment_request_on_checkout', false, $post ) ) {
539
  return;
540
  }
541
 
542
+ if ( is_product() && ! $this->should_show_payment_button_on_product_page() ) {
543
+ return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
544
  } else {
545
  if ( ! $this->allowed_items_in_cart() ) {
546
  WC_Stripe_Logger::log( 'Items in the cart has unsupported product type ( Payment Request button disabled )' );
575
  return;
576
  }
577
 
 
 
 
 
578
  if ( is_checkout() && ! apply_filters( 'wc_stripe_show_payment_request_on_checkout', false, $post ) ) {
579
  return;
580
  }
581
 
582
+ if ( is_product() && ! $this->should_show_payment_button_on_product_page() ) {
583
+ return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
584
  } else {
585
  if ( ! $this->allowed_items_in_cart() ) {
586
  WC_Stripe_Logger::log( 'Items in the cart has unsupported product type ( Payment Request button disabled )' );
592
  <?php
593
  }
594
 
595
+ /**
596
+ * Whether payment button html should be rendered
597
+ *
598
+ * @since 4.3.2
599
+ *
600
+ * @param object $post
601
+ *
602
+ * @return bool
603
+ */
604
+ private function should_show_payment_button_on_product_page() {
605
+ global $post;
606
+
607
+ $product = wc_get_product( $post->ID );
608
+
609
+ if ( apply_filters( 'wc_stripe_hide_payment_request_on_product_page', false, $post ) ) {
610
+ return false;
611
+ }
612
+
613
+ if ( ! is_object( $product ) || ! in_array( ( WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $product->product_type : $product->get_type() ), $this->supported_product_types() ) ) {
614
+ return false;
615
+ }
616
+
617
+ // Trial subscriptions with shipping are not supported
618
+ if ( class_exists( 'WC_Subscriptions_Order' ) && $product->needs_shipping() && WC_Subscriptions_Product::get_trial_length( $product ) > 0 ) {
619
+ return false;
620
+ }
621
+
622
+ // Pre Orders charge upon release not supported.
623
+ if ( class_exists( 'WC_Pre_Orders_Order' ) && WC_Pre_Orders_Product::product_is_charged_upon_release( $product ) ) {
624
+ WC_Stripe_Logger::log( 'Pre Order charge upon release is not supported. ( Payment Request button disabled )' );
625
+ return false;
626
+ }
627
+
628
+ // File upload addon not supported
629
+ if ( class_exists( 'WC_Product_Addons_Helper' ) ) {
630
+ $product_addons = WC_Product_Addons_Helper::get_product_addons( $product->get_id() );
631
+ foreach ( $product_addons as $addon ) {
632
+ if ( 'file_upload' === $addon['type'] ) {
633
+ return false;
634
+ }
635
+ }
636
+ }
637
+
638
+ return true;
639
+ }
640
+
641
  /**
642
  * Log errors coming from Payment Request
643
  *
806
  try {
807
  $product_id = absint( $_POST['product_id'] );
808
  $qty = ! isset( $_POST['qty'] ) ? 1 : apply_filters( 'woocommerce_add_to_cart_quantity', absint( $_POST['qty'] ), $product_id );
809
+ $addon_value = isset( $_POST['addon_value'] ) ? max( floatval( $_POST['addon_value'] ), 0 ) : 0;
810
  $product = wc_get_product( $product_id );
811
  $variation_id = null;
812
 
841
  throw new Exception( sprintf( __( 'You cannot add that amount of "%1$s"; to the cart because there is not enough stock (%2$s remaining).', 'woocommerce-gateway-stripe' ), $product->get_name(), wc_format_stock_quantity_for_display( $product->get_stock_quantity(), $product ) ) );
842
  }
843
 
844
+ $total = $qty * ( WC_Stripe_Helper::is_wc_lt( '3.0' ) ? $product->price : $product->get_price() ) + $addon_value;
845
 
846
  $quantity_label = 1 < $qty ? ' (x' . $qty . ')' : '';
847
 
languages/woocommerce-gateway-stripe.pot CHANGED
@@ -1,15 +1,15 @@
1
- # Copyright (C) 2019 WooCommerce
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: "
7
  "https://wordpress.org/support/plugin/woocommerce-gateway-stripe\n"
8
- "POT-Creation-Date: 2019-11-12 11:30:47+00:00\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=utf-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
- "PO-Revision-Date: 2019-MO-DA HO:MI+ZONE\n"
13
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
  "Language-Team: LANGUAGE <LL@li.org>\n"
15
  "X-Generator: node-wp-i18n 1.2.1\n"
@@ -29,8 +29,8 @@ msgid "Save payment information to my account for future purchases."
29
  msgstr ""
30
 
31
  #: includes/abstracts/abstract-wc-stripe-payment-gateway.php:230
32
- #: includes/compat/class-wc-stripe-sepa-subs-compat.php:216
33
- #: includes/compat/class-wc-stripe-subs-compat.php:218
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."
@@ -55,7 +55,7 @@ msgid "Stripe charge awaiting payment: %s."
55
  msgstr ""
56
 
57
  #: includes/abstracts/abstract-wc-stripe-payment-gateway.php:424
58
- #: includes/class-wc-stripe-order-handler.php:296
59
  #: includes/class-wc-stripe-webhook-handler.php:347
60
  #: includes/class-wc-stripe-webhook-handler.php:399
61
  #. translators: transaction id
@@ -63,8 +63,8 @@ msgid "Stripe charge complete (Charge ID: %s)"
63
  msgstr ""
64
 
65
  #: includes/abstracts/abstract-wc-stripe-payment-gateway.php:429
66
- #: includes/class-wc-gateway-stripe.php:495
67
- #: includes/compat/class-wc-stripe-sepa-subs-compat.php:173
68
  msgid "Payment processing failed. Please retry."
69
  msgstr ""
70
 
@@ -92,7 +92,7 @@ msgstr ""
92
  msgid "There was a problem adding the payment method."
93
  msgstr ""
94
 
95
- #: includes/admin/class-wc-stripe-admin-notices.php:124
96
  #. translators: 1) A URL that explains Stripe Radar.
97
  msgid ""
98
  "WooCommerce Stripe - We see that you had the \"Require 3D secure when "
@@ -101,7 +101,7 @@ msgid ""
101
  "href=\"%s\" target=\"_blank\">here</a>."
102
  msgstr ""
103
 
104
- #: includes/admin/class-wc-stripe-admin-notices.php:131
105
  #. translators: 1) int version 2) int version
106
  msgid ""
107
  "WooCommerce Stripe - We recently made changes to Stripe that may impact the "
@@ -111,32 +111,32 @@ msgid ""
111
  "target=\"_blank\">instructions</a> to fix."
112
  msgstr ""
113
 
114
- #: includes/admin/class-wc-stripe-admin-notices.php:141
115
  #. translators: 1) int version 2) int version
116
  msgid ""
117
  "WooCommerce Stripe - The minimum PHP version required for this plugin is "
118
  "%1$s. You are running %2$s."
119
  msgstr ""
120
 
121
- #: includes/admin/class-wc-stripe-admin-notices.php:152
122
  #. translators: 1) int version 2) int version
123
  msgid ""
124
  "WooCommerce Stripe - The minimum WooCommerce version required for this "
125
  "plugin is %1$s. You are running %2$s."
126
  msgstr ""
127
 
128
- #: includes/admin/class-wc-stripe-admin-notices.php:162
129
  msgid "WooCommerce Stripe - cURL is not installed."
130
  msgstr ""
131
 
132
- #: includes/admin/class-wc-stripe-admin-notices.php:172
133
  #. translators: 1) link
134
  msgid ""
135
  "Stripe is almost ready. To get started, <a href=\"%s\">set your Stripe "
136
  "account keys</a>."
137
  msgstr ""
138
 
139
- #: includes/admin/class-wc-stripe-admin-notices.php:183
140
  #. translators: 1) link
141
  msgid ""
142
  "Stripe is in test mode however your test keys may not be valid. Test keys "
@@ -144,7 +144,7 @@ msgid ""
144
  "<a href=\"%s\">set your Stripe account keys</a>."
145
  msgstr ""
146
 
147
- #: includes/admin/class-wc-stripe-admin-notices.php:192
148
  #. translators: 1) link
149
  msgid ""
150
  "Stripe is in live mode however your test keys may not be valid. Live keys "
@@ -152,7 +152,7 @@ msgid ""
152
  "<a href=\"%s\">set your Stripe account keys</a>."
153
  msgstr ""
154
 
155
- #: includes/admin/class-wc-stripe-admin-notices.php:201
156
  #. translators: 1) link
157
  msgid ""
158
  "Stripe is enabled, but a SSL certificate is not detected. Your checkout may "
@@ -160,22 +160,30 @@ msgid ""
160
  "target=\"_blank\">SSL certificate</a>"
161
  msgstr ""
162
 
163
- #: includes/admin/class-wc-stripe-admin-notices.php:206
164
  msgid ""
165
  "Stripe is now ready for Strong Customer Authentication (SCA) and 3D Secure "
166
  "2! <a href=\"%1$s\" target=\"_blank\">Read about SCA</a>"
167
  msgstr ""
168
 
169
- #: includes/admin/class-wc-stripe-admin-notices.php:229
 
 
 
 
 
 
 
 
170
  #. translators: %1$s Payment method, %2$s List of supported currencies
171
  msgid "%1$s is enabled - it requires store currency to be set to %2$s"
172
  msgstr ""
173
 
174
- #: includes/admin/class-wc-stripe-admin-notices.php:243
175
  msgid "Action failed. Please refresh the page and retry."
176
  msgstr ""
177
 
178
- #: includes/admin/class-wc-stripe-admin-notices.php:247
179
  msgid "Cheatin&#8217; huh?"
180
  msgstr ""
181
 
@@ -210,9 +218,9 @@ msgid "Retains any Stripe data such as Stripe customer ID, source ID."
210
  msgstr ""
211
 
212
  #: includes/admin/class-wc-stripe-privacy.php:41
213
- #: includes/compat/class-wc-stripe-sepa-subs-compat.php:463
214
- #: includes/compat/class-wc-stripe-subs-compat.php:530
215
- #: includes/compat/class-wc-stripe-subs-compat.php:545
216
  msgid "N/A"
217
  msgstr ""
218
 
@@ -380,6 +388,7 @@ msgstr ""
380
 
381
  #: includes/admin/stripe-alipay-settings.php:43
382
  #: includes/admin/stripe-bancontact-settings.php:43
 
383
  #: includes/admin/stripe-giropay-settings.php:43
384
  #: includes/admin/stripe-ideal-settings.php:43
385
  #: includes/admin/stripe-multibanco-settings.php:39
@@ -428,10 +437,6 @@ msgstr ""
428
  msgid "You will be redirected to EPS."
429
  msgstr ""
430
 
431
- #: includes/admin/stripe-eps-settings.php:39
432
- msgid "Webhook Enpoints"
433
- msgstr ""
434
-
435
  #: includes/admin/stripe-giropay-settings.php:10
436
  msgid "Relevant Payer Geography: Germany"
437
  msgstr ""
@@ -798,68 +803,68 @@ msgstr ""
798
  msgid "Card Code (CVC)"
799
  msgstr ""
800
 
801
- #: includes/class-wc-gateway-stripe.php:408
802
  msgid "Please accept the terms and conditions first"
803
  msgstr ""
804
 
805
- #: includes/class-wc-gateway-stripe.php:409
806
  msgid "Please fill in required checkout fields first"
807
  msgstr ""
808
 
809
- #: includes/class-wc-gateway-stripe.php:438
810
- #: includes/class-wc-gateway-stripe.php:482
811
  msgid ""
812
  "Sorry, we're not accepting prepaid cards at this time. Your credit card has "
813
  "not been charged. Please try with alternative payment method."
814
  msgstr ""
815
 
816
- #: includes/class-wc-gateway-stripe.php:439
817
  msgid "Please enter your IBAN account name."
818
  msgstr ""
819
 
820
- #: includes/class-wc-gateway-stripe.php:440
821
  msgid "Please enter your IBAN account number."
822
  msgstr ""
823
 
824
- #: includes/class-wc-gateway-stripe.php:441
825
  msgid "We couldn't initiate the payment. Please try again."
826
  msgstr ""
827
 
828
- #: includes/class-wc-gateway-stripe.php:452
829
  msgid "Billing First Name and Last Name are required."
830
  msgstr ""
831
 
832
- #: includes/class-wc-gateway-stripe.php:720
833
  #. translators: error message
834
  msgid "This represents the fee Stripe collects for the transaction."
835
  msgstr ""
836
 
837
- #: includes/class-wc-gateway-stripe.php:721
838
  msgid "Stripe Fee:"
839
  msgstr ""
840
 
841
- #: includes/class-wc-gateway-stripe.php:757
842
  msgid ""
843
  "This represents the net total that will be credited to your Stripe bank "
844
  "account. This may be in the currency that is set in your Stripe account."
845
  msgstr ""
846
 
847
- #: includes/class-wc-gateway-stripe.php:758
848
  msgid "Stripe Payout:"
849
  msgstr ""
850
 
851
- #: includes/class-wc-gateway-stripe.php:805
852
  #: includes/class-wc-stripe-order-handler.php:162
853
  #: includes/class-wc-stripe-webhook-handler.php:238
854
- #: includes/compat/class-wc-stripe-sepa-subs-compat.php:263
855
- #: includes/compat/class-wc-stripe-subs-compat.php:272
856
  #: includes/payment-methods/class-wc-gateway-stripe-sepa.php:373
857
  msgid ""
858
  "Sorry, we are unable to process your payment at this time. Please retry "
859
  "later."
860
  msgstr ""
861
 
862
- #: includes/class-wc-gateway-stripe.php:858
863
  msgid ""
864
  "Almost there!\n"
865
  "\n"
@@ -867,14 +872,14 @@ msgid ""
867
  "done is for you to authorize the payment with your bank."
868
  msgstr ""
869
 
870
- #: includes/class-wc-gateway-stripe.php:1070
871
  #: includes/class-wc-stripe-webhook-handler.php:685
872
  #: includes/class-wc-stripe-webhook-handler.php:724
873
  #. translators: 1) The error message that was received from Stripe.
874
  msgid "Stripe SCA authentication failed. Reason: %s"
875
  msgstr ""
876
 
877
- #: includes/class-wc-gateway-stripe.php:1071
878
  msgid "Stripe SCA authentication failed."
879
  msgstr ""
880
 
@@ -921,7 +926,19 @@ msgstr ""
921
  msgid "Attempting to update a Stripe customer without a customer ID."
922
  msgstr ""
923
 
924
- #: includes/class-wc-stripe-customer.php:242
 
 
 
 
 
 
 
 
 
 
 
 
925
  msgid "Unable to add payment source."
926
  msgstr ""
927
 
@@ -1023,9 +1040,9 @@ msgid "Stripe payment failed: %s"
1023
  msgstr ""
1024
 
1025
  #: includes/class-wc-stripe-order-handler.php:245
1026
- #: includes/class-wc-stripe-order-handler.php:257
1027
- #: includes/class-wc-stripe-order-handler.php:273
1028
- #: includes/class-wc-stripe-order-handler.php:285
1029
  #. translators: error message
1030
  msgid "Unable to capture charge! %s"
1031
  msgstr ""
@@ -1155,8 +1172,8 @@ msgid "Unable to store payment details. Please try again."
1155
  msgstr ""
1156
 
1157
  #: includes/compat/class-wc-stripe-pre-orders-compat.php:121
1158
- #: includes/compat/class-wc-stripe-subs-compat.php:304
1159
- #: includes/compat/class-wc-stripe-subs-compat.php:609
1160
  msgid "Stripe charge awaiting authentication by user: %s."
1161
  msgstr ""
1162
 
@@ -1165,52 +1182,60 @@ msgstr ""
1165
  msgid "Stripe Transaction Failed (%s)"
1166
  msgstr ""
1167
 
1168
- #: includes/compat/class-wc-stripe-sepa-subs-compat.php:88
1169
- #: includes/compat/class-wc-stripe-subs-compat.php:97
1170
- msgid ""
1171
- "Update the Payment Method used for all of my active subscriptions "
1172
- "(optional)."
1173
  msgstr ""
1174
 
1175
- #: includes/compat/class-wc-stripe-sepa-subs-compat.php:226
1176
- #: includes/compat/class-wc-stripe-subs-compat.php:233
1177
  msgid "Customer not found"
1178
  msgstr ""
1179
 
1180
- #: includes/compat/class-wc-stripe-sepa-subs-compat.php:386
1181
- #: includes/compat/class-wc-stripe-subs-compat.php:453
1182
  #. translators: error message
1183
  msgid "A \"Stripe Customer ID\" value is required."
1184
  msgstr ""
1185
 
1186
- #: includes/compat/class-wc-stripe-sepa-subs-compat.php:388
1187
- #: includes/compat/class-wc-stripe-subs-compat.php:455
1188
  msgid ""
1189
  "Invalid customer ID. A valid \"Stripe Customer ID\" must begin with "
1190
  "\"cus_\"."
1191
  msgstr ""
1192
 
1193
- #: includes/compat/class-wc-stripe-sepa-subs-compat.php:397
1194
- #: includes/compat/class-wc-stripe-subs-compat.php:464
1195
  msgid ""
1196
  "Invalid source ID. A valid source \"Stripe Source ID\" must begin with "
1197
  "\"src_\" or \"card_\"."
1198
  msgstr ""
1199
 
1200
- #: includes/compat/class-wc-stripe-sepa-subs-compat.php:470
1201
  #. translators: 1) last 4 digits of SEPA Direct Debit
1202
  msgid "Via SEPA Direct Debit ending in %1$s"
1203
  msgstr ""
1204
 
1205
- #: includes/compat/class-wc-stripe-subs-compat.php:296
1206
  msgid "This transaction requires authentication."
1207
  msgstr ""
1208
 
1209
- #: includes/compat/class-wc-stripe-subs-compat.php:545
1210
  #. translators: 1) card brand 2) last 4 digits
1211
  msgid "Via %1$s card ending in %2$s"
1212
  msgstr ""
1213
 
 
 
 
 
 
 
 
 
 
 
1214
  #: includes/payment-methods/class-wc-gateway-stripe-alipay.php:60
1215
  #: woocommerce-gateway-stripe.php:256
1216
  msgid "Stripe Alipay"
@@ -1326,57 +1351,57 @@ msgstr ""
1326
  msgid "Stripe SOFORT"
1327
  msgstr ""
1328
 
1329
- #: includes/payment-methods/class-wc-stripe-payment-request.php:261
1330
- #: includes/payment-methods/class-wc-stripe-payment-request.php:866
1331
- #: includes/payment-methods/class-wc-stripe-payment-request.php:1164
1332
  msgid "Tax"
1333
  msgstr ""
1334
 
1335
- #: includes/payment-methods/class-wc-stripe-payment-request.php:269
1336
- #: includes/payment-methods/class-wc-stripe-payment-request.php:874
1337
- #: includes/payment-methods/class-wc-stripe-payment-request.php:1171
1338
  msgid "Shipping"
1339
  msgstr ""
1340
 
1341
- #: includes/payment-methods/class-wc-stripe-payment-request.php:276
1342
- #: includes/payment-methods/class-wc-stripe-payment-request.php:881
1343
  msgid "Pending"
1344
  msgstr ""
1345
 
1346
- #: includes/payment-methods/class-wc-stripe-payment-request.php:503
1347
  msgid "Sorry, we're not accepting prepaid cards at this time."
1348
  msgstr ""
1349
 
1350
- #: includes/payment-methods/class-wc-stripe-payment-request.php:505
1351
  #. translators: Do not translate the [option] placeholder
1352
  msgid "Unknown shipping option \"[option]\"."
1353
  msgstr ""
1354
 
1355
- #: includes/payment-methods/class-wc-stripe-payment-request.php:646
1356
  msgid "OR"
1357
  msgstr ""
1358
 
1359
- #: includes/payment-methods/class-wc-stripe-payment-request.php:740
1360
- #: includes/payment-methods/class-wc-stripe-payment-request.php:753
1361
  msgid "Unable to find shipping method for address."
1362
  msgstr ""
1363
 
1364
- #: includes/payment-methods/class-wc-stripe-payment-request.php:822
1365
  msgid "Product with the ID (%d) cannot be found."
1366
  msgstr ""
1367
 
1368
- #: includes/payment-methods/class-wc-stripe-payment-request.php:849
1369
  #. translators: 1: product name 2: quantity in stock
1370
  msgid ""
1371
  "You cannot add that amount of \"%1$s\"; to the cart because there is not "
1372
  "enough stock (%2$s remaining)."
1373
  msgstr ""
1374
 
1375
- #: includes/payment-methods/class-wc-stripe-payment-request.php:1003
1376
  msgid "Empty cart"
1377
  msgstr ""
1378
 
1379
- #: includes/payment-methods/class-wc-stripe-payment-request.php:1178
1380
  msgid "Discount"
1381
  msgstr ""
1382
 
1
+ # Copyright (C) 2020 WooCommerce
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.1\n"
6
  "Report-Msgid-Bugs-To: "
7
  "https://wordpress.org/support/plugin/woocommerce-gateway-stripe\n"
8
+ "POT-Creation-Date: 2020-02-14 07:56:25+00:00\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=utf-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
+ "PO-Revision-Date: 2020-MO-DA HO:MI+ZONE\n"
13
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
  "Language-Team: LANGUAGE <LL@li.org>\n"
15
  "X-Generator: node-wp-i18n 1.2.1\n"
29
  msgstr ""
30
 
31
  #: includes/abstracts/abstract-wc-stripe-payment-gateway.php:230
32
+ #: includes/compat/class-wc-stripe-sepa-subs-compat.php:222
33
+ #: includes/compat/class-wc-stripe-subs-compat.php:224
34
  #. translators: 1) dollar amount
35
  #. translators: minimum amount
36
  msgid "Sorry, the minimum allowed order total is %1$s to use this payment method."
55
  msgstr ""
56
 
57
  #: includes/abstracts/abstract-wc-stripe-payment-gateway.php:424
58
+ #: includes/class-wc-stripe-order-handler.php:302
59
  #: includes/class-wc-stripe-webhook-handler.php:347
60
  #: includes/class-wc-stripe-webhook-handler.php:399
61
  #. translators: transaction id
63
  msgstr ""
64
 
65
  #: includes/abstracts/abstract-wc-stripe-payment-gateway.php:429
66
+ #: includes/class-wc-gateway-stripe.php:504
67
+ #: includes/compat/class-wc-stripe-sepa-subs-compat.php:179
68
  msgid "Payment processing failed. Please retry."
69
  msgstr ""
70
 
92
  msgid "There was a problem adding the payment method."
93
  msgstr ""
94
 
95
+ #: includes/admin/class-wc-stripe-admin-notices.php:125
96
  #. translators: 1) A URL that explains Stripe Radar.
97
  msgid ""
98
  "WooCommerce Stripe - We see that you had the \"Require 3D secure when "
101
  "href=\"%s\" target=\"_blank\">here</a>."
102
  msgstr ""
103
 
104
+ #: includes/admin/class-wc-stripe-admin-notices.php:132
105
  #. translators: 1) int version 2) int version
106
  msgid ""
107
  "WooCommerce Stripe - We recently made changes to Stripe that may impact the "
111
  "target=\"_blank\">instructions</a> to fix."
112
  msgstr ""
113
 
114
+ #: includes/admin/class-wc-stripe-admin-notices.php:142
115
  #. translators: 1) int version 2) int version
116
  msgid ""
117
  "WooCommerce Stripe - The minimum PHP version required for this plugin is "
118
  "%1$s. You are running %2$s."
119
  msgstr ""
120
 
121
+ #: includes/admin/class-wc-stripe-admin-notices.php:153
122
  #. translators: 1) int version 2) int version
123
  msgid ""
124
  "WooCommerce Stripe - The minimum WooCommerce version required for this "
125
  "plugin is %1$s. You are running %2$s."
126
  msgstr ""
127
 
128
+ #: includes/admin/class-wc-stripe-admin-notices.php:163
129
  msgid "WooCommerce Stripe - cURL is not installed."
130
  msgstr ""
131
 
132
+ #: includes/admin/class-wc-stripe-admin-notices.php:173
133
  #. translators: 1) link
134
  msgid ""
135
  "Stripe is almost ready. To get started, <a href=\"%s\">set your Stripe "
136
  "account keys</a>."
137
  msgstr ""
138
 
139
+ #: includes/admin/class-wc-stripe-admin-notices.php:184
140
  #. translators: 1) link
141
  msgid ""
142
  "Stripe is in test mode however your test keys may not be valid. Test keys "
144
  "<a href=\"%s\">set your Stripe account keys</a>."
145
  msgstr ""
146
 
147
+ #: includes/admin/class-wc-stripe-admin-notices.php:193
148
  #. translators: 1) link
149
  msgid ""
150
  "Stripe is in live mode however your test keys may not be valid. Live keys "
152
  "<a href=\"%s\">set your Stripe account keys</a>."
153
  msgstr ""
154
 
155
+ #: includes/admin/class-wc-stripe-admin-notices.php:202
156
  #. translators: 1) link
157
  msgid ""
158
  "Stripe is enabled, but a SSL certificate is not detected. Your checkout may "
160
  "target=\"_blank\">SSL certificate</a>"
161
  msgstr ""
162
 
163
+ #: includes/admin/class-wc-stripe-admin-notices.php:207
164
  msgid ""
165
  "Stripe is now ready for Strong Customer Authentication (SCA) and 3D Secure "
166
  "2! <a href=\"%1$s\" target=\"_blank\">Read about SCA</a>"
167
  msgstr ""
168
 
169
+ #: includes/admin/class-wc-stripe-admin-notices.php:212
170
+ #. translators: %s is a the URL for the link.
171
+ msgid ""
172
+ "The public and/or secret keys for the Stripe gateway have been changed. "
173
+ "This might cause errors for existing customers and saved payment methods. "
174
+ "<a href=\"%s\" target=\"_blank\">Click here to learn more</a>."
175
+ msgstr ""
176
+
177
+ #: includes/admin/class-wc-stripe-admin-notices.php:235
178
  #. translators: %1$s Payment method, %2$s List of supported currencies
179
  msgid "%1$s is enabled - it requires store currency to be set to %2$s"
180
  msgstr ""
181
 
182
+ #: includes/admin/class-wc-stripe-admin-notices.php:249
183
  msgid "Action failed. Please refresh the page and retry."
184
  msgstr ""
185
 
186
+ #: includes/admin/class-wc-stripe-admin-notices.php:253
187
  msgid "Cheatin&#8217; huh?"
188
  msgstr ""
189
 
218
  msgstr ""
219
 
220
  #: includes/admin/class-wc-stripe-privacy.php:41
221
+ #: includes/compat/class-wc-stripe-sepa-subs-compat.php:469
222
+ #: includes/compat/class-wc-stripe-subs-compat.php:567
223
+ #: includes/compat/class-wc-stripe-subs-compat.php:582
224
  msgid "N/A"
225
  msgstr ""
226
 
388
 
389
  #: includes/admin/stripe-alipay-settings.php:43
390
  #: includes/admin/stripe-bancontact-settings.php:43
391
+ #: includes/admin/stripe-eps-settings.php:39
392
  #: includes/admin/stripe-giropay-settings.php:43
393
  #: includes/admin/stripe-ideal-settings.php:43
394
  #: includes/admin/stripe-multibanco-settings.php:39
437
  msgid "You will be redirected to EPS."
438
  msgstr ""
439
 
 
 
 
 
440
  #: includes/admin/stripe-giropay-settings.php:10
441
  msgid "Relevant Payer Geography: Germany"
442
  msgstr ""
803
  msgid "Card Code (CVC)"
804
  msgstr ""
805
 
806
+ #: includes/class-wc-gateway-stripe.php:417
807
  msgid "Please accept the terms and conditions first"
808
  msgstr ""
809
 
810
+ #: includes/class-wc-gateway-stripe.php:418
811
  msgid "Please fill in required checkout fields first"
812
  msgstr ""
813
 
814
+ #: includes/class-wc-gateway-stripe.php:447
815
+ #: includes/class-wc-gateway-stripe.php:491
816
  msgid ""
817
  "Sorry, we're not accepting prepaid cards at this time. Your credit card has "
818
  "not been charged. Please try with alternative payment method."
819
  msgstr ""
820
 
821
+ #: includes/class-wc-gateway-stripe.php:448
822
  msgid "Please enter your IBAN account name."
823
  msgstr ""
824
 
825
+ #: includes/class-wc-gateway-stripe.php:449
826
  msgid "Please enter your IBAN account number."
827
  msgstr ""
828
 
829
+ #: includes/class-wc-gateway-stripe.php:450
830
  msgid "We couldn't initiate the payment. Please try again."
831
  msgstr ""
832
 
833
+ #: includes/class-wc-gateway-stripe.php:461
834
  msgid "Billing First Name and Last Name are required."
835
  msgstr ""
836
 
837
+ #: includes/class-wc-gateway-stripe.php:737
838
  #. translators: error message
839
  msgid "This represents the fee Stripe collects for the transaction."
840
  msgstr ""
841
 
842
+ #: includes/class-wc-gateway-stripe.php:738
843
  msgid "Stripe Fee:"
844
  msgstr ""
845
 
846
+ #: includes/class-wc-gateway-stripe.php:774
847
  msgid ""
848
  "This represents the net total that will be credited to your Stripe bank "
849
  "account. This may be in the currency that is set in your Stripe account."
850
  msgstr ""
851
 
852
+ #: includes/class-wc-gateway-stripe.php:775
853
  msgid "Stripe Payout:"
854
  msgstr ""
855
 
856
+ #: includes/class-wc-gateway-stripe.php:823
857
  #: includes/class-wc-stripe-order-handler.php:162
858
  #: includes/class-wc-stripe-webhook-handler.php:238
859
+ #: includes/compat/class-wc-stripe-sepa-subs-compat.php:269
860
+ #: includes/compat/class-wc-stripe-subs-compat.php:309
861
  #: includes/payment-methods/class-wc-gateway-stripe-sepa.php:373
862
  msgid ""
863
  "Sorry, we are unable to process your payment at this time. Please retry "
864
  "later."
865
  msgstr ""
866
 
867
+ #: includes/class-wc-gateway-stripe.php:876
868
  msgid ""
869
  "Almost there!\n"
870
  "\n"
872
  "done is for you to authorize the payment with your bank."
873
  msgstr ""
874
 
875
+ #: includes/class-wc-gateway-stripe.php:1117
876
  #: includes/class-wc-stripe-webhook-handler.php:685
877
  #: includes/class-wc-stripe-webhook-handler.php:724
878
  #. translators: 1) The error message that was received from Stripe.
879
  msgid "Stripe SCA authentication failed. Reason: %s"
880
  msgstr ""
881
 
882
+ #: includes/class-wc-gateway-stripe.php:1118
883
  msgid "Stripe SCA authentication failed."
884
  msgstr ""
885
 
926
  msgid "Attempting to update a Stripe customer without a customer ID."
927
  msgstr ""
928
 
929
+ #: includes/class-wc-stripe-customer.php:197
930
+ #. Translators: %s is a message, which states that no such customer exists,
931
+ #. without a full stop at the end.
932
+ msgid "%s. Was the customer created in live mode? "
933
+ msgstr ""
934
+
935
+ #: includes/class-wc-stripe-customer.php:199
936
+ #. Translators: %s is a message, which states that no such customer exists,
937
+ #. without a full stop at the end.
938
+ msgid "%s. Was the customer created in test mode? "
939
+ msgstr ""
940
+
941
+ #: includes/class-wc-stripe-customer.php:262
942
  msgid "Unable to add payment source."
943
  msgstr ""
944
 
1040
  msgstr ""
1041
 
1042
  #: includes/class-wc-stripe-order-handler.php:245
1043
+ #: includes/class-wc-stripe-order-handler.php:260
1044
+ #: includes/class-wc-stripe-order-handler.php:276
1045
+ #: includes/class-wc-stripe-order-handler.php:291
1046
  #. translators: error message
1047
  msgid "Unable to capture charge! %s"
1048
  msgstr ""
1172
  msgstr ""
1173
 
1174
  #: includes/compat/class-wc-stripe-pre-orders-compat.php:121
1175
+ #: includes/compat/class-wc-stripe-subs-compat.php:341
1176
+ #: includes/compat/class-wc-stripe-subs-compat.php:646
1177
  msgid "Stripe charge awaiting authentication by user: %s."
1178
  msgstr ""
1179
 
1182
  msgid "Stripe Transaction Failed (%s)"
1183
  msgstr ""
1184
 
1185
+ #: includes/compat/class-wc-stripe-sepa-subs-compat.php:83
1186
+ #: includes/compat/class-wc-stripe-subs-compat.php:92
1187
+ msgid "Update the Payment Method used for all of my active subscriptions."
 
 
1188
  msgstr ""
1189
 
1190
+ #: includes/compat/class-wc-stripe-sepa-subs-compat.php:232
1191
+ #: includes/compat/class-wc-stripe-subs-compat.php:270
1192
  msgid "Customer not found"
1193
  msgstr ""
1194
 
1195
+ #: includes/compat/class-wc-stripe-sepa-subs-compat.php:392
1196
+ #: includes/compat/class-wc-stripe-subs-compat.php:490
1197
  #. translators: error message
1198
  msgid "A \"Stripe Customer ID\" value is required."
1199
  msgstr ""
1200
 
1201
+ #: includes/compat/class-wc-stripe-sepa-subs-compat.php:394
1202
+ #: includes/compat/class-wc-stripe-subs-compat.php:492
1203
  msgid ""
1204
  "Invalid customer ID. A valid \"Stripe Customer ID\" must begin with "
1205
  "\"cus_\"."
1206
  msgstr ""
1207
 
1208
+ #: includes/compat/class-wc-stripe-sepa-subs-compat.php:403
1209
+ #: includes/compat/class-wc-stripe-subs-compat.php:501
1210
  msgid ""
1211
  "Invalid source ID. A valid source \"Stripe Source ID\" must begin with "
1212
  "\"src_\" or \"card_\"."
1213
  msgstr ""
1214
 
1215
+ #: includes/compat/class-wc-stripe-sepa-subs-compat.php:476
1216
  #. translators: 1) last 4 digits of SEPA Direct Debit
1217
  msgid "Via SEPA Direct Debit ending in %1$s"
1218
  msgstr ""
1219
 
1220
+ #: includes/compat/class-wc-stripe-subs-compat.php:333
1221
  msgid "This transaction requires authentication."
1222
  msgstr ""
1223
 
1224
+ #: includes/compat/class-wc-stripe-subs-compat.php:582
1225
  #. translators: 1) card brand 2) last 4 digits
1226
  msgid "Via %1$s card ending in %2$s"
1227
  msgstr ""
1228
 
1229
+ #: includes/compat/class-wc-stripe-subs-compat.php:679
1230
+ msgid "Your early renewal order was successful."
1231
+ msgstr ""
1232
+
1233
+ #: includes/compat/class-wc-stripe-subs-compat.php:692
1234
+ msgid ""
1235
+ "Payment authorization for the renewal order was unsuccessful, please try "
1236
+ "again."
1237
+ msgstr ""
1238
+
1239
  #: includes/payment-methods/class-wc-gateway-stripe-alipay.php:60
1240
  #: woocommerce-gateway-stripe.php:256
1241
  msgid "Stripe Alipay"
1351
  msgid "Stripe SOFORT"
1352
  msgstr ""
1353
 
1354
+ #: includes/payment-methods/class-wc-stripe-payment-request.php:254
1355
+ #: includes/payment-methods/class-wc-stripe-payment-request.php:858
1356
+ #: includes/payment-methods/class-wc-stripe-payment-request.php:1157
1357
  msgid "Tax"
1358
  msgstr ""
1359
 
1360
+ #: includes/payment-methods/class-wc-stripe-payment-request.php:262
1361
+ #: includes/payment-methods/class-wc-stripe-payment-request.php:866
1362
+ #: includes/payment-methods/class-wc-stripe-payment-request.php:1164
1363
  msgid "Shipping"
1364
  msgstr ""
1365
 
1366
+ #: includes/payment-methods/class-wc-stripe-payment-request.php:269
1367
+ #: includes/payment-methods/class-wc-stripe-payment-request.php:873
1368
  msgid "Pending"
1369
  msgstr ""
1370
 
1371
+ #: includes/payment-methods/class-wc-stripe-payment-request.php:486
1372
  msgid "Sorry, we're not accepting prepaid cards at this time."
1373
  msgstr ""
1374
 
1375
+ #: includes/payment-methods/class-wc-stripe-payment-request.php:488
1376
  #. translators: Do not translate the [option] placeholder
1377
  msgid "Unknown shipping option \"[option]\"."
1378
  msgstr ""
1379
 
1380
+ #: includes/payment-methods/class-wc-stripe-payment-request.php:591
1381
  msgid "OR"
1382
  msgstr ""
1383
 
1384
+ #: includes/payment-methods/class-wc-stripe-payment-request.php:731
1385
+ #: includes/payment-methods/class-wc-stripe-payment-request.php:744
1386
  msgid "Unable to find shipping method for address."
1387
  msgstr ""
1388
 
1389
+ #: includes/payment-methods/class-wc-stripe-payment-request.php:814
1390
  msgid "Product with the ID (%d) cannot be found."
1391
  msgstr ""
1392
 
1393
+ #: includes/payment-methods/class-wc-stripe-payment-request.php:841
1394
  #. translators: 1: product name 2: quantity in stock
1395
  msgid ""
1396
  "You cannot add that amount of \"%1$s\"; to the cart because there is not "
1397
  "enough stock (%2$s remaining)."
1398
  msgstr ""
1399
 
1400
+ #: includes/payment-methods/class-wc-stripe-payment-request.php:996
1401
  msgid "Empty cart"
1402
  msgstr ""
1403
 
1404
+ #: includes/payment-methods/class-wc-stripe-payment-request.php:1171
1405
  msgid "Discount"
1406
  msgstr ""
1407
 
readme.txt CHANGED
@@ -2,9 +2,9 @@
2
  Contributors: automattic, royho, akeda, mattyza, bor0, woothemes
3
  Tags: credit card, stripe, apple pay, payment request, google pay, sepa, sofort, bancontact, alipay, giropay, ideal, p24, woocommerce, automattic
4
  Requires at least: 4.4
5
- Tested up to: 5.3.0
6
  Requires PHP: 5.6
7
- Stable tag: 4.3.1
8
  License: GPLv3
9
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
10
  Attributions: thorsten-stripe
@@ -113,6 +113,13 @@ If you get stuck, you can ask for help in the Plugin Forum.
113
 
114
  == Changelog ==
115
 
 
 
 
 
 
 
 
116
  = 4.3.1 2019-11-12 =
117
  * Fix - Overwrite the previous Apple Pay verification file if it has changed.
118
  * Fix - Avoid re-mounting card elements if they are already mounted in the DOM.
@@ -122,16 +129,6 @@ If you get stuck, you can ask for help in the Plugin Forum.
122
  * Fix - Google Pay buttons on subscriptions.
123
  * Add - A filter, which allows all subscriptions' payment methods to be overwritten when adding a new payment method.
124
 
125
- = 4.3.0 2019-10-17 =
126
- * 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
127
- * 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
128
- * Add - When an off-session payment requires authentication, create a link for customers to come back to the store to authenticate the payment
129
- * Add - Send an email to WooCommerce Subscription and Pre-Orders customers who need to authenticate a payment that was automatically tried on their behalf
130
- * Add - When an off-session payment requires authentication, send an email to the admin
131
- * Add - Admin notice about SCA-readiness
132
- * Fix - Avoid idempotency key errors for Pre-Orders
133
- * Fix - Use unique anchor for link about checkout styling changes
134
-
135
  [See changelog for all versions](https://raw.githubusercontent.com/woocommerce/woocommerce-gateway-stripe/master/changelog.txt).
136
 
137
  == 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.3.2
6
  Requires PHP: 5.6
7
+ Stable tag: 4.3.2
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.2 2020-02-17 =
117
+ * Fix - Add compatibility to payment request buttons with some of the WooCommerce Product Add-ons on the product page
118
+ * Fix - Improved compatibility for free orders with other extensions
119
+ * Add - Support for multisite when sites use different Stripe accounts
120
+ * Fix - Display a localized error message when a customer tries to save a card during checkout, but there's an error
121
+ * Add - Send level 3 credit card data for purchases when possible
122
+
123
  = 4.3.1 2019-11-12 =
124
  * Fix - Overwrite the previous Apple Pay verification file if it has changed.
125
  * Fix - Avoid re-mounting card elements if they are already mounted in the DOM.
129
  * Fix - Google Pay buttons on subscriptions.
130
  * Add - A filter, which allows all subscriptions' payment methods to be overwritten when adding a new payment method.
131
 
 
 
 
 
 
 
 
 
 
 
132
  [See changelog for all versions](https://raw.githubusercontent.com/woocommerce/woocommerce-gateway-stripe/master/changelog.txt).
133
 
134
  == Upgrade Notice ==
woocommerce-gateway-stripe.php CHANGED
@@ -5,11 +5,11 @@
5
  * Description: Take credit card payments on your store using Stripe.
6
  * Author: WooCommerce
7
  * Author URI: https://woocommerce.com/
8
- * Version: 4.3.1
9
  * Requires at least: 4.4
10
- * Tested up to: 5.3.0
11
  * WC requires at least: 2.6
12
- * WC tested up to: 3.8
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.3.1' );
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__ );
5
  * Description: Take credit card payments on your store using Stripe.
6
  * Author: WooCommerce
7
  * Author URI: https://woocommerce.com/
8
+ * Version: 4.3.2
9
  * Requires at least: 4.4
10
+ * Tested up to: 5.3.2
11
  * WC requires at least: 2.6
12
+ * WC tested up to: 3.9.2
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.2' );
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__ );