WooCommerce Stripe Payment Gateway - Version 4.0.2

Version Description

  • 2018-01-17 =
  • Add - 3DS support on Stripe Checkout ( Modal Popup ).
  • Add - Filter to enable Payment Request Button on Checkout 'wc_stripe_show_payment_request_on_checkout'.
  • Add - Filter to remove all fields from checkout validation. 'wc_stripe_validate_checkout_all_fields'.
  • Add - Filter to remove required fields from checkout validation. 'wc_stripe_validate_checkout_required_fields'.
  • Add - Custom error exceptions class.
  • Add - Credit card field names for clarity.
  • Fix - Possible conflicts with payment request totals when subscriptions is active.
  • Fix - Undefined notice on save card via subscriptions if card is deleted.
  • Fix - Error translation issue when 3DS is required.
  • Fix - Possible 404 if getting customer source if no id was found.
  • Fix - Add payment method was still available when save cards setting is disabled.
  • Fix - In certain cases when webhook is used, refunds can show as doubled when it is not.
  • Fix - Stripe checkout with bitcoin returns error on processing.
  • Tweak - Remove Sofort country selection in favor of using the billing country.
  • Tweak - Add payment page CSS styling.
  • Tweak - Error log to show full response object.
Download this release

Release Info

Developer royho
Plugin Icon 128x128 WooCommerce Stripe Payment Gateway
Version 4.0.2
Comparing to
See all releases

Code changes from version 4.0.1 to 4.0.2

assets/css/stripe-paymentfonts.css CHANGED
@@ -1,4 +1,4 @@
1
  /*!
2
  * PaymentFont 1.2.5 by @AMPoellmann - http://paymentfont.com
3
  * License - http://paymentfont.io/#license (Font: SIL OFL 1.1, CSS: MIT License)
4
- */@font-face{font-family:PaymentFont;src:url(../paymentfonts/paymentfont-webfont.eot);src:url(../paymentfonts/paymentfont-webfont.eot?#iefix) format('embedded-opentype'),url(../paymentfonts/paymentfont-webfont.woff) format('woff2'),url(../paymentfonts/paymentfont-webfont.woff) format('woff'),url(../paymentfonts/paymentfont-webfont.ttf) format('truetype'),url(../paymentfonts/paymentfont-webfont.svg#paymentfont-webfont) format('svg');font-weight:400;font-style:normal}.stripe-pf{display:inline-block;font:normal normal normal 14px/1 PaymentFont;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-size:1.2em}.stripe-pf-right{float:right}.stripe-pf-left{float:left}.stripe-pf-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.stripe-pf-2x{font-size:2em}.stripe-pf-3x{font-size:3em}.stripe-pf-4x{font-size:4em}.stripe-pf-5x{font-size:5em}.stripe-pf-amazon:before{content:"\f000"}.stripe-pf-american-express:before{content:"\f001"}.stripe-pf-american-express-alt:before{content:"\f002"}.stripe-pf-atm:before{content:"\f003"}.stripe-pf-bankomat:before{content:"\f004"}.stripe-pf-bank-transfer:before{content:"\f005"}.stripe-pf-bitcoin:before{content:"\f006"}.stripe-pf-bitcoin-sign:before{content:"\f007"}.stripe-pf-braintree:before{content:"\f008"}.stripe-pf-btc:before{content:"\f009"}.stripe-pf-card:before{content:"\f00a"}.stripe-pf-carta-si:before{content:"\f00b"}.stripe-pf-cash:before{content:"\f00c"}.stripe-pf-cash-on-delivery:before{content:"\f00d"}.stripe-pf-cb:before{content:"\f00e"}.stripe-pf-cirrus:before{content:"\f00f"}.stripe-pf-cirrus-alt:before{content:"\f010"}.stripe-pf-clickandbuy:before{content:"\f011"}.stripe-pf-credit-card:before{content:"\f012"}.stripe-pf-diners:before{content:"\f013"}.stripe-pf-discover:before{content:"\f014"}.stripe-pf-ec:before{content:"\f015"}.stripe-pf-eps:before{content:"\f016"}.stripe-pf-eur:before{content:"\f017"}.stripe-pf-facture:before{content:"\f018"}.stripe-pf-fattura:before{content:"\f019"}.stripe-pf-flattr:before{content:"\f01a"}.stripe-pf-giropay:before{content:"\f01b"}.stripe-pf-google-wallet:before{content:"\f01c"}.stripe-pf-google-wallet-alt:before{content:"\f01d"}.stripe-pf-gpb:before{content:"\f01e"}.stripe-pf-gratipay:before{content:"\f01f"}.stripe-pf-ideal:before{content:"\f020"}.stripe-pf-ils:before{content:"\f021"}.stripe-pf-inr:before{content:"\f022"}.stripe-pf-invoice:before{content:"\f023"}.stripe-pf-invoice-sign:before{content:"\f024"}.stripe-pf-invoice-sign-alt:before{content:"\f025"}.stripe-pf-invoice-sign-alt-o:before{content:"\f026"}.stripe-pf-invoice-sign-o:before{content:"\f027"}.stripe-pf-jcb:before{content:"\f028"}.stripe-pf-jpy:before{content:"\f029"}.stripe-pf-krw:before{content:"\f02a"}.stripe-pf-maestro:before{content:"\f02b"}.stripe-pf-maestro-alt:before{content:"\f02c"}.stripe-pf-mastercard:before{content:"\f02d"}.stripe-pf-mastercard-alt:before{content:"\f02e"}.stripe-pf-mastercard-securecode:before{content:"\f02f"}.stripe-pf-ogone:before{content:"\f030"}.stripe-pf-paybox:before{content:"\f031"}.stripe-pf-paylife:before{content:"\f032"}.stripe-pf-paypal:before{content:"\f033"}.stripe-pf-paypal-alt:before{content:"\f034"}.stripe-pf-paysafecard:before{content:"\f035"}.stripe-pf-postepay:before{content:"\f036"}.stripe-pf-quick:before{content:"\f037"}.stripe-pf-rechnung:before{content:"\f038"}.stripe-pf-ripple:before{content:"\f039"}.stripe-pf-rub:before{content:"\f03a"}.stripe-pf-skrill:before{content:"\f03b"}.stripe-pf-sofort:before{content:"\f03c"}.stripe-pf-square:before{content:"\f03d"}.stripe-pf-stripe:before{content:"\f03e"}.stripe-pf-truste:before{content:"\f03f"}.stripe-pf-try:before{content:"\f040"}.stripe-pf-unionpay:before{content:"\f041"}.stripe-pf-usd:before{content:"\f042"}.stripe-pf-verified-by-visa:before{content:"\f043"}.stripe-pf-verisign:before{content:"\f044"}.stripe-pf-visa:before{content:"\f045"}.stripe-pf-visa-electron:before{content:"\f046"}.stripe-pf-western-union:before{content:"\f047"}.stripe-pf-western-union-alt:before{content:"\f048"}.stripe-pf-wirecard:before{content:"\f049"}.stripe-pf-sepa:before{content:"\f04a"}.stripe-pf-sepa-alt:before{content:"\f04b"}.stripe-pf-apple-pay:before{content:"\f04c"}.stripe-pf-interac:before{content:"\f04d"}.stripe-pf-paymill:before{content:"\f04e"}.stripe-pf-dankort:before{content:"\f04f"}.stripe-pf-bancontact-mister-cash:before{content:"\f050"}.stripe-pf-moip:before{content:"\f051"}.stripe-pf-pagseguro:before{content:"\f052"}.stripe-pf-cash-on-pickup:before{content:"\f053"}.stripe-pf-sage:before{content:"\f054"}.stripe-pf-elo:before{content:"\f055"}.stripe-pf-elo-alt:before{content:"\f056"}.stripe-pf-payu:before{content:"\f057"}.stripe-pf-mercado-pago:before{content:"\f058"}.stripe-pf-mercado-pago-sign:before{content:"\f059"}.stripe-pf-payshop:before{content:"\f05a"}.stripe-pf-multibanco:before{content:"\f05b"}.stripe-pf-gratipay-sign:before{content:"\f05c"}.stripe-pf-six:before{content:"\f05d"}.stripe-pf-cashcloud:before{content:"\f05e"}.stripe-pf-interac-alt:before{content:"\f05f"}.stripe-pf-klarna:before{content:"\f060"}.stripe-pf-bitpay:before{content:"\f061"}.stripe-pf-venmo:before{content:"\f062"}.stripe-pf-visa-debit:before{content:"\f063"}.stripe-pf-alipay:before{content:"\f064"}.stripe-pf-diners-alt:before{content:"\f065"}.stripe-pf-hipercard:before{content:"\f066"}.stripe-pf-skrill-alt:before{content:"\f067"}.stripe-pf-shopify:before{content:"\f068"}.stripe-pf-direct-debit:before{content:"\f069"}.stripe-pf-sodexo:before{content:"\f06a"}.stripe-pf-bpay:before{content:"\f06b"}.stripe-pf-contactless:before{content:"\f06c"}.stripe-pf-contactless-alt:before{content:"\f06d"}.stripe-pf-eth:before{content:"\f06e"}.stripe-pf-ltc:before{content:"\f06f"}.stripe-pf-visa-pay:before{content:"\f070"}.stripe-pf-wechat-pay:before{content:"\f071"}.stripe-pf-amazon-pay:before{content:"\f072"}.stripe-pf-amazon-pay-alt:before{content:"\f073"}.stripe-pf-p24{background-image:url(../images/p24.svg);background-repeat:no-repeat;width:2.5em;height:2.5em}
1
  /*!
2
  * PaymentFont 1.2.5 by @AMPoellmann - http://paymentfont.com
3
  * License - http://paymentfont.io/#license (Font: SIL OFL 1.1, CSS: MIT License)
4
+ */@font-face{font-family:PaymentFont;src:url(../paymentfonts/paymentfont-webfont.eot);src:url(../paymentfonts/paymentfont-webfont.eot?#iefix) format('embedded-opentype'),url(../paymentfonts/paymentfont-webfont.woff) format('woff2'),url(../paymentfonts/paymentfont-webfont.woff) format('woff'),url(../paymentfonts/paymentfont-webfont.ttf) format('truetype'),url(../paymentfonts/paymentfont-webfont.svg#paymentfont-webfont) format('svg');font-weight:400;font-style:normal}.stripe-pf{display:inline-block;font:normal normal normal 14px/1 PaymentFont;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-size:1.2em}.stripe-pf-right{float:right}.stripe-pf-left{float:left}.stripe-pf-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.stripe-pf-2x{font-size:2em}.stripe-pf-3x{font-size:3em}.stripe-pf-4x{font-size:4em}.stripe-pf-5x{font-size:5em}.stripe-pf-amazon:before{content:"\f000"}.stripe-pf-american-express:before{content:"\f001"}.stripe-pf-american-express-alt:before{content:"\f002"}.stripe-pf-atm:before{content:"\f003"}.stripe-pf-bankomat:before{content:"\f004"}.stripe-pf-bank-transfer:before{content:"\f005"}.stripe-pf-bitcoin:before{content:"\f006"}.stripe-pf-bitcoin-sign:before{content:"\f007"}.stripe-pf-braintree:before{content:"\f008"}.stripe-pf-btc:before{content:"\f009"}.stripe-pf-card:before{content:"\f00a"}.stripe-pf-carta-si:before{content:"\f00b"}.stripe-pf-cash:before{content:"\f00c"}.stripe-pf-cash-on-delivery:before{content:"\f00d"}.stripe-pf-cb:before{content:"\f00e"}.stripe-pf-cirrus:before{content:"\f00f"}.stripe-pf-cirrus-alt:before{content:"\f010"}.stripe-pf-clickandbuy:before{content:"\f011"}.stripe-pf-credit-card:before{content:"\f012"}.stripe-pf-diners:before{content:"\f013"}.stripe-pf-discover:before{content:"\f014"}.stripe-pf-ec:before{content:"\f015"}.stripe-pf-eps:before{content:"\f016"}.stripe-pf-eur:before{content:"\f017"}.stripe-pf-facture:before{content:"\f018"}.stripe-pf-fattura:before{content:"\f019"}.stripe-pf-flattr:before{content:"\f01a"}.stripe-pf-giropay:before{content:"\f01b"}.stripe-pf-google-wallet:before{content:"\f01c"}.stripe-pf-google-wallet-alt:before{content:"\f01d"}.stripe-pf-gpb:before{content:"\f01e"}.stripe-pf-gratipay:before{content:"\f01f"}.stripe-pf-ideal:before{content:"\f020"}.stripe-pf-ils:before{content:"\f021"}.stripe-pf-inr:before{content:"\f022"}.stripe-pf-invoice:before{content:"\f023"}.stripe-pf-invoice-sign:before{content:"\f024"}.stripe-pf-invoice-sign-alt:before{content:"\f025"}.stripe-pf-invoice-sign-alt-o:before{content:"\f026"}.stripe-pf-invoice-sign-o:before{content:"\f027"}.stripe-pf-jcb:before{content:"\f028"}.stripe-pf-jpy:before{content:"\f029"}.stripe-pf-krw:before{content:"\f02a"}.stripe-pf-maestro:before{content:"\f02b"}.stripe-pf-maestro-alt:before{content:"\f02c"}.stripe-pf-mastercard:before{content:"\f02d"}.stripe-pf-mastercard-alt:before{content:"\f02e"}.stripe-pf-mastercard-securecode:before{content:"\f02f"}.stripe-pf-ogone:before{content:"\f030"}.stripe-pf-paybox:before{content:"\f031"}.stripe-pf-paylife:before{content:"\f032"}.stripe-pf-paypal:before{content:"\f033"}.stripe-pf-paypal-alt:before{content:"\f034"}.stripe-pf-paysafecard:before{content:"\f035"}.stripe-pf-postepay:before{content:"\f036"}.stripe-pf-quick:before{content:"\f037"}.stripe-pf-rechnung:before{content:"\f038"}.stripe-pf-ripple:before{content:"\f039"}.stripe-pf-rub:before{content:"\f03a"}.stripe-pf-skrill:before{content:"\f03b"}.stripe-pf-sofort:before{content:"\f03c"}.stripe-pf-square:before{content:"\f03d"}.stripe-pf-stripe:before{content:"\f03e"}.stripe-pf-truste:before{content:"\f03f"}.stripe-pf-try:before{content:"\f040"}.stripe-pf-unionpay:before{content:"\f041"}.stripe-pf-usd:before{content:"\f042"}.stripe-pf-verified-by-visa:before{content:"\f043"}.stripe-pf-verisign:before{content:"\f044"}.stripe-pf-visa:before{content:"\f045"}.stripe-pf-visa-electron:before{content:"\f046"}.stripe-pf-western-union:before{content:"\f047"}.stripe-pf-western-union-alt:before{content:"\f048"}.stripe-pf-wirecard:before{content:"\f049"}.stripe-pf-sepa:before{content:"\f04a"}.stripe-pf-sepa-alt:before{content:"\f04b"}.stripe-pf-apple-pay:before{content:"\f04c"}.stripe-pf-interac:before{content:"\f04d"}.stripe-pf-paymill:before{content:"\f04e"}.stripe-pf-dankort:before{content:"\f04f"}.stripe-pf-bancontact-mister-cash:before{content:"\f050"}.stripe-pf-moip:before{content:"\f051"}.stripe-pf-pagseguro:before{content:"\f052"}.stripe-pf-cash-on-pickup:before{content:"\f053"}.stripe-pf-sage:before{content:"\f054"}.stripe-pf-elo:before{content:"\f055"}.stripe-pf-elo-alt:before{content:"\f056"}.stripe-pf-payu:before{content:"\f057"}.stripe-pf-mercado-pago:before{content:"\f058"}.stripe-pf-mercado-pago-sign:before{content:"\f059"}.stripe-pf-payshop:before{content:"\f05a"}.stripe-pf-multibanco:before{content:"\f05b"}.stripe-pf-gratipay-sign:before{content:"\f05c"}.stripe-pf-six:before{content:"\f05d"}.stripe-pf-cashcloud:before{content:"\f05e"}.stripe-pf-interac-alt:before{content:"\f05f"}.stripe-pf-klarna:before{content:"\f060"}.stripe-pf-bitpay:before{content:"\f061"}.stripe-pf-venmo:before{content:"\f062"}.stripe-pf-visa-debit:before{content:"\f063"}.stripe-pf-alipay:before{content:"\f064"}.stripe-pf-diners-alt:before{content:"\f065"}.stripe-pf-hipercard:before{content:"\f066"}.stripe-pf-skrill-alt:before{content:"\f067"}.stripe-pf-shopify:before{content:"\f068"}.stripe-pf-direct-debit:before{content:"\f069"}.stripe-pf-sodexo:before{content:"\f06a"}.stripe-pf-bpay:before{content:"\f06b"}.stripe-pf-contactless:before{content:"\f06c"}.stripe-pf-contactless-alt:before{content:"\f06d"}.stripe-pf-eth:before{content:"\f06e"}.stripe-pf-ltc:before{content:"\f06f"}.stripe-pf-visa-pay:before{content:"\f070"}.stripe-pf-wechat-pay:before{content:"\f071"}.stripe-pf-amazon-pay:before{content:"\f072"}.stripe-pf-amazon-pay-alt:before{content:"\f073"}.stripe-pf-p24{background-image:url(../images/p24.svg);background-repeat:no-repeat;width:2.5em;height:2.5em}#add_payment_method #payment_method_stripe {margin:25px 0 25px 25px;}#add_payment_method #payment_method_stripe_sepa {margin:25px 0 25px 25px;}#add_payment_method .woocommerce-PaymentMethod label {margin-left:10px;}#add_payment_method .woocommerce-PaymentMethod label .stripe-pf{margin:25px 0 25px 0;}#add_payment_method .woocommerce-PaymentMethod label .stripe-pf:first-child{margin-right:25px;}#add_payment_method li {clear:right;}#add_payment_method #wc-stripe_sepa-form {padding:10px;}
assets/js/stripe.js CHANGED
@@ -302,22 +302,25 @@ jQuery( function( $ ) {
302
  openModal: function() {
303
  // Capture submittal and open stripecheckout
304
  var $form = wc_stripe_form.form,
305
- $data = $( '#stripe-payment-data' ),
306
- token = $form.find( 'input.stripe_token' );
307
 
308
- token.val( '' );
309
 
310
  var token_action = function( res ) {
311
- $form.find( 'input.stripe_token' ).remove();
312
- $form.append( '<input type="hidden" class="stripe_token" name="stripe_token" value="' + res.id + '"/>' );
313
- $form.append( "<input type='hidden' class='stripe-checkout-object' name='stripe_checkout_object' value='" + wc_stripe_form.prepareSourceToServer( res ) + "'/>" );
314
- wc_stripe_form.stripe_submit = true;
315
 
316
- if ( $( 'form#add_payment_method' ).length ) {
317
- $( wc_stripe_form.form ).off( 'submit', wc_stripe_form.form.onSubmit );
 
 
 
 
 
 
 
 
 
318
  }
319
-
320
- $form.submit();
321
  };
322
 
323
  StripeCheckout.open({
@@ -374,8 +377,12 @@ jQuery( function( $ ) {
374
  }
375
 
376
  wc_stripe_form.reset();
 
377
  console.log( result.error.message ); // Leave for troubleshooting.
378
  $( errorContainer ).html( '<ul class="woocommerce_error woocommerce-error wc-stripe-error"><li>' + message + '</li></ul>' );
 
 
 
379
  wc_stripe_form.unblock();
380
  },
381
 
@@ -466,9 +473,9 @@ jQuery( function( $ ) {
466
  case 'sofort':
467
  case 'alipay':
468
  // These redirect flow payment methods need this information to be set at source creation.
469
- extra_details.amount = $( '#stripe-' + source_type + '-payment-data' ).data( 'amount' );
470
- extra_details.currency = $( '#stripe-' + source_type + '-payment-data' ).data( 'currency' );
471
- extra_details.redirect = { return_url: wc_stripe_params.return_url };
472
 
473
  if ( wc_stripe_params.statement_descriptor ) {
474
  extra_details.statement_descriptor = wc_stripe_params.statement_descriptor;
@@ -487,9 +494,6 @@ jQuery( function( $ ) {
487
  case 'ideal':
488
  extra_details.ideal = { bank: $( '#stripe-ideal-bank' ).val() };
489
  break;
490
- case 'sofort':
491
- extra_details.sofort = { country: $( '#stripe-sofort-country' ).val() };
492
- break;
493
  case 'bitcoin':
494
  case 'alipay':
495
  extra_details.currency = $( '#stripe-' + source_type + '-payment-data' ).data( 'currency' );
@@ -727,7 +731,7 @@ jQuery( function( $ ) {
727
  },
728
 
729
  getRequiredFields: function() {
730
- return wc_stripe_form.form.find( '.form-row.validate-required > input, .form-row.validate-required > select' );
731
  },
732
 
733
  validateCheckout: function( type ) {
@@ -786,7 +790,7 @@ jQuery( function( $ ) {
786
  wc_stripe_form.form.find( '.input-text, select, input:checkbox' ).blur();
787
  $( 'html, body' ).animate({
788
  scrollTop: ( $( 'form.checkout' ).offset().top - 100 )
789
- }, 1000 );
790
  $( document.body ).trigger( 'checkout_error' );
791
  wc_stripe_form.unblock();
792
  }
302
  openModal: function() {
303
  // Capture submittal and open stripecheckout
304
  var $form = wc_stripe_form.form,
305
+ $data = $( '#stripe-payment-data' );
 
306
 
307
+ wc_stripe_form.reset();
308
 
309
  var token_action = function( res ) {
310
+ $form.find( 'input.stripe_source' ).remove();
 
 
 
311
 
312
+ /* Since source was introduced in 4.0. We need to
313
+ * convert the token into a source.
314
+ */
315
+ if ( 'token' === res.object ) {
316
+ stripe.createSource( {
317
+ type: 'card',
318
+ token: res.id,
319
+ } ).then( wc_stripe_form.sourceResponse );
320
+ } else if ( 'source' === res.object ) {
321
+ var response = { source: res };
322
+ wc_stripe_form.sourceResponse( response );
323
  }
 
 
324
  };
325
 
326
  StripeCheckout.open({
377
  }
378
 
379
  wc_stripe_form.reset();
380
+ $( '.woocommerce-NoticeGroup-checkout' ).remove();
381
  console.log( result.error.message ); // Leave for troubleshooting.
382
  $( errorContainer ).html( '<ul class="woocommerce_error woocommerce-error wc-stripe-error"><li>' + message + '</li></ul>' );
383
+ $( 'html, body' ).animate({
384
+ scrollTop: ( $( '.wc-stripe-error' ).offset().top - 200 )
385
+ }, 200 );
386
  wc_stripe_form.unblock();
387
  },
388
 
473
  case 'sofort':
474
  case 'alipay':
475
  // These redirect flow payment methods need this information to be set at source creation.
476
+ extra_details.amount = $( '#stripe-' + source_type + '-payment-data' ).data( 'amount' );
477
+ extra_details.currency = $( '#stripe-' + source_type + '-payment-data' ).data( 'currency' );
478
+ extra_details.redirect = { return_url: wc_stripe_params.return_url };
479
 
480
  if ( wc_stripe_params.statement_descriptor ) {
481
  extra_details.statement_descriptor = wc_stripe_params.statement_descriptor;
494
  case 'ideal':
495
  extra_details.ideal = { bank: $( '#stripe-ideal-bank' ).val() };
496
  break;
 
 
 
497
  case 'bitcoin':
498
  case 'alipay':
499
  extra_details.currency = $( '#stripe-' + source_type + '-payment-data' ).data( 'currency' );
731
  },
732
 
733
  getRequiredFields: function() {
734
+ return wc_stripe_form.form.find( '.form-row.validate-required > input, .form-row.validate-required > select, .form-row.validate-required > textarea' );
735
  },
736
 
737
  validateCheckout: function( type ) {
790
  wc_stripe_form.form.find( '.input-text, select, input:checkbox' ).blur();
791
  $( 'html, body' ).animate({
792
  scrollTop: ( $( 'form.checkout' ).offset().top - 100 )
793
+ }, 500 );
794
  $( document.body ).trigger( 'checkout_error' );
795
  wc_stripe_form.unblock();
796
  }
assets/js/stripe.min.js CHANGED
@@ -1 +1 @@
1
- jQuery(function(a){"use strict";var b=Stripe(wc_stripe_params.key);if("yes"===wc_stripe_params.use_elements)var c,d,e,f=b.elements();var g={getAjaxURL:function(a){return wc_stripe_params.ajaxurl.toString().replace("%%endpoint%%","wc_stripe_"+a)},init:function(){"yes"===wc_stripe_params.is_change_payment_page&&a(document.body).trigger("wc-credit-card-form-init"),this.stripe_checkout_submit=!1,a("form.woocommerce-checkout").length&&(this.form=a("form.woocommerce-checkout")),a("form.woocommerce-checkout").on("checkout_place_order_stripe checkout_place_order_stripe_bancontact checkout_place_order_stripe_sofort checkout_place_order_stripe_giropay checkout_place_order_stripe_ideal checkout_place_order_stripe_alipay checkout_place_order_stripe_sepa checkout_place_order_stripe_bitcoin",this.onSubmit),a("form#order_review").length&&(this.form=a("form#order_review")),a("form#order_review").on("submit",this.onSubmit),a("form#add_payment_method").length&&(this.form=a("form#add_payment_method")),a("form#add_payment_method").on("submit",this.onSubmit),a("form.woocommerce-checkout").on("change","#stripe-bank-country",this.reset),a(document).on("stripeError",this.onError).on("checkout_error",this.reset);var b={base:{iconColor:"#666EE8",color:"#31325F",fontSize:"15px","::placeholder":{color:"#CFD7E0"}}},h={focus:"focused",empty:"empty",invalid:"invalid"};"yes"===wc_stripe_params.use_elements&&a("#stripe-card-element").length&&(b=wc_stripe_params.elements_styling?wc_stripe_params.elements_styling:b,h=wc_stripe_params.elements_classes?wc_stripe_params.elements_classes:h,"yes"===wc_stripe_params.inline_cc_form?(c=f.create("card",{style:b,hidePostalCode:!0}),c.addEventListener("change",function(b){g.onCCFormChange(),b.error&&a(document.body).trigger("stripeError",b)})):(c=f.create("cardNumber",{style:b,classes:h}),d=f.create("cardExpiry",{style:b,classes:h}),e=f.create("cardCvc",{style:b,classes:h}),c.addEventListener("change",function(b){g.onCCFormChange(),b.error&&a(document.body).trigger("stripeError",b)}),d.addEventListener("change",function(b){g.onCCFormChange(),b.error&&a(document.body).trigger("stripeError",b)}),e.addEventListener("change",function(b){g.onCCFormChange(),b.error&&a(document.body).trigger("stripeError",b)})),wc_stripe_params.is_checkout?a(document.body).on("updated_checkout",function(){c&&("yes"===wc_stripe_params.inline_cc_form?c.unmount("#stripe-card-element"):(c.unmount("#stripe-card-element"),d.unmount("#stripe-exp-element"),e.unmount("#stripe-cvc-element"))),"yes"===wc_stripe_params.inline_cc_form?c.mount("#stripe-card-element"):(c.mount("#stripe-card-element"),d.mount("#stripe-exp-element"),e.mount("#stripe-cvc-element"))}):(a("form#add_payment_method").length||a("form#order_review").length)&&("yes"===wc_stripe_params.inline_cc_form?c.mount("#stripe-card-element"):(c.mount("#stripe-card-element"),d.mount("#stripe-exp-element"),e.mount("#stripe-cvc-element"))))},isStripeChosen:function(){return a("#payment_method_stripe, #payment_method_stripe_bancontact, #payment_method_stripe_sofort, #payment_method_stripe_giropay, #payment_method_stripe_ideal, #payment_method_stripe_alipay, #payment_method_stripe_sepa, #payment_method_stripe_bitcoin").is(":checked")||"new"===a('input[name="wc-stripe-payment-token"]:checked').val()},isStripeSaveCardChosen:function(){return a("#payment_method_stripe").is(":checked")&&a('input[name="wc-stripe-payment-token"]').is(":checked")&&"new"!==a('input[name="wc-stripe-payment-token"]:checked').val()||a("#payment_method_stripe_sepa").is(":checked")&&a('input[name="wc-stripe_sepa-payment-token"]').is(":checked")&&"new"!==a('input[name="wc-stripe_sepa-payment-token"]:checked').val()},isStripeCardChosen:function(){return a("#payment_method_stripe").is(":checked")},isBancontactChosen:function(){return a("#payment_method_stripe_bancontact").is(":checked")},isGiropayChosen:function(){return a("#payment_method_stripe_giropay").is(":checked")},isIdealChosen:function(){return a("#payment_method_stripe_ideal").is(":checked")},isSofortChosen:function(){return a("#payment_method_stripe_sofort").is(":checked")},isAlipayChosen:function(){return a("#payment_method_stripe_alipay").is(":checked")},isSepaChosen:function(){return a("#payment_method_stripe_sepa").is(":checked")},isBitcoinChosen:function(){return a("#payment_method_stripe_bitcoin").is(":checked")},hasSource:function(){return 0<a("input.stripe-source").length},hasToken:function(){return 0<a("input.stripe_token").length},isMobile:function(){return!!/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)},isStripeModalNeeded:function(a){var b=g.form.find("input.stripe_token");return(!g.stripe_submit||!b)&&!!g.isStripeChosen()},block:function(){g.isMobile()?a.blockUI({message:null,overlayCSS:{background:"#fff",opacity:.6}}):g.form.block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},unblock:function(){g.isMobile()?a.unblockUI():g.form.unblock()},getSelectedPaymentElement:function(){return a('.payment_methods input[name="payment_method"]:checked')},openModal:function(){var b=g.form,c=a("#stripe-payment-data");b.find("input.stripe_token").val("");var d=function(c){b.find("input.stripe_token").remove(),b.append('<input type="hidden" class="stripe_token" name="stripe_token" value="'+c.id+'"/>'),b.append("<input type='hidden' class='stripe-checkout-object' name='stripe_checkout_object' value='"+g.prepareSourceToServer(c)+"'/>"),g.stripe_submit=!0,a("form#add_payment_method").length&&a(g.form).off("submit",g.form.onSubmit),b.submit()};StripeCheckout.open({key:wc_stripe_params.key,billingAddress:"yes"===wc_stripe_params.stripe_checkout_require_billing_address,amount:c.data("amount"),name:c.data("name"),description:c.data("description"),currency:c.data("currency"),image:c.data("image"),bitcoin:c.data("bitcoin"),locale:c.data("locale"),email:a("#billing_email").val()||c.data("email"),panelLabel:c.data("panel-label"),allowRememberMe:c.data("allow-remember-me"),token:d,closed:g.onClose()})},resetModal:function(){g.reset(),g.stripe_checkout_submit=!1},onClose:function(){g.unblock()},onError:function(b,c){var d=c.error.message,e=g.getSelectedPaymentElement().parent(".wc_payment_method, .woocommerce-PaymentMethod").find(".stripe-source-errors");"invalid_request_error"!==c.error.type&&"api_connection_error"!==c.error.type&&"api_error"!==c.error.type&&"authentication_error"!==c.error.type&&"rate_limit_error"!==c.error.type||(d=wc_stripe_params.invalid_request_error),"card_error"===c.error.type&&wc_stripe_params.hasOwnProperty(c.error.code)&&(d=wc_stripe_params[c.error.code]),"validation_error"===c.error.type&&wc_stripe_params.hasOwnProperty(c.error.code)&&(d=wc_stripe_params[c.error.code]),g.reset(),console.log(c.error.message),a(e).html('<ul class="woocommerce_error woocommerce-error wc-stripe-error"><li>'+d+"</li></ul>"),g.unblock()},getOwnerDetails:function(){var b=a("#billing_first_name").length?a("#billing_first_name").val():wc_stripe_params.billing_first_name,c=a("#billing_last_name").length?a("#billing_last_name").val():wc_stripe_params.billing_last_name,d={owner:{name:"",address:{},email:"",phone:""}};return d.owner.name=b,b&&c&&(d.owner.name=b+" "+c),d.owner.email=a("#billing_email").val(),d.owner.phone=a("#billing_phone").val(),void 0!==d.owner.phone&&0>=d.owner.phone.length&&delete d.owner.phone,void 0!==d.owner.email&&0>=d.owner.email.length&&delete d.owner.email,a("#billing_address_1").length>0?(d.owner.address.line1=a("#billing_address_1").val(),d.owner.address.line2=a("#billing_address_2").val(),d.owner.address.state=a("#billing_state").val(),d.owner.address.city=a("#billing_city").val(),d.owner.address.postal_code=a("#billing_postcode").val(),d.owner.address.country=a("#billing_country").val()):wc_stripe_params.billing_address_1&&(d.owner.address.line1=wc_stripe_params.billing_address_1,d.owner.address.line2=wc_stripe_params.billing_address_2,d.owner.address.state=wc_stripe_params.billing_state,d.owner.address.city=wc_stripe_params.billing_city,d.owner.address.postal_code=wc_stripe_params.billing_postcode,d.owner.address.country=wc_stripe_params.billing_country),d},createSource:function(){var d=g.getOwnerDetails(),e="card";if(g.isBancontactChosen()&&(e="bancontact"),g.isSepaChosen()&&(e="sepa_debit"),g.isIdealChosen()&&(e="ideal"),g.isSofortChosen()&&(e="sofort"),g.isBitcoinChosen()&&(e="bitcoin"),g.isGiropayChosen()&&(e="giropay"),g.isAlipayChosen()&&(e="alipay"),"card"===e)b.createSource(c,d).then(g.sourceResponse);else{switch(e){case"bancontact":case"giropay":case"ideal":case"sofort":case"alipay":d.amount=a("#stripe-"+e+"-payment-data").data("amount"),d.currency=a("#stripe-"+e+"-payment-data").data("currency"),d.redirect={return_url:wc_stripe_params.return_url},wc_stripe_params.statement_descriptor&&(d.statement_descriptor=wc_stripe_params.statement_descriptor)}switch(e){case"sepa_debit":d.currency=a("#stripe-"+e+"-payment-data").data("currency"),d.owner.name=a("#stripe-sepa-owner").val(),d.sepa_debit={iban:a("#stripe-sepa-iban").val()};break;case"ideal":d.ideal={bank:a("#stripe-ideal-bank").val()};break;case"sofort":d.sofort={country:a("#stripe-sofort-country").val()};break;case"bitcoin":case"alipay":d.currency=a("#stripe-"+e+"-payment-data").data("currency"),d.amount=a("#stripe-"+e+"-payment-data").data("amount")}d.type=e,b.createSource(d).then(g.sourceResponse)}},sourceResponse:function(b){b.error?a(document.body).trigger("stripeError",b):"no"===wc_stripe_params.allow_prepaid_card&&"card"===b.source.type&&"prepaid"===b.source.card.funding?(b.error={message:wc_stripe_params.no_prepaid_card_msg},a(document.body).trigger("stripeError",b)):g.processStripeResponse(b.source)},createToken:function(){var b=a("#stripe-card-number").val(),c=a("#stripe-card-cvc").val(),d=a("#stripe-card-expiry").payment("cardExpiryVal"),e=a("#billing_first_name").length?a("#billing_first_name").val():wc_stripe_params.billing_first_name,f=a("#billing_last_name").length?a("#billing_last_name").val():wc_stripe_params.billing_last_name,h={number:b,cvc:c,exp_month:parseInt(d.month,10)||0,exp_year:parseInt(d.year,10)||0};e&&f&&(h.name=e+" "+f),a("#billing_address_1").length>0?(h.address_line1=a("#billing_address_1").val(),h.address_line2=a("#billing_address_2").val(),h.address_state=a("#billing_state").val(),h.address_city=a("#billing_city").val(),h.address_zip=a("#billing_postcode").val(),h.address_country=a("#billing_country").val()):wc_stripe_params.billing_address_1&&(h.address_line1=wc_stripe_params.billing_address_1,h.address_line2=wc_stripe_params.billing_address_2,h.address_state=wc_stripe_params.billing_state,h.address_city=wc_stripe_params.billing_city,h.address_zip=wc_stripe_params.billing_postcode,h.address_country=wc_stripe_params.billing_country),Stripe.setPublishableKey(wc_stripe_params.key),Stripe.createToken(h,g.onStripeTokenResponse)},onStripeTokenResponse:function(b,c){if(c.error)a(document).trigger("stripeError",c);else{if("no"===wc_stripe_params.allow_prepaid_card&&"prepaid"===c.card.funding)return c.error={message:wc_stripe_params.no_prepaid_card_msg},a(document).trigger("stripeError",{response:c}),!1;var d=c.id;g.form.append("<input type='hidden' class='stripe_token' name='stripe_token' value='"+d+"'/>"),a("form#add_payment_method").length&&a(g.form).off("submit",g.form.onSubmit),g.form.submit()}},onSubmit:function(b){if(g.isStripeChosen()&&!g.isStripeSaveCardChosen()&&!g.hasSource()&&!g.hasToken()){if(b.preventDefault(),"yes"===wc_stripe_params.is_stripe_checkout&&g.isStripeModalNeeded()&&g.isStripeCardChosen())return g.isMobile()?g.openModal():g.validateCheckout("modal"),!1;if(g.block(),g.isStripeCardChosen()&&"no"===wc_stripe_params.use_elements)return g.createToken(),!1;if(g.isBancontactChosen()||g.isGiropayChosen()||g.isIdealChosen()||g.isAlipayChosen())return a("form#order_review").length&&(a("form#order_review").off("submit",this.onSubmit),g.form.submit()),!0;if(g.isSofortChosen()){if("-1"===a("#stripe-bank-country").val()){var c={error:{message:wc_stripe_params.no_bank_country_msg}};return a(document.body).trigger("stripeError",c),!1}return a("form#order_review").length&&(a("form#order_review").off("submit",this.onSubmit),g.form.submit()),!0}return g.validateCheckout(),!1}if(a("form#add_payment_method").length){if(b.preventDefault(),"yes"===wc_stripe_params.is_stripe_checkout&&g.isStripeModalNeeded()&&g.isStripeCardChosen())return g.openModal(),!1;if(g.isSepaChosen()){if(""===a("#stripe-sepa-owner").val())return a(document.body).trigger("stripeError",{error:{message:wc_stripe_params.no_sepa_owner_msg}}),!1;if(""===a("#stripe-sepa-iban").val())return a(document.body).trigger("stripeError",{error:{message:wc_stripe_params.no_sepa_iban_msg}}),!1}return g.block(),g.isStripeCardChosen()&&"no"===wc_stripe_params.use_elements?(g.createToken(),!1):(g.createSource(),!1)}},onCCFormChange:function(){g.reset()},prepareSourceToServer:function(a){return{id:a.id,card:a.card?a.card:"",bitcoin:a.bitcoin?a.bitcoin:"",flow:a.flow,object:a.object,status:a.status,type:a.type,usage:a.usage}},processStripeResponse:function(b){g.reset(),g.form.append("<input type='hidden' class='stripe-source' name='stripe_source' value='"+JSON.stringify(g.prepareSourceToServer(b))+"'/>"),a("form#add_payment_method").length&&a(g.form).off("submit",g.form.onSubmit),g.form.submit()},reset:function(){a(".wc-stripe-error, .stripe-source, .stripe_token, .stripe-checkout-object").remove(),"yes"===wc_stripe_params.is_stripe_checkout&&(g.stripe_submit=!1)},getRequiredFields:function(){return g.form.find(".form-row.validate-required > input, .form-row.validate-required > select")},validateCheckout:function(b){void 0===b&&(b="");var c={nonce:wc_stripe_params.stripe_nonce,required_fields:g.getRequiredFields().serialize(),all_fields:g.form.serialize(),source_type:g.getSelectedPaymentElement().val(),is_add_payment_page:wc_stripe_params.is_add_payment_method_page};a.ajax({type:"POST",url:g.getAjaxURL("validate_checkout"),data:c,dataType:"json",success:function(c){if("success"===c)if("modal"===b)g.openModal();else{if(g.isSepaChosen()){if(""===a("#stripe-sepa-owner").val())return a(document.body).trigger("stripeError",{error:{message:wc_stripe_params.no_sepa_owner_msg}}),!1;if(""===a("#stripe-sepa-iban").val())return a(document.body).trigger("stripeError",{error:{message:wc_stripe_params.no_sepa_iban_msg}}),!1}g.createSource()}else c.messages&&(g.resetModal(),g.reset(),g.submitError(c.messages))}})},submitError:function(b){a(".woocommerce-NoticeGroup-checkout, .woocommerce-error, .woocommerce-message").remove(),g.form.prepend('<div class="woocommerce-NoticeGroup woocommerce-NoticeGroup-checkout">'+b+"</div>"),g.form.removeClass("processing").unblock(),g.form.find(".input-text, select, input:checkbox").blur(),a("html, body").animate({scrollTop:a("form.checkout").offset().top-100},1e3),a(document.body).trigger("checkout_error"),g.unblock()}};g.init()});
1
+ jQuery(function(a){"use strict";var b=Stripe(wc_stripe_params.key);if("yes"===wc_stripe_params.use_elements)var c,d,e,f=b.elements();var g={getAjaxURL:function(a){return wc_stripe_params.ajaxurl.toString().replace("%%endpoint%%","wc_stripe_"+a)},init:function(){"yes"===wc_stripe_params.is_change_payment_page&&a(document.body).trigger("wc-credit-card-form-init"),this.stripe_checkout_submit=!1,a("form.woocommerce-checkout").length&&(this.form=a("form.woocommerce-checkout")),a("form.woocommerce-checkout").on("checkout_place_order_stripe checkout_place_order_stripe_bancontact checkout_place_order_stripe_sofort checkout_place_order_stripe_giropay checkout_place_order_stripe_ideal checkout_place_order_stripe_alipay checkout_place_order_stripe_sepa checkout_place_order_stripe_bitcoin",this.onSubmit),a("form#order_review").length&&(this.form=a("form#order_review")),a("form#order_review").on("submit",this.onSubmit),a("form#add_payment_method").length&&(this.form=a("form#add_payment_method")),a("form#add_payment_method").on("submit",this.onSubmit),a("form.woocommerce-checkout").on("change","#stripe-bank-country",this.reset),a(document).on("stripeError",this.onError).on("checkout_error",this.reset);var b={base:{iconColor:"#666EE8",color:"#31325F",fontSize:"15px","::placeholder":{color:"#CFD7E0"}}},h={focus:"focused",empty:"empty",invalid:"invalid"};"yes"===wc_stripe_params.use_elements&&a("#stripe-card-element").length&&(b=wc_stripe_params.elements_styling?wc_stripe_params.elements_styling:b,h=wc_stripe_params.elements_classes?wc_stripe_params.elements_classes:h,"yes"===wc_stripe_params.inline_cc_form?(c=f.create("card",{style:b,hidePostalCode:!0}),c.addEventListener("change",function(b){g.onCCFormChange(),b.error&&a(document.body).trigger("stripeError",b)})):(c=f.create("cardNumber",{style:b,classes:h}),d=f.create("cardExpiry",{style:b,classes:h}),e=f.create("cardCvc",{style:b,classes:h}),c.addEventListener("change",function(b){g.onCCFormChange(),b.error&&a(document.body).trigger("stripeError",b)}),d.addEventListener("change",function(b){g.onCCFormChange(),b.error&&a(document.body).trigger("stripeError",b)}),e.addEventListener("change",function(b){g.onCCFormChange(),b.error&&a(document.body).trigger("stripeError",b)})),wc_stripe_params.is_checkout?a(document.body).on("updated_checkout",function(){c&&("yes"===wc_stripe_params.inline_cc_form?c.unmount("#stripe-card-element"):(c.unmount("#stripe-card-element"),d.unmount("#stripe-exp-element"),e.unmount("#stripe-cvc-element"))),"yes"===wc_stripe_params.inline_cc_form?c.mount("#stripe-card-element"):(c.mount("#stripe-card-element"),d.mount("#stripe-exp-element"),e.mount("#stripe-cvc-element"))}):(a("form#add_payment_method").length||a("form#order_review").length)&&("yes"===wc_stripe_params.inline_cc_form?c.mount("#stripe-card-element"):(c.mount("#stripe-card-element"),d.mount("#stripe-exp-element"),e.mount("#stripe-cvc-element"))))},isStripeChosen:function(){return a("#payment_method_stripe, #payment_method_stripe_bancontact, #payment_method_stripe_sofort, #payment_method_stripe_giropay, #payment_method_stripe_ideal, #payment_method_stripe_alipay, #payment_method_stripe_sepa, #payment_method_stripe_bitcoin").is(":checked")||"new"===a('input[name="wc-stripe-payment-token"]:checked').val()},isStripeSaveCardChosen:function(){return a("#payment_method_stripe").is(":checked")&&a('input[name="wc-stripe-payment-token"]').is(":checked")&&"new"!==a('input[name="wc-stripe-payment-token"]:checked').val()||a("#payment_method_stripe_sepa").is(":checked")&&a('input[name="wc-stripe_sepa-payment-token"]').is(":checked")&&"new"!==a('input[name="wc-stripe_sepa-payment-token"]:checked').val()},isStripeCardChosen:function(){return a("#payment_method_stripe").is(":checked")},isBancontactChosen:function(){return a("#payment_method_stripe_bancontact").is(":checked")},isGiropayChosen:function(){return a("#payment_method_stripe_giropay").is(":checked")},isIdealChosen:function(){return a("#payment_method_stripe_ideal").is(":checked")},isSofortChosen:function(){return a("#payment_method_stripe_sofort").is(":checked")},isAlipayChosen:function(){return a("#payment_method_stripe_alipay").is(":checked")},isSepaChosen:function(){return a("#payment_method_stripe_sepa").is(":checked")},isBitcoinChosen:function(){return a("#payment_method_stripe_bitcoin").is(":checked")},hasSource:function(){return 0<a("input.stripe-source").length},hasToken:function(){return 0<a("input.stripe_token").length},isMobile:function(){return!!/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)},isStripeModalNeeded:function(a){var b=g.form.find("input.stripe_token");return(!g.stripe_submit||!b)&&!!g.isStripeChosen()},block:function(){g.isMobile()?a.blockUI({message:null,overlayCSS:{background:"#fff",opacity:.6}}):g.form.block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},unblock:function(){g.isMobile()?a.unblockUI():g.form.unblock()},getSelectedPaymentElement:function(){return a('.payment_methods input[name="payment_method"]:checked')},openModal:function(){var c=g.form,d=a("#stripe-payment-data");g.reset();var e=function(a){if(c.find("input.stripe_source").remove(),"token"===a.object)b.createSource({type:"card",token:a.id}).then(g.sourceResponse);else if("source"===a.object){var d={source:a};g.sourceResponse(d)}};StripeCheckout.open({key:wc_stripe_params.key,billingAddress:"yes"===wc_stripe_params.stripe_checkout_require_billing_address,amount:d.data("amount"),name:d.data("name"),description:d.data("description"),currency:d.data("currency"),image:d.data("image"),bitcoin:d.data("bitcoin"),locale:d.data("locale"),email:a("#billing_email").val()||d.data("email"),panelLabel:d.data("panel-label"),allowRememberMe:d.data("allow-remember-me"),token:e,closed:g.onClose()})},resetModal:function(){g.reset(),g.stripe_checkout_submit=!1},onClose:function(){g.unblock()},onError:function(b,c){var d=c.error.message,e=g.getSelectedPaymentElement().parent(".wc_payment_method, .woocommerce-PaymentMethod").find(".stripe-source-errors");"invalid_request_error"!==c.error.type&&"api_connection_error"!==c.error.type&&"api_error"!==c.error.type&&"authentication_error"!==c.error.type&&"rate_limit_error"!==c.error.type||(d=wc_stripe_params.invalid_request_error),"card_error"===c.error.type&&wc_stripe_params.hasOwnProperty(c.error.code)&&(d=wc_stripe_params[c.error.code]),"validation_error"===c.error.type&&wc_stripe_params.hasOwnProperty(c.error.code)&&(d=wc_stripe_params[c.error.code]),g.reset(),a(".woocommerce-NoticeGroup-checkout").remove(),console.log(c.error.message),a(e).html('<ul class="woocommerce_error woocommerce-error wc-stripe-error"><li>'+d+"</li></ul>"),a("html, body").animate({scrollTop:a(".wc-stripe-error").offset().top-200},200),g.unblock()},getOwnerDetails:function(){var b=a("#billing_first_name").length?a("#billing_first_name").val():wc_stripe_params.billing_first_name,c=a("#billing_last_name").length?a("#billing_last_name").val():wc_stripe_params.billing_last_name,d={owner:{name:"",address:{},email:"",phone:""}};return d.owner.name=b,b&&c&&(d.owner.name=b+" "+c),d.owner.email=a("#billing_email").val(),d.owner.phone=a("#billing_phone").val(),void 0!==d.owner.phone&&0>=d.owner.phone.length&&delete d.owner.phone,void 0!==d.owner.email&&0>=d.owner.email.length&&delete d.owner.email,a("#billing_address_1").length>0?(d.owner.address.line1=a("#billing_address_1").val(),d.owner.address.line2=a("#billing_address_2").val(),d.owner.address.state=a("#billing_state").val(),d.owner.address.city=a("#billing_city").val(),d.owner.address.postal_code=a("#billing_postcode").val(),d.owner.address.country=a("#billing_country").val()):wc_stripe_params.billing_address_1&&(d.owner.address.line1=wc_stripe_params.billing_address_1,d.owner.address.line2=wc_stripe_params.billing_address_2,d.owner.address.state=wc_stripe_params.billing_state,d.owner.address.city=wc_stripe_params.billing_city,d.owner.address.postal_code=wc_stripe_params.billing_postcode,d.owner.address.country=wc_stripe_params.billing_country),d},createSource:function(){var d=g.getOwnerDetails(),e="card";if(g.isBancontactChosen()&&(e="bancontact"),g.isSepaChosen()&&(e="sepa_debit"),g.isIdealChosen()&&(e="ideal"),g.isSofortChosen()&&(e="sofort"),g.isBitcoinChosen()&&(e="bitcoin"),g.isGiropayChosen()&&(e="giropay"),g.isAlipayChosen()&&(e="alipay"),"card"===e)b.createSource(c,d).then(g.sourceResponse);else{switch(e){case"bancontact":case"giropay":case"ideal":case"sofort":case"alipay":d.amount=a("#stripe-"+e+"-payment-data").data("amount"),d.currency=a("#stripe-"+e+"-payment-data").data("currency"),d.redirect={return_url:wc_stripe_params.return_url},wc_stripe_params.statement_descriptor&&(d.statement_descriptor=wc_stripe_params.statement_descriptor)}switch(e){case"sepa_debit":d.currency=a("#stripe-"+e+"-payment-data").data("currency"),d.owner.name=a("#stripe-sepa-owner").val(),d.sepa_debit={iban:a("#stripe-sepa-iban").val()};break;case"ideal":d.ideal={bank:a("#stripe-ideal-bank").val()};break;case"bitcoin":case"alipay":d.currency=a("#stripe-"+e+"-payment-data").data("currency"),d.amount=a("#stripe-"+e+"-payment-data").data("amount")}d.type=e,b.createSource(d).then(g.sourceResponse)}},sourceResponse:function(b){b.error?a(document.body).trigger("stripeError",b):"no"===wc_stripe_params.allow_prepaid_card&&"card"===b.source.type&&"prepaid"===b.source.card.funding?(b.error={message:wc_stripe_params.no_prepaid_card_msg},a(document.body).trigger("stripeError",b)):g.processStripeResponse(b.source)},createToken:function(){var b=a("#stripe-card-number").val(),c=a("#stripe-card-cvc").val(),d=a("#stripe-card-expiry").payment("cardExpiryVal"),e=a("#billing_first_name").length?a("#billing_first_name").val():wc_stripe_params.billing_first_name,f=a("#billing_last_name").length?a("#billing_last_name").val():wc_stripe_params.billing_last_name,h={number:b,cvc:c,exp_month:parseInt(d.month,10)||0,exp_year:parseInt(d.year,10)||0};e&&f&&(h.name=e+" "+f),a("#billing_address_1").length>0?(h.address_line1=a("#billing_address_1").val(),h.address_line2=a("#billing_address_2").val(),h.address_state=a("#billing_state").val(),h.address_city=a("#billing_city").val(),h.address_zip=a("#billing_postcode").val(),h.address_country=a("#billing_country").val()):wc_stripe_params.billing_address_1&&(h.address_line1=wc_stripe_params.billing_address_1,h.address_line2=wc_stripe_params.billing_address_2,h.address_state=wc_stripe_params.billing_state,h.address_city=wc_stripe_params.billing_city,h.address_zip=wc_stripe_params.billing_postcode,h.address_country=wc_stripe_params.billing_country),Stripe.setPublishableKey(wc_stripe_params.key),Stripe.createToken(h,g.onStripeTokenResponse)},onStripeTokenResponse:function(b,c){if(c.error)a(document).trigger("stripeError",c);else{if("no"===wc_stripe_params.allow_prepaid_card&&"prepaid"===c.card.funding)return c.error={message:wc_stripe_params.no_prepaid_card_msg},a(document).trigger("stripeError",{response:c}),!1;var d=c.id;g.form.append("<input type='hidden' class='stripe_token' name='stripe_token' value='"+d+"'/>"),a("form#add_payment_method").length&&a(g.form).off("submit",g.form.onSubmit),g.form.submit()}},onSubmit:function(b){if(g.isStripeChosen()&&!g.isStripeSaveCardChosen()&&!g.hasSource()&&!g.hasToken()){if(b.preventDefault(),"yes"===wc_stripe_params.is_stripe_checkout&&g.isStripeModalNeeded()&&g.isStripeCardChosen())return g.isMobile()?g.openModal():g.validateCheckout("modal"),!1;if(g.block(),g.isStripeCardChosen()&&"no"===wc_stripe_params.use_elements)return g.createToken(),!1;if(g.isBancontactChosen()||g.isGiropayChosen()||g.isIdealChosen()||g.isAlipayChosen())return a("form#order_review").length&&(a("form#order_review").off("submit",this.onSubmit),g.form.submit()),!0;if(g.isSofortChosen()){if("-1"===a("#stripe-bank-country").val()){var c={error:{message:wc_stripe_params.no_bank_country_msg}};return a(document.body).trigger("stripeError",c),!1}return a("form#order_review").length&&(a("form#order_review").off("submit",this.onSubmit),g.form.submit()),!0}return g.validateCheckout(),!1}if(a("form#add_payment_method").length){if(b.preventDefault(),"yes"===wc_stripe_params.is_stripe_checkout&&g.isStripeModalNeeded()&&g.isStripeCardChosen())return g.openModal(),!1;if(g.isSepaChosen()){if(""===a("#stripe-sepa-owner").val())return a(document.body).trigger("stripeError",{error:{message:wc_stripe_params.no_sepa_owner_msg}}),!1;if(""===a("#stripe-sepa-iban").val())return a(document.body).trigger("stripeError",{error:{message:wc_stripe_params.no_sepa_iban_msg}}),!1}return g.block(),g.isStripeCardChosen()&&"no"===wc_stripe_params.use_elements?(g.createToken(),!1):(g.createSource(),!1)}},onCCFormChange:function(){g.reset()},prepareSourceToServer:function(a){return{id:a.id,card:a.card?a.card:"",bitcoin:a.bitcoin?a.bitcoin:"",flow:a.flow,object:a.object,status:a.status,type:a.type,usage:a.usage}},processStripeResponse:function(b){g.reset(),g.form.append("<input type='hidden' class='stripe-source' name='stripe_source' value='"+JSON.stringify(g.prepareSourceToServer(b))+"'/>"),a("form#add_payment_method").length&&a(g.form).off("submit",g.form.onSubmit),g.form.submit()},reset:function(){a(".wc-stripe-error, .stripe-source, .stripe_token, .stripe-checkout-object").remove(),"yes"===wc_stripe_params.is_stripe_checkout&&(g.stripe_submit=!1)},getRequiredFields:function(){return g.form.find(".form-row.validate-required > input, .form-row.validate-required > select, .form-row.validate-required > textarea")},validateCheckout:function(b){void 0===b&&(b="");var c={nonce:wc_stripe_params.stripe_nonce,required_fields:g.getRequiredFields().serialize(),all_fields:g.form.serialize(),source_type:g.getSelectedPaymentElement().val(),is_add_payment_page:wc_stripe_params.is_add_payment_method_page};a.ajax({type:"POST",url:g.getAjaxURL("validate_checkout"),data:c,dataType:"json",success:function(c){if("success"===c)if("modal"===b)g.openModal();else{if(g.isSepaChosen()){if(""===a("#stripe-sepa-owner").val())return a(document.body).trigger("stripeError",{error:{message:wc_stripe_params.no_sepa_owner_msg}}),!1;if(""===a("#stripe-sepa-iban").val())return a(document.body).trigger("stripeError",{error:{message:wc_stripe_params.no_sepa_iban_msg}}),!1}g.createSource()}else c.messages&&(g.resetModal(),g.reset(),g.submitError(c.messages))}})},submitError:function(b){a(".woocommerce-NoticeGroup-checkout, .woocommerce-error, .woocommerce-message").remove(),g.form.prepend('<div class="woocommerce-NoticeGroup woocommerce-NoticeGroup-checkout">'+b+"</div>"),g.form.removeClass("processing").unblock(),g.form.find(".input-text, select, input:checkbox").blur(),a("html, body").animate({scrollTop:a("form.checkout").offset().top-100},500),a(document.body).trigger("checkout_error"),g.unblock()}};g.init()});
changelog.txt CHANGED
@@ -1,5 +1,23 @@
1
  *** Changelog ***
2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  = 4.0.1 - 2018-01-11 =
4
  * Fix - Add payment method conflict with terms and agreement page.
5
  * Fix - Checkout validation checkout field names/labels were not translated.
1
  *** Changelog ***
2
 
3
+ = 4.0.2 - 2018-01-17 =
4
+ * Add - 3DS support on Stripe Checkout ( Modal Popup ).
5
+ * Add - Filter to enable Payment Request Button on Checkout 'wc_stripe_show_payment_request_on_checkout'.
6
+ * Add - Filter to remove all fields from checkout validation. 'wc_stripe_validate_checkout_all_fields'.
7
+ * Add - Filter to remove required fields from checkout validation. 'wc_stripe_validate_checkout_required_fields'.
8
+ * Add - Custom error exceptions class.
9
+ * Add - Credit card field names for clarity.
10
+ * Fix - Possible conflicts with payment request totals when subscriptions is active.
11
+ * Fix - Undefined notice on save card via subscriptions if card is deleted.
12
+ * Fix - Error translation issue when 3DS is required.
13
+ * Fix - Possible 404 if getting customer source if no id was found.
14
+ * Fix - Add payment method was still available when save cards setting is disabled.
15
+ * Fix - In certain cases when webhook is used, refunds can show as doubled when it is not.
16
+ * Fix - Stripe checkout with bitcoin returns error on processing.
17
+ * Tweak - Remove Sofort country selection in favor of using the billing country.
18
+ * Tweak - Add payment page CSS styling.
19
+ * Tweak - Error log to show full response object.
20
+
21
  = 4.0.1 - 2018-01-11 =
22
  * Fix - Add payment method conflict with terms and agreement page.
23
  * Fix - Checkout validation checkout field names/labels were not translated.
includes/abstracts/abstract-wc-stripe-payment-gateway.php CHANGED
@@ -56,6 +56,34 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
56
  }
57
  }
58
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  /**
60
  * Validates that the order meets the minimum order amount
61
  * set by Stripe.
@@ -67,7 +95,7 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
67
  public function validate_minimum_order_amount( $order ) {
68
  if ( $order->get_total() * 100 < WC_Stripe_Helper::get_minimum_amount() ) {
69
  /* translators: 1) dollar amount */
70
- throw new Exception( sprintf( __( 'Sorry, the minimum allowed order total is %1$s to use this payment method.', 'woocommerce-gateway-stripe' ), wc_price( WC_Stripe_Helper::get_minimum_amount() / 100 ) ) );
71
  }
72
  }
73
 
@@ -169,7 +197,7 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
169
  $post_data['statement_descriptor'] = WC_Stripe_Helper::clean_statement_descriptor( $statement_descriptor );
170
  }
171
 
172
- $post_data['capture'] = $capture ? 'true' : 'false';
173
  break;
174
  }
175
 
@@ -210,8 +238,10 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
210
 
211
  $order_id = WC_Stripe_Helper::is_pre_30() ? $order->id : $order->get_id();
212
 
 
 
213
  // Store charge data
214
- WC_Stripe_Helper::is_pre_30() ? update_post_meta( $order_id, '_stripe_charge_captured', $response->captured ? 'yes' : 'no' ) : $order->update_meta_data( '_stripe_charge_captured', $response->captured ? 'yes' : 'no' );
215
 
216
  // Store other data such as fees
217
  if ( isset( $response->balance_transaction ) && isset( $response->balance_transaction->fee ) ) {
@@ -223,7 +253,7 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
223
  WC_Stripe_Helper::is_pre_30() ? update_post_meta( $order_id, self::META_NAME_NET, $net ) : $order->update_meta_data( self::META_NAME_NET, $net );
224
  }
225
 
226
- if ( $response->captured ) {
227
  /**
228
  * Charge can be captured but in a pending state. Payment methods
229
  * that are asynchronous may take couple days to clear. Webhook will
@@ -248,9 +278,9 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
248
  }
249
 
250
  if ( 'failed' === $response->status ) {
251
- $error_msg = __( 'Payment processing failed. Please retry.', 'woocommerce-gateway-stripe' );
252
- $order->add_order_note( $error_msg );
253
- throw new Exception( $error_msg );
254
  }
255
  } else {
256
  WC_Stripe_Helper::is_pre_30() ? update_post_meta( $order_id, '_transaction_id', $response->id, true ) : $order->set_transaction_id( $response->id );
@@ -358,7 +388,7 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
358
  $source = $customer->add_source( $source->id );
359
 
360
  if ( ! empty( $source->error ) ) {
361
- throw new Exception( $source->error->message );
362
  }
363
  } else {
364
  $source = $source->id;
@@ -371,7 +401,7 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
371
 
372
  if ( ! $wc_token || $wc_token->get_user_id() !== get_current_user_id() ) {
373
  WC()->session->set( 'refresh_totals', true );
374
- throw new Exception( __( 'Invalid payment method. Please input a new card number.', 'woocommerce-gateway-stripe' ) );
375
  }
376
 
377
  $source = $wc_token->get_token();
@@ -384,7 +414,7 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
384
  $source = $customer->add_source( $stripe_token );
385
 
386
  if ( ! empty( $source->error ) ) {
387
- throw new Exception( $source->error->message );
388
  }
389
  } else {
390
  $set_customer = false;
@@ -564,8 +594,12 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
564
 
565
  if ( ! empty( $response->error ) ) {
566
  WC_Stripe_Logger::log( 'Error: ' . $response->error->message );
 
567
  return $response;
 
568
  } elseif ( ! empty( $response->id ) ) {
 
 
569
  $amount = wc_price( $response->amount / 100 );
570
 
571
  if ( in_array( strtolower( $order->get_currency() ), WC_Stripe_Helper::no_decimal_currencies() ) ) {
56
  }
57
  }
58
 
59
+ /**
60
+ * All payment icons that work with Stripe.
61
+ *
62
+ * @since 4.0.0
63
+ * @version 4.0.0
64
+ * @return array
65
+ */
66
+ public function payment_icons() {
67
+ return apply_filters( 'wc_stripe_payment_icons', array(
68
+ 'visa' => '<i class="stripe-pf stripe-pf-visa stripe-pf-right" alt="Visa" aria-hidden="true"></i>',
69
+ 'amex' => '<i class="stripe-pf stripe-pf-american-express stripe-pf-right" alt="Amex" aria-hidden="true"></i>',
70
+ 'mastercard' => '<i class="stripe-pf stripe-pf-mastercard stripe-pf-right" alt="Mastercard" aria-hidden="true"></i>',
71
+ 'discover' => '<i class="stripe-pf stripe-pf-discover stripe-pf-right" alt="Discover" aria-hidden="true"></i>',
72
+ 'diners' => '<i class="stripe-pf stripe-pf-diners stripe-pf-right" alt="Diners" aria-hidden="true"></i>',
73
+ 'jcb' => '<i class="stripe-pf stripe-pf-jcb stripe-pf-right" alt="JCB" aria-hidden="true"></i>',
74
+ 'alipay' => '<i class="stripe-pf stripe-pf-alipay stripe-pf-right" alt="Alipay" aria-hidden="true"></i>',
75
+ 'wechat' => '<i class="stripe-pf stripe-pf-wechat-pay stripe-pf-right" alt="Wechat Pay" aria-hidden="true"></i>',
76
+ 'bitcoin' => '<i class="stripe-pf stripe-pf-bitcoin stripe-pf-right" alt="Bitcoin" aria-hidden="true"></i>',
77
+ 'bancontact' => '<i class="stripe-pf stripe-pf-bancontact-mister-cash stripe-pf-right" alt="Bancontact" aria-hidden="true"></i>',
78
+ 'ideal' => '<i class="stripe-pf stripe-pf-ideal stripe-pf-right" alt="iDeal" aria-hidden="true"></i>',
79
+ 'p24' => '<i class="stripe-pf stripe-pf-p24 stripe-pf-right" alt="P24" aria-hidden="true"></i>',
80
+ 'giropay' => '<i class="stripe-pf stripe-pf-giropay stripe-pf-right" alt="Giropay" aria-hidden="true"></i>',
81
+ 'eps' => '<i class="stripe-pf stripe-pf-eps stripe-pf-right" alt="EPS" aria-hidden="true"></i>',
82
+ 'sofort' => '<i class="stripe-pf stripe-pf-sofort stripe-pf-right" alt="SOFORT" aria-hidden="true"></i>',
83
+ 'sepa' => '<i class="stripe-pf stripe-pf-sepa stripe-pf-right" alt="SEPA" aria-hidden="true"></i>',
84
+ ) );
85
+ }
86
+
87
  /**
88
  * Validates that the order meets the minimum order amount
89
  * set by Stripe.
95
  public function validate_minimum_order_amount( $order ) {
96
  if ( $order->get_total() * 100 < WC_Stripe_Helper::get_minimum_amount() ) {
97
  /* translators: 1) dollar amount */
98
+ throw new WC_Stripe_Exception( 'Did not meet minimum amount', sprintf( __( 'Sorry, the minimum allowed order total is %1$s to use this payment method.', 'woocommerce-gateway-stripe' ), wc_price( WC_Stripe_Helper::get_minimum_amount() / 100 ) ) );
99
  }
100
  }
101
 
197
  $post_data['statement_descriptor'] = WC_Stripe_Helper::clean_statement_descriptor( $statement_descriptor );
198
  }
199
 
200
+ $post_data['capture'] = $capture ? 'true' : 'false';
201
  break;
202
  }
203
 
238
 
239
  $order_id = WC_Stripe_Helper::is_pre_30() ? $order->id : $order->get_id();
240
 
241
+ $captured = ( isset( $response->captured ) && $response->captured ) ? 'yes' : 'no';
242
+
243
  // Store charge data
244
+ WC_Stripe_Helper::is_pre_30() ? update_post_meta( $order_id, '_stripe_charge_captured', $captured ) : $order->update_meta_data( '_stripe_charge_captured', $captured );
245
 
246
  // Store other data such as fees
247
  if ( isset( $response->balance_transaction ) && isset( $response->balance_transaction->fee ) ) {
253
  WC_Stripe_Helper::is_pre_30() ? update_post_meta( $order_id, self::META_NAME_NET, $net ) : $order->update_meta_data( self::META_NAME_NET, $net );
254
  }
255
 
256
+ if ( 'yes' === $captured ) {
257
  /**
258
  * Charge can be captured but in a pending state. Payment methods
259
  * that are asynchronous may take couple days to clear. Webhook will
278
  }
279
 
280
  if ( 'failed' === $response->status ) {
281
+ $localized_message = __( 'Payment processing failed. Please retry.', 'woocommerce-gateway-stripe' );
282
+ $order->add_order_note( $localized_message );
283
+ throw new WC_Stripe_Exception( print_r( $response, true ), $localized_message );
284
  }
285
  } else {
286
  WC_Stripe_Helper::is_pre_30() ? update_post_meta( $order_id, '_transaction_id', $response->id, true ) : $order->set_transaction_id( $response->id );
388
  $source = $customer->add_source( $source->id );
389
 
390
  if ( ! empty( $source->error ) ) {
391
+ throw new WC_Stripe_Exception( print_r( $source, true ), $source->error->message );
392
  }
393
  } else {
394
  $source = $source->id;
401
 
402
  if ( ! $wc_token || $wc_token->get_user_id() !== get_current_user_id() ) {
403
  WC()->session->set( 'refresh_totals', true );
404
+ throw new WC_Stripe_Exception( 'Invalid payment method', __( 'Invalid payment method. Please input a new card number.', 'woocommerce-gateway-stripe' ) );
405
  }
406
 
407
  $source = $wc_token->get_token();
414
  $source = $customer->add_source( $stripe_token );
415
 
416
  if ( ! empty( $source->error ) ) {
417
+ throw new WC_Stripe_Exception( print_r( $source, true ), $source->error->message );
418
  }
419
  } else {
420
  $set_customer = false;
594
 
595
  if ( ! empty( $response->error ) ) {
596
  WC_Stripe_Logger::log( 'Error: ' . $response->error->message );
597
+
598
  return $response;
599
+
600
  } elseif ( ! empty( $response->id ) ) {
601
+ WC_Stripe_Helper::is_pre_30() ? update_post_meta( $order_id, '_stripe_refund_id', $response->id ) : $order->update_meta_data( '_stripe_refund_id', $response->id );
602
+
603
  $amount = wc_price( $response->amount / 100 );
604
 
605
  if ( in_array( strtolower( $order->get_currency() ), WC_Stripe_Helper::no_decimal_currencies() ) ) {
includes/class-wc-gateway-stripe.php CHANGED
@@ -183,31 +183,16 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
183
  }
184
 
185
  /**
186
- * All payment icons that work with Stripe.
187
  *
188
- * @since 4.0.0
189
- * @version 4.0.0
190
- * @return array
191
  */
192
- public function payment_icons() {
193
- return apply_filters( 'wc_stripe_payment_icons', array(
194
- 'visa' => '<i class="stripe-pf stripe-pf-visa stripe-pf-right" alt="Visa" aria-hidden="true"></i>',
195
- 'amex' => '<i class="stripe-pf stripe-pf-american-express stripe-pf-right" alt="Amex" aria-hidden="true"></i>',
196
- 'mastercard' => '<i class="stripe-pf stripe-pf-mastercard stripe-pf-right" alt="Mastercard" aria-hidden="true"></i>',
197
- 'discover' => '<i class="stripe-pf stripe-pf-discover stripe-pf-right" alt="Discover" aria-hidden="true"></i>',
198
- 'diners' => '<i class="stripe-pf stripe-pf-diners stripe-pf-right" alt="Diners" aria-hidden="true"></i>',
199
- 'jcb' => '<i class="stripe-pf stripe-pf-jcb stripe-pf-right" alt="JCB" aria-hidden="true"></i>',
200
- 'alipay' => '<i class="stripe-pf stripe-pf-alipay stripe-pf-right" alt="Alipay" aria-hidden="true"></i>',
201
- 'wechat' => '<i class="stripe-pf stripe-pf-wechat-pay stripe-pf-right" alt="Wechat Pay" aria-hidden="true"></i>',
202
- 'bitcoin' => '<i class="stripe-pf stripe-pf-bitcoin stripe-pf-right" alt="Bitcoin" aria-hidden="true"></i>',
203
- 'bancontact' => '<i class="stripe-pf stripe-pf-bancontact-mister-cash stripe-pf-right" alt="Bancontact" aria-hidden="true"></i>',
204
- 'ideal' => '<i class="stripe-pf stripe-pf-ideal stripe-pf-right" alt="iDeal" aria-hidden="true"></i>',
205
- 'p24' => '<i class="stripe-pf stripe-pf-p24 stripe-pf-right" alt="P24" aria-hidden="true"></i>',
206
- 'giropay' => '<i class="stripe-pf stripe-pf-giropay stripe-pf-right" alt="Giropay" aria-hidden="true"></i>',
207
- 'eps' => '<i class="stripe-pf stripe-pf-eps stripe-pf-right" alt="EPS" aria-hidden="true"></i>',
208
- 'sofort' => '<i class="stripe-pf stripe-pf-sofort stripe-pf-right" alt="SOFORT" aria-hidden="true"></i>',
209
- 'sepa' => '<i class="stripe-pf stripe-pf-sepa stripe-pf-right" alt="SEPA" aria-hidden="true"></i>',
210
- ) );
211
  }
212
 
213
  /**
@@ -426,7 +411,7 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
426
  data-name="' . esc_attr( $this->statement_descriptor ) . '"
427
  data-currency="' . esc_attr( strtolower( get_woocommerce_currency() ) ) . '"
428
  data-image="' . esc_attr( $this->stripe_checkout_image ) . '"
429
- data-bitcoin="' . esc_attr( $this->bitcoin ? 'true' : 'false' ) . '"
430
  data-locale="' . esc_attr( $this->stripe_checkout_locale ? $this->stripe_checkout_locale : 'en' ) . '"
431
  data-three-d-secure="' . esc_attr( $this->three_d_secure ? 'true' : 'false' ) . '"
432
  data-allow-remember-me="' . esc_attr( $this->saved_cards ? 'true' : 'false' ) . '">';
@@ -471,24 +456,38 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
471
  ?>
472
  <fieldset id="wc-<?php echo esc_attr( $this->id ); ?>-cc-form" class="wc-credit-card-form wc-payment-form" style="background:transparent;">
473
  <?php do_action( 'woocommerce_credit_card_form_start', $this->id ); ?>
474
- <label for="card-element">
475
- <?php esc_html_e( 'Credit or debit card', 'woocommerce-gateway-stripe' ); ?>
476
- </label>
477
 
478
  <?php if ( $this->inline_cc_form ) { ?>
479
- <div id="stripe-card-element" style="background:#f2f2f2;padding:0 1em;box-shadow:inset 0 1px 1px rgba(0,0,0,.125);margin:5px 0;padding:10px 5px;">
 
 
 
 
480
  <!-- a Stripe Element will be inserted here. -->
481
  </div>
482
  <?php } else { ?>
483
- <div id="stripe-card-element" class="form-row form-row-wide" style="background:#f2f2f2;padding:0 1em;box-shadow:inset 0 1px 1px rgba(0,0,0,.125);margin:5px 0;padding:10px 5px;">
484
- <!-- a Stripe Element will be inserted here. -->
 
 
 
 
485
  </div>
486
- <div id="stripe-exp-element" class="form-row form-row-first" style="background:#f2f2f2;padding:0 1em;box-shadow:inset 0 1px 1px rgba(0,0,0,.125);margin:5px 0;padding:10px 5px;">
487
- <!-- a Stripe Element will be inserted here. -->
 
 
 
 
 
488
  </div>
489
- <div id="stripe-cvc-element" class="form-row form-row-last" style="background:#f2f2f2;padding:0 1em;box-shadow:inset 0 1px 1px rgba(0,0,0,.125);margin:5px 0;padding:10px 5px;">
 
 
 
490
  <!-- a Stripe Element will be inserted here. -->
491
  </div>
 
492
  <div class="clear"></div>
493
  <?php } ?>
494
 
@@ -653,14 +652,14 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
653
  $stripe_checkout_object = ! empty( $_POST['stripe_checkout_object'] ) ? json_decode( wc_clean( stripslashes( $_POST['stripe_checkout_object'] ) ) ) : false;
654
 
655
  if ( $stripe_checkout_object && 'token' === $stripe_checkout_object->object && 'prepaid' === $stripe_checkout_object->card->funding ) {
656
- $error_msg = __( 'Sorry, we\'re not accepting prepaid cards at this time. Your credit card has not been charge. Please try with alternative payment method.', 'woocommerce-gateway-stripe' );
657
- throw new Exception( $error_msg );
658
  }
659
  }
660
 
661
  if ( empty( $prepared_source->source ) ) {
662
- $error_msg = __( 'Payment processing failed. Please retry.', 'woocommerce-gateway-stripe' );
663
- throw new Exception( $error_msg );
664
  }
665
 
666
  // Store source to order meta.
@@ -680,16 +679,16 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
680
  * Note that if we need to save source, the original source must be first
681
  * attached to a customer in Stripe before it can be charged.
682
  */
683
- if ( $source_object && ( 'card' === $source_object->type && 'required' === $source_object->card->three_d_secure || ( $this->three_d_secure && 'optional' === $source_object->card->three_d_secure ) ) ) {
684
 
685
  $response = $this->create_3ds_source( $order, $source_object );
686
 
687
  if ( ! empty( $response->error ) ) {
688
- $message = $response->error->message;
689
 
690
- $order->add_order_note( $message );
691
 
692
- throw new Exception( $message );
693
  }
694
 
695
  // Update order meta with 3DS source.
@@ -720,9 +719,9 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
720
  sleep( 5 );
721
  return $this->process_payment( $order_id, false, $force_save_source );
722
  } else {
723
- $message = 'API connection error and retries exhausted.';
724
- $order->add_order_note( $message );
725
- throw new Exception( $message );
726
  }
727
  }
728
 
@@ -735,18 +734,22 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
735
  // Source param wrong? The CARD may have been deleted on stripe's end. Remove token and show message.
736
  $wc_token = WC_Payment_Tokens::get( $prepared_source->token_id );
737
  $wc_token->delete();
738
- $message = __( 'This card is no longer available and has been removed.', 'woocommerce-gateway-stripe' );
739
- $order->add_order_note( $message );
740
- throw new Exception( $message );
741
  }
742
 
743
  $localized_messages = WC_Stripe_Helper::get_localized_messages();
744
 
745
- $message = isset( $localized_messages[ $response->error->type ] ) ? $localized_messages[ $response->error->type ] : $response->error->message;
 
 
 
 
746
 
747
- $order->add_order_note( $message );
748
 
749
- throw new Exception( $message );
750
  }
751
 
752
  do_action( 'wc_gateway_stripe_process_payment', $response, $order );
@@ -766,8 +769,8 @@ class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway {
766
  'redirect' => $this->get_return_url( $order ),
767
  );
768
 
769
- } catch ( Exception $e ) {
770
- wc_add_notice( $e->getMessage(), 'error' );
771
  WC_Stripe_Logger::log( 'Error: ' . $e->getMessage() );
772
 
773
  do_action( 'wc_gateway_stripe_process_payment_error', $e, $order );
183
  }
184
 
185
  /**
186
+ * Checks if gateway should be available to use.
187
  *
188
+ * @since 4.0.2
 
 
189
  */
190
+ public function is_available() {
191
+ if ( is_add_payment_method_page() && ! $this->saved_cards ) {
192
+ return false;
193
+ }
194
+
195
+ return parent::is_available();
 
 
 
 
 
 
 
 
 
 
 
 
 
196
  }
197
 
198
  /**
411
  data-name="' . esc_attr( $this->statement_descriptor ) . '"
412
  data-currency="' . esc_attr( strtolower( get_woocommerce_currency() ) ) . '"
413
  data-image="' . esc_attr( $this->stripe_checkout_image ) . '"
414
+ data-bitcoin="' . esc_attr( ( $this->bitcoin && $this->capture ) ? 'true' : 'false' ) . '"
415
  data-locale="' . esc_attr( $this->stripe_checkout_locale ? $this->stripe_checkout_locale : 'en' ) . '"
416
  data-three-d-secure="' . esc_attr( $this->three_d_secure ? 'true' : 'false' ) . '"
417
  data-allow-remember-me="' . esc_attr( $this->saved_cards ? 'true' : 'false' ) . '">';
456
  ?>
457
  <fieldset id="wc-<?php echo esc_attr( $this->id ); ?>-cc-form" class="wc-credit-card-form wc-payment-form" style="background:transparent;">
458
  <?php do_action( 'woocommerce_credit_card_form_start', $this->id ); ?>
 
 
 
459
 
460
  <?php if ( $this->inline_cc_form ) { ?>
461
+ <label for="card-element">
462
+ <?php esc_html_e( 'Credit or debit card', 'woocommerce-gateway-stripe' ); ?>
463
+ </label>
464
+
465
+ <div id="stripe-card-element" style="background:#fff;padding:0 1em;border:1px solid #ddd;margin:5px 0;padding:10px 5px;">
466
  <!-- a Stripe Element will be inserted here. -->
467
  </div>
468
  <?php } else { ?>
469
+ <div class="form-row form-row-wide">
470
+ <label><?php _e( 'Card Number', 'woocommerce-gateway-stripe' ); ?><span class="required">*</span></label>
471
+
472
+ <div id="stripe-card-element" style="background:#fff;padding:0 1em;border:1px solid #ddd;margin:5px 0;padding:10px 5px;">
473
+ <!-- a Stripe Element will be inserted here. -->
474
+ </div>
475
  </div>
476
+
477
+ <div class="form-row form-row-first">
478
+ <label><?php _e( 'Expiry Date', 'woocommerce-gateway-stripe' ); ?><span class="required">*</span></label>
479
+
480
+ <div id="stripe-exp-element" style="background:#fff;padding:0 1em;border:1px solid #ddd;margin:5px 0;padding:10px 5px;">
481
+ <!-- a Stripe Element will be inserted here. -->
482
+ </div>
483
  </div>
484
+
485
+ <div class="form-row form-row-last">
486
+ <label><?php _e( 'Card Code (CVC)', 'woocommerce-gateway-stripe' ); ?><span class="required">*</span></label>
487
+ <div id="stripe-cvc-element" style="background:#fff;padding:0 1em;border:1px solid #ddd;margin:5px 0;padding:10px 5px;">
488
  <!-- a Stripe Element will be inserted here. -->
489
  </div>
490
+ </div>
491
  <div class="clear"></div>
492
  <?php } ?>
493
 
652
  $stripe_checkout_object = ! empty( $_POST['stripe_checkout_object'] ) ? json_decode( wc_clean( stripslashes( $_POST['stripe_checkout_object'] ) ) ) : false;
653
 
654
  if ( $stripe_checkout_object && 'token' === $stripe_checkout_object->object && 'prepaid' === $stripe_checkout_object->card->funding ) {
655
+ $localized_message = __( 'Sorry, we\'re not accepting prepaid cards at this time. Your credit card has not been charge. Please try with alternative payment method.', 'woocommerce-gateway-stripe' );
656
+ throw new WC_Stripe_Exception( print_r( $stripe_checkout_object, true ), $localized_message );
657
  }
658
  }
659
 
660
  if ( empty( $prepared_source->source ) ) {
661
+ $localized_message = __( 'Payment processing failed. Please retry.', 'woocommerce-gateway-stripe' );
662
+ throw new WC_Stripe_Exception( print_r( $prepared_source, true ), $localized_message );
663
  }
664
 
665
  // Store source to order meta.
679
  * Note that if we need to save source, the original source must be first
680
  * attached to a customer in Stripe before it can be charged.
681
  */
682
+ if ( ( $source_object && ! empty( $source_object->card ) ) && ( 'card' === $source_object->type && 'required' === $source_object->card->three_d_secure || ( $this->three_d_secure && 'optional' === $source_object->card->three_d_secure ) ) ) {
683
 
684
  $response = $this->create_3ds_source( $order, $source_object );
685
 
686
  if ( ! empty( $response->error ) ) {
687
+ $localized_message = $response->error->message;
688
 
689
+ $order->add_order_note( $localized_message );
690
 
691
+ throw new WC_Stripe_Exception( print_r( $response, true ), $localized_message );
692
  }
693
 
694
  // Update order meta with 3DS source.
719
  sleep( 5 );
720
  return $this->process_payment( $order_id, false, $force_save_source );
721
  } else {
722
+ $localized_message = 'API connection error and retries exhausted.';
723
+ $order->add_order_note( $localized_message );
724
+ throw new WC_Stripe_Exception( print_r( $response, true ), $localized_message );
725
  }
726
  }
727
 
734
  // Source param wrong? The CARD may have been deleted on stripe's end. Remove token and show message.
735
  $wc_token = WC_Payment_Tokens::get( $prepared_source->token_id );
736
  $wc_token->delete();
737
+ $localized_message = __( 'This card is no longer available and has been removed.', 'woocommerce-gateway-stripe' );
738
+ $order->add_order_note( $localized_message );
739
+ throw new WC_Stripe_Exception( print_r( $response, true ), $localized_message );
740
  }
741
 
742
  $localized_messages = WC_Stripe_Helper::get_localized_messages();
743
 
744
+ if ( 'card_error' === $response->error->type ) {
745
+ $localized_message = isset( $localized_messages[ $response->error->code ] ) ? $localized_messages[ $response->error->code ] : $response->error->message;
746
+ } else {
747
+ $localized_message = isset( $localized_messages[ $response->error->type ] ) ? $localized_messages[ $response->error->type ] : $response->error->message;
748
+ }
749
 
750
+ $order->add_order_note( $localized_message );
751
 
752
+ throw new WC_Stripe_Exception( print_r( $response, true ), $localized_message );
753
  }
754
 
755
  do_action( 'wc_gateway_stripe_process_payment', $response, $order );
769
  'redirect' => $this->get_return_url( $order ),
770
  );
771
 
772
+ } catch ( WC_Stripe_Exception $e ) {
773
+ wc_add_notice( $e->getLocalizedMessage(), 'error' );
774
  WC_Stripe_Logger::log( 'Error: ' . $e->getMessage() );
775
 
776
  do_action( 'wc_gateway_stripe_process_payment_error', $e, $order );
includes/class-wc-stripe-api.php CHANGED
@@ -100,11 +100,8 @@ class WC_Stripe_API {
100
 
101
  $headers = self::get_headers();
102
 
103
- $customer = ! empty( $request['customer'] ) ? $request['customer'] : '';
104
- $source = ! empty( $request['source'] ) ? $request['source'] : $customer;
105
-
106
  if ( 'charges' === $api && 'POST' === $method ) {
107
- $headers['Idempotency-Key'] = $request['metadata']['order_id'] . '-' . $source;
108
  }
109
 
110
  $response = wp_safe_remote_post(
@@ -119,7 +116,7 @@ class WC_Stripe_API {
119
 
120
  if ( is_wp_error( $response ) || empty( $response['body'] ) ) {
121
  WC_Stripe_Logger::log( 'Error Response: ' . print_r( $response, true ) );
122
- throw new Exception( __( 'There was a problem connecting to the Stripe API endpoint.', 'woocommerce-gateway-stripe' ) );
123
  }
124
 
125
  return json_decode( $response['body'] );
100
 
101
  $headers = self::get_headers();
102
 
 
 
 
103
  if ( 'charges' === $api && 'POST' === $method ) {
104
+ $headers['Idempotency-Key'] = uniqid( 'stripe_' );
105
  }
106
 
107
  $response = wp_safe_remote_post(
116
 
117
  if ( is_wp_error( $response ) || empty( $response['body'] ) ) {
118
  WC_Stripe_Logger::log( 'Error Response: ' . print_r( $response, true ) );
119
+ throw new WC_Stripe_Exception( print_r( $response, true ), __( 'There was a problem connecting to the Stripe API endpoint.', 'woocommerce-gateway-stripe' ) );
120
  }
121
 
122
  return json_decode( $response['body'] );
includes/class-wc-stripe-customer.php CHANGED
@@ -125,7 +125,7 @@ class WC_Stripe_Customer {
125
  * @return WP_Error|int
126
  */
127
  public function create_customer( $args = array() ) {
128
- $billing_email = filter_var( $_POST['billing_email'], FILTER_SANITIZE_EMAIL );
129
  $user = $this->get_user();
130
 
131
  if ( $user ) {
@@ -138,7 +138,7 @@ class WC_Stripe_Customer {
138
  );
139
  } else {
140
  $defaults = array(
141
- 'email' => ! empty( $billing_email ) ? $billing_email : '',
142
  'description' => '',
143
  );
144
  }
@@ -151,7 +151,7 @@ class WC_Stripe_Customer {
151
  $response = WC_Stripe_API::request( apply_filters( 'wc_stripe_create_customer_args', $args ), 'customers' );
152
 
153
  if ( ! empty( $response->error ) ) {
154
- throw new Exception( $response->error->message );
155
  }
156
 
157
  $this->set_id( $response->id );
@@ -175,7 +175,7 @@ class WC_Stripe_Customer {
175
  */
176
  public function add_source( $source_id, $retry = true ) {
177
  if ( ! $this->get_id() ) {
178
- $this->create_customer();
179
  }
180
 
181
  $response = WC_Stripe_API::request( array(
@@ -250,6 +250,10 @@ class WC_Stripe_Customer {
250
  * @return array
251
  */
252
  public function get_sources() {
 
 
 
 
253
  $sources = get_transient( 'stripe_sources_' . $this->get_id() );
254
 
255
  if ( false === $sources ) {
@@ -276,6 +280,10 @@ class WC_Stripe_Customer {
276
  * @param string $source_id
277
  */
278
  public function delete_source( $source_id ) {
 
 
 
 
279
  $response = WC_Stripe_API::request( array(), 'customers/' . $this->get_id() . '/sources/' . sanitize_text_field( $source_id ), 'DELETE' );
280
 
281
  $this->clear_cache();
125
  * @return WP_Error|int
126
  */
127
  public function create_customer( $args = array() ) {
128
+ $billing_email = isset( $_POST['billing_email'] ) ? filter_var( $_POST['billing_email'], FILTER_SANITIZE_EMAIL ) : '';
129
  $user = $this->get_user();
130
 
131
  if ( $user ) {
138
  );
139
  } else {
140
  $defaults = array(
141
+ 'email' => $billing_email,
142
  'description' => '',
143
  );
144
  }
151
  $response = WC_Stripe_API::request( apply_filters( 'wc_stripe_create_customer_args', $args ), 'customers' );
152
 
153
  if ( ! empty( $response->error ) ) {
154
+ throw new WC_Stripe_Exception( print_r( $response, true ), $response->error->message );
155
  }
156
 
157
  $this->set_id( $response->id );
175
  */
176
  public function add_source( $source_id, $retry = true ) {
177
  if ( ! $this->get_id() ) {
178
+ $this->set_id( $this->create_customer() );
179
  }
180
 
181
  $response = WC_Stripe_API::request( array(
250
  * @return array
251
  */
252
  public function get_sources() {
253
+ if ( ! $this->get_id() ) {
254
+ return array();
255
+ }
256
+
257
  $sources = get_transient( 'stripe_sources_' . $this->get_id() );
258
 
259
  if ( false === $sources ) {
280
  * @param string $source_id
281
  */
282
  public function delete_source( $source_id ) {
283
+ if ( ! $this->get_id() ) {
284
+ return false;
285
+ }
286
+
287
  $response = WC_Stripe_API::request( array(), 'customers/' . $this->get_id() . '/sources/' . sanitize_text_field( $source_id ), 'DELETE' );
288
 
289
  $this->clear_cache();
includes/class-wc-stripe-exception.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * WooCommerce Stripe Exception Class
4
+ *
5
+ * Extends Exception to provide additional data
6
+ *
7
+ * @since 4.0.2
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) {
11
+ exit; // Exit if accessed directly
12
+ }
13
+
14
+ class WC_Stripe_Exception extends Exception {
15
+
16
+ /** @var string sanitized/localized error message */
17
+ protected $localized_message;
18
+
19
+ /**
20
+ * Setup exception
21
+ *
22
+ * @since 4.0.2
23
+ * @param string $error_message Full response
24
+ * @param string $localized_message user-friendly translated error message
25
+ */
26
+ public function __construct( $error_message = '', $localized_message = '' ) {
27
+ $this->localized_message = $localized_message;
28
+ parent::__construct( $error_message );
29
+ }
30
+
31
+ /**
32
+ * Returns the localized message.
33
+ *
34
+ * @since 4.0.2
35
+ * @return string
36
+ */
37
+ public function getLocalizedMessage() {
38
+ return $this->localized_message;
39
+ }
40
+ }
includes/class-wc-stripe-helper.php CHANGED
@@ -43,17 +43,17 @@ class WC_Stripe_Helper {
43
  'invalid_expiry_year' => __( 'The card\'s expiration year is invalid.', 'woocommerce-gateway-stripe' ),
44
  'invalid_cvc' => __( 'The card\'s security code is invalid.', 'woocommerce-gateway-stripe' ),
45
  'incorrect_number' => __( 'The card number is incorrect.', 'woocommerce-gateway-stripe' ),
46
- 'incomplete_number' => __( 'Your card number is incomplete.', 'woocommerce-gateway-stripe' ),
47
- 'incomplete_cvc' => __( 'Your card\'s security code is incomplete.', 'woocommerce-gateway-stripe' ),
48
- 'incomplete_expiry' => __( 'Your card\'s expiration date is incomplete.', 'woocommerce-gateway-stripe' ),
49
  'expired_card' => __( 'The card has expired.', 'woocommerce-gateway-stripe' ),
50
  'incorrect_cvc' => __( 'The card\'s security code is incorrect.', 'woocommerce-gateway-stripe' ),
51
  'incorrect_zip' => __( 'The card\'s zip code failed validation.', 'woocommerce-gateway-stripe' ),
 
52
  'card_declined' => __( 'The card was declined.', 'woocommerce-gateway-stripe' ),
53
  'missing' => __( 'There is no card on a customer that is being charged.', 'woocommerce-gateway-stripe' ),
54
  'processing_error' => __( 'An error occurred while processing the card.', 'woocommerce-gateway-stripe' ),
55
- 'invalid_request_error' => __( 'Could not find payment information. Please try with another payment method.', 'woocommerce-gateway-stripe' ),
56
- 'invalid_expiry_year_past' => __( 'Your card\'s expiration year is in the past', 'woocommerce-gateway-stripe' ),
57
  ) );
58
  }
59
 
43
  'invalid_expiry_year' => __( 'The card\'s expiration year is invalid.', 'woocommerce-gateway-stripe' ),
44
  'invalid_cvc' => __( 'The card\'s security code is invalid.', 'woocommerce-gateway-stripe' ),
45
  'incorrect_number' => __( 'The card number is incorrect.', 'woocommerce-gateway-stripe' ),
46
+ 'incomplete_number' => __( 'The card number is incomplete.', 'woocommerce-gateway-stripe' ),
47
+ 'incomplete_cvc' => __( 'The card\'s security code is incomplete.', 'woocommerce-gateway-stripe' ),
48
+ 'incomplete_expiry' => __( 'The card\'s expiration date is incomplete.', 'woocommerce-gateway-stripe' ),
49
  'expired_card' => __( 'The card has expired.', 'woocommerce-gateway-stripe' ),
50
  'incorrect_cvc' => __( 'The card\'s security code is incorrect.', 'woocommerce-gateway-stripe' ),
51
  'incorrect_zip' => __( 'The card\'s zip code failed validation.', 'woocommerce-gateway-stripe' ),
52
+ 'invalid_expiry_year_past' => __( 'The card\'s expiration year is in the past', 'woocommerce-gateway-stripe' ),
53
  'card_declined' => __( 'The card was declined.', 'woocommerce-gateway-stripe' ),
54
  'missing' => __( 'There is no card on a customer that is being charged.', 'woocommerce-gateway-stripe' ),
55
  'processing_error' => __( 'An error occurred while processing the card.', 'woocommerce-gateway-stripe' ),
56
+ 'invalid_request_error' => __( 'Unable to process this payment, please try again or use alternative method.', 'woocommerce-gateway-stripe' ),
 
57
  ) );
58
  }
59
 
includes/class-wc-stripe-order-handler.php CHANGED
@@ -89,11 +89,11 @@ class WC_Stripe_Order_Handler extends WC_Stripe_Payment_Gateway {
89
  $source_info = WC_Stripe_API::retrieve( 'sources/' . $source );
90
 
91
  if ( ! empty( $source_info->error ) ) {
92
- throw new Exception( $source_info->error->message );
93
  }
94
 
95
  if ( 'failed' === $source_info->status || 'canceled' === $source_info->status ) {
96
- throw new Exception( __( 'Unable to process this payment, please try again or use alternative method.', 'woocommerce-gateway-stripe' ) );
97
  }
98
 
99
  // If already consumed, then ignore request.
@@ -118,7 +118,7 @@ class WC_Stripe_Order_Handler extends WC_Stripe_Payment_Gateway {
118
  } else {
119
  $message = 'API connection error and retries exhausted.';
120
  $order->add_order_note( $message );
121
- throw new Exception( $message );
122
  }
123
  }
124
 
@@ -135,33 +135,37 @@ class WC_Stripe_Order_Handler extends WC_Stripe_Payment_Gateway {
135
  $wc_token->delete();
136
  $message = __( 'This card is no longer available and has been removed.', 'woocommerce-gateway-stripe' );
137
  $order->add_order_note( $message );
138
- throw new Exception( $message );
139
  }
140
 
141
  $localized_messages = WC_Stripe_Helper::get_localized_messages();
142
 
143
- $message = isset( $localized_messages[ $response->error->code ] ) ? $localized_messages[ $response->error->code ] : $response->error->message;
 
 
 
 
144
 
145
- throw new Exception( $message );
146
  }
147
 
148
  do_action( 'wc_gateway_stripe_process_redirect_payment', $response, $order );
149
 
150
  $this->process_response( $response, $order );
151
 
152
- } catch ( Exception $e ) {
153
  WC_Stripe_Logger::log( 'Error: ' . $e->getMessage() );
154
 
155
  do_action( 'wc_gateway_stripe_process_redirect_payment_error', $e, $order );
156
 
157
  /* translators: error message */
158
- $order->update_status( 'failed', sprintf( __( 'Stripe payment failed: %s', 'woocommerce-gateway-stripe' ), $e->getMessage() ) );
159
 
160
  if ( $order->has_status( array( 'pending', 'failed' ) ) ) {
161
  $this->send_failed_order_email( $order_id );
162
  }
163
 
164
- wc_add_notice( $e->getMessage(), 'error' );
165
  wp_safe_redirect( wc_get_checkout_url() );
166
  exit;
167
  }
@@ -291,9 +295,13 @@ class WC_Stripe_Order_Handler extends WC_Stripe_Payment_Gateway {
291
  $replace_str = array();
292
 
293
  if ( array_key_exists( $field, $checkout_fields['billing'] ) ) {
294
- $error_field = $checkout_fields['billing'][ $field ]['label'];
295
  } elseif ( array_key_exists( $field, $checkout_fields['shipping'] ) ) {
296
- $error_field = $checkout_fields['shipping'][ $field ]['label'];
 
 
 
 
297
  } else {
298
  $error_field = str_replace( '_', ' ', $field );
299
 
@@ -336,6 +344,9 @@ class WC_Stripe_Order_Handler extends WC_Stripe_Payment_Gateway {
336
  $validate_shipping_fields = false;
337
  $create_account = false;
338
 
 
 
 
339
  array_walk_recursive( $required_fields, 'wc_clean' );
340
  array_walk_recursive( $all_fields, 'wc_clean' );
341
 
@@ -391,7 +402,7 @@ class WC_Stripe_Order_Handler extends WC_Stripe_Payment_Gateway {
391
  if ( empty( $field_value ) || '-1' === $field_value ) {
392
  $error_field = $this->normalize_field( $field );
393
  /* translators: error field name */
394
- $errors->add( 'validation', sprintf( __( '%s cannot be empty', 'woocommerce-gateway-stripe' ), $error_field ) );
395
  }
396
  }
397
 
89
  $source_info = WC_Stripe_API::retrieve( 'sources/' . $source );
90
 
91
  if ( ! empty( $source_info->error ) ) {
92
+ throw new WC_Stripe_Exception( print_r( $source_info, true ), $source_info->error->message );
93
  }
94
 
95
  if ( 'failed' === $source_info->status || 'canceled' === $source_info->status ) {
96
+ throw new WC_Stripe_Exception( print_r( $source_info, true ), __( 'Unable to process this payment, please try again or use alternative method.', 'woocommerce-gateway-stripe' ) );
97
  }
98
 
99
  // If already consumed, then ignore request.
118
  } else {
119
  $message = 'API connection error and retries exhausted.';
120
  $order->add_order_note( $message );
121
+ throw new WC_Stripe_Exception( print_r( $response, true ), $message );
122
  }
123
  }
124
 
135
  $wc_token->delete();
136
  $message = __( 'This card is no longer available and has been removed.', 'woocommerce-gateway-stripe' );
137
  $order->add_order_note( $message );
138
+ throw new WC_Stripe_Exception( print_r( $response, true ), $message );
139
  }
140
 
141
  $localized_messages = WC_Stripe_Helper::get_localized_messages();
142
 
143
+ if ( 'card_error' === $response->error->type ) {
144
+ $message = isset( $localized_messages[ $response->error->code ] ) ? $localized_messages[ $response->error->code ] : $response->error->message;
145
+ } else {
146
+ $message = isset( $localized_messages[ $response->error->type ] ) ? $localized_messages[ $response->error->type ] : $response->error->message;
147
+ }
148
 
149
+ throw new WC_Stripe_Exception( print_r( $response, true ), $message );
150
  }
151
 
152
  do_action( 'wc_gateway_stripe_process_redirect_payment', $response, $order );
153
 
154
  $this->process_response( $response, $order );
155
 
156
+ } catch ( WC_Stripe_Exception $e ) {
157
  WC_Stripe_Logger::log( 'Error: ' . $e->getMessage() );
158
 
159
  do_action( 'wc_gateway_stripe_process_redirect_payment_error', $e, $order );
160
 
161
  /* translators: error message */
162
+ $order->update_status( 'failed', sprintf( __( 'Stripe payment failed: %s', 'woocommerce-gateway-stripe' ), $e->getLocalizedMessage() ) );
163
 
164
  if ( $order->has_status( array( 'pending', 'failed' ) ) ) {
165
  $this->send_failed_order_email( $order_id );
166
  }
167
 
168
+ wc_add_notice( $e->getLocalizedMessage(), 'error' );
169
  wp_safe_redirect( wc_get_checkout_url() );
170
  exit;
171
  }
295
  $replace_str = array();
296
 
297
  if ( array_key_exists( $field, $checkout_fields['billing'] ) ) {
298
+ $error_field = __( 'Billing', 'woocommerce-gateway-stripe' ) . ' ' . $checkout_fields['billing'][ $field ]['label'];
299
  } elseif ( array_key_exists( $field, $checkout_fields['shipping'] ) ) {
300
+ $error_field = __( 'Shipping', 'woocommerce-gateway-stripe' ) . ' ' . $checkout_fields['shipping'][ $field ]['label'];
301
+ } elseif ( array_key_exists( $field, $checkout_fields['order'] ) ) {
302
+ $error_field = $checkout_fields['order'][ $field ]['label'];
303
+ } elseif ( array_key_exists( $field, $checkout_fields['account'] ) ) {
304
+ $error_field = $checkout_fields['account'][ $field ]['label'];
305
  } else {
306
  $error_field = str_replace( '_', ' ', $field );
307
 
344
  $validate_shipping_fields = false;
345
  $create_account = false;
346
 
347
+ $all_fields = apply_filters( 'wc_stripe_validate_checkout_all_fields', $all_fields );
348
+ $required_fields = apply_filters( 'wc_stripe_validate_checkout_required_fields', $required_fields );
349
+
350
  array_walk_recursive( $required_fields, 'wc_clean' );
351
  array_walk_recursive( $all_fields, 'wc_clean' );
352
 
402
  if ( empty( $field_value ) || '-1' === $field_value ) {
403
  $error_field = $this->normalize_field( $field );
404
  /* translators: error field name */
405
+ $errors->add( 'validation', sprintf( __( '<strong>%s</strong> cannot be empty', 'woocommerce-gateway-stripe' ), $error_field ) );
406
  }
407
  }
408
 
includes/class-wc-stripe-webhook-handler.php CHANGED
@@ -154,9 +154,9 @@ class WC_Stripe_Webhook_Handler extends WC_Stripe_Payment_Gateway {
154
  sleep( 5 );
155
  return $this->process_payment( $order_id, false );
156
  } else {
157
- $message = 'API connection error and retries exhausted.';
158
- $order->add_order_note( $message );
159
- throw new Exception( $message );
160
  }
161
  }
162
 
@@ -172,23 +172,27 @@ class WC_Stripe_Webhook_Handler extends WC_Stripe_Payment_Gateway {
172
  $wc_token->delete();
173
  $message = __( 'This card is no longer available and has been removed.', 'woocommerce-gateway-stripe' );
174
  $order->add_order_note( $message );
175
- throw new Exception( $message );
176
  }
177
 
178
  $localized_messages = WC_Stripe_Helper::get_localized_messages();
179
 
180
- $message = isset( $localized_messages[ $response->error->type ] ) ? $localized_messages[ $response->error->type ] : $response->error->message;
 
 
 
 
181
 
182
- $order->add_order_note( $message );
183
 
184
- throw new Exception( $message );
185
  }
186
 
187
  do_action( 'wc_gateway_stripe_process_webhook_payment', $response, $order );
188
 
189
  $this->process_response( $response, $order );
190
 
191
- } catch ( Exception $e ) {
192
  WC_Stripe_Logger::log( 'Error: ' . $e->getMessage() );
193
 
194
  do_action( 'wc_gateway_stripe_process_webhook_payment_error', $e, $order );
@@ -388,8 +392,14 @@ class WC_Stripe_Webhook_Handler extends WC_Stripe_Payment_Gateway {
388
  $order_id = WC_Stripe_Helper::is_pre_30() ? $order->id : $order->get_id();
389
 
390
  if ( 'stripe' === ( WC_Stripe_Helper::is_pre_30() ? $order->payment_method : $order->get_payment_method() ) ) {
391
- $charge = WC_Stripe_Helper::is_pre_30() ? get_post_meta( $order_id, '_transaction_id', true ) : $order->get_transaction_id();
392
- $captured = WC_Stripe_Helper::is_pre_30() ? get_post_meta( $order_id, '_stripe_charge_captured', true ) : $order->get_meta( '_stripe_charge_captured', true );
 
 
 
 
 
 
393
 
394
  // Only refund captured charge.
395
  if ( $charge && 'yes' === $captured ) {
154
  sleep( 5 );
155
  return $this->process_payment( $order_id, false );
156
  } else {
157
+ $localized_message = 'API connection error and retries exhausted.';
158
+ $order->add_order_note( $localized_message );
159
+ throw new WC_Stripe_Exception( print_r( $response, true ), $localized_message );
160
  }
161
  }
162
 
172
  $wc_token->delete();
173
  $message = __( 'This card is no longer available and has been removed.', 'woocommerce-gateway-stripe' );
174
  $order->add_order_note( $message );
175
+ throw new WC_Stripe_Exception( print_r( $response, true ), $message );
176
  }
177
 
178
  $localized_messages = WC_Stripe_Helper::get_localized_messages();
179
 
180
+ if ( 'card_error' === $response->error->type ) {
181
+ $localized_message = isset( $localized_messages[ $response->error->code ] ) ? $localized_messages[ $response->error->code ] : $response->error->message;
182
+ } else {
183
+ $localized_message = isset( $localized_messages[ $response->error->type ] ) ? $localized_messages[ $response->error->type ] : $response->error->message;
184
+ }
185
 
186
+ $order->add_order_note( $localized_message );
187
 
188
+ throw new WC_Stripe_Exception( print_r( $response, true ), $localized_message );
189
  }
190
 
191
  do_action( 'wc_gateway_stripe_process_webhook_payment', $response, $order );
192
 
193
  $this->process_response( $response, $order );
194
 
195
+ } catch ( WC_Stripe_Exception $e ) {
196
  WC_Stripe_Logger::log( 'Error: ' . $e->getMessage() );
197
 
198
  do_action( 'wc_gateway_stripe_process_webhook_payment_error', $e, $order );
392
  $order_id = WC_Stripe_Helper::is_pre_30() ? $order->id : $order->get_id();
393
 
394
  if ( 'stripe' === ( WC_Stripe_Helper::is_pre_30() ? $order->payment_method : $order->get_payment_method() ) ) {
395
+ $charge = WC_Stripe_Helper::is_pre_30() ? get_post_meta( $order_id, '_transaction_id', true ) : $order->get_transaction_id();
396
+ $captured = WC_Stripe_Helper::is_pre_30() ? get_post_meta( $order_id, '_stripe_charge_captured', true ) : $order->get_meta( '_stripe_charge_captured', true );
397
+ $refund_id = WC_Stripe_Helper::is_pre_30() ? get_post_meta( $order_id, '_stripe_refund_id', true ) : $order->get_meta( '_stripe_refund_id', true );
398
+
399
+ // If the refund ID matches, don't continue to prevent double refunding.
400
+ if ( $notification->data->object->refunds->data[0]->id === $refund_id ) {
401
+ return;
402
+ }
403
 
404
  // Only refund captured charge.
405
  if ( $charge && 'yes' === $captured ) {
includes/compat/class-wc-stripe-compat.php CHANGED
@@ -384,8 +384,13 @@ class WC_Stripe_Compat extends WC_Gateway_Stripe {
384
 
385
  if ( $source->id === $stripe_source_id ) {
386
  $found_source = true;
387
- /* translators: 1) card brand 2) last 4 digits */
388
- $payment_method_to_display = sprintf( __( 'Via %1$s card ending in %2$s', 'woocommerce-gateway-stripe' ), ( isset( $card->brand ) ? $card->brand : __( 'N/A', 'woocommerce-gateway-stripe' ) ), $card->last4 );
 
 
 
 
 
389
  break;
390
  }
391
  }
@@ -395,8 +400,12 @@ class WC_Stripe_Compat extends WC_Gateway_Stripe {
395
  $card = $sources[0]->card;
396
  }
397
 
398
- /* translators: 1) card brand 2) last 4 digits */
399
- $payment_method_to_display = sprintf( __( 'Via %1$s card ending in %2$s', 'woocommerce-gateway-stripe' ), ( isset( $card->brand ) ? $card->brand : __( 'N/A', 'woocommerce-gateway-stripe' ) ), $card->last4 );
 
 
 
 
400
  }
401
  }
402
 
384
 
385
  if ( $source->id === $stripe_source_id ) {
386
  $found_source = true;
387
+
388
+ if ( $card ) {
389
+ /* translators: 1) card brand 2) last 4 digits */
390
+ $payment_method_to_display = sprintf( __( 'Via %1$s card ending in %2$s', 'woocommerce-gateway-stripe' ), ( isset( $card->brand ) ? $card->brand : __( 'N/A', 'woocommerce-gateway-stripe' ) ), $card->last4 );
391
+ } else {
392
+ $payment_method_to_display = __( 'N/A', 'woocommerce-gateway-stripe' );
393
+ }
394
  break;
395
  }
396
  }
400
  $card = $sources[0]->card;
401
  }
402
 
403
+ if ( $card ) {
404
+ /* translators: 1) card brand 2) last 4 digits */
405
+ $payment_method_to_display = sprintf( __( 'Via %1$s card ending in %2$s', 'woocommerce-gateway-stripe' ), ( isset( $card->brand ) ? $card->brand : __( 'N/A', 'woocommerce-gateway-stripe' ) ), $card->last4 );
406
+ } else {
407
+ $payment_method_to_display = __( 'N/A', 'woocommerce-gateway-stripe' );
408
+ }
409
  }
410
  }
411
 
includes/compat/class-wc-stripe-sepa-compat.php CHANGED
@@ -383,8 +383,13 @@ class WC_Stripe_Sepa_Compat extends WC_Gateway_Stripe_Sepa {
383
 
384
  if ( $source->id === $stripe_source_id ) {
385
  $found_source = true;
386
- /* translators: 1) card brand 2) last 4 digits */
387
- $payment_method_to_display = sprintf( __( 'Via %1$s card ending in %2$s', 'woocommerce-gateway-stripe' ), ( isset( $card->brand ) ? $card->brand : __( 'N/A', 'woocommerce-gateway-stripe' ) ), $card->last4 );
 
 
 
 
 
388
  break;
389
  }
390
  }
@@ -394,8 +399,12 @@ class WC_Stripe_Sepa_Compat extends WC_Gateway_Stripe_Sepa {
394
  $card = $sources[0]->card;
395
  }
396
 
397
- /* translators: 1) card brand 2) last 4 digits */
398
- $payment_method_to_display = sprintf( __( 'Via %1$s card ending in %2$s', 'woocommerce-gateway-stripe' ), ( isset( $card->brand ) ? $card->brand : __( 'N/A', 'woocommerce-gateway-stripe' ) ), $card->last4 );
 
 
 
 
399
  }
400
  }
401
 
383
 
384
  if ( $source->id === $stripe_source_id ) {
385
  $found_source = true;
386
+
387
+ if ( $card ) {
388
+ /* translators: 1) card brand 2) last 4 digits */
389
+ $payment_method_to_display = sprintf( __( 'Via %1$s card ending in %2$s', 'woocommerce-gateway-stripe' ), ( isset( $card->brand ) ? $card->brand : __( 'N/A', 'woocommerce-gateway-stripe' ) ), $card->last4 );
390
+ } else {
391
+ $payment_method_to_display = __( 'N/A', 'woocommerce-gateway-stripe' );
392
+ }
393
  break;
394
  }
395
  }
399
  $card = $sources[0]->card;
400
  }
401
 
402
+ if ( $card ) {
403
+ /* translators: 1) card brand 2) last 4 digits */
404
+ $payment_method_to_display = sprintf( __( 'Via %1$s card ending in %2$s', 'woocommerce-gateway-stripe' ), ( isset( $card->brand ) ? $card->brand : __( 'N/A', 'woocommerce-gateway-stripe' ) ), $card->last4 );
405
+ } else {
406
+ $payment_method_to_display = __( 'N/A', 'woocommerce-gateway-stripe' );
407
+ }
408
  }
409
  }
410
 
includes/deprecated/class-wc-stripe-apple-pay.php CHANGED
@@ -17,13 +17,20 @@ if ( ! class_exists( 'WC_Stripe_Apple_Pay' ) ) {
17
 
18
  public function __construct() {
19
  self::$_this = $this;
20
-
21
  }
22
 
23
  public static function instance() {
24
  WC_Stripe_Logger::log( "DEPRECATED! WC_Stripe_Apple_Pay class has been hard deprecated. Please remove any code that references this class or instance." );
25
  return self::$_this;
26
- }
 
 
 
 
 
 
 
 
27
  }
28
  }
29
 
17
 
18
  public function __construct() {
19
  self::$_this = $this;
 
20
  }
21
 
22
  public static function instance() {
23
  WC_Stripe_Logger::log( "DEPRECATED! WC_Stripe_Apple_Pay class has been hard deprecated. Please remove any code that references this class or instance." );
24
  return self::$_this;
25
+ }
26
+
27
+ public function __get( $var ) {
28
+ return null;
29
+ }
30
+
31
+ public function __call( $name, $arguments ) {
32
+ return null;
33
+ }
34
  }
35
  }
36
 
includes/payment-methods/class-wc-gateway-stripe-alipay.php CHANGED
@@ -172,19 +172,6 @@ class WC_Gateway_Stripe_Alipay extends WC_Stripe_Payment_Gateway {
172
  return parent::is_available();
173
  }
174
 
175
- /**
176
- * All payment icons that work with Stripe.
177
- *
178
- * @since 4.0.0
179
- * @version 4.0.0
180
- * @return array
181
- */
182
- public function payment_icons() {
183
- return apply_filters( 'wc_stripe_payment_icons', array(
184
- 'alipay' => '<i class="stripe-pf stripe-pf-alipay stripe-pf-right" alt="Alipay" aria-hidden="true"></i>',
185
- ) );
186
- }
187
-
188
  /**
189
  * Get_icon function.
190
  *
@@ -316,7 +303,7 @@ class WC_Gateway_Stripe_Alipay extends WC_Stripe_Payment_Gateway {
316
  if ( ! empty( $response->error ) ) {
317
  $order->add_order_note( $response->error->message );
318
 
319
- throw new Exception( $response->error->message );
320
  }
321
 
322
  if ( WC_Stripe_Helper::is_pre_30() ) {
@@ -332,8 +319,8 @@ class WC_Gateway_Stripe_Alipay extends WC_Stripe_Payment_Gateway {
332
  'result' => 'success',
333
  'redirect' => esc_url_raw( $response->redirect->url ),
334
  );
335
- } catch ( Exception $e ) {
336
- wc_add_notice( $e->getMessage(), 'error' );
337
  WC_Stripe_Logger::log( 'Error: ' . $e->getMessage() );
338
 
339
  do_action( 'wc_gateway_stripe_process_payment_error', $e, $order );
172
  return parent::is_available();
173
  }
174
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
  /**
176
  * Get_icon function.
177
  *
303
  if ( ! empty( $response->error ) ) {
304
  $order->add_order_note( $response->error->message );
305
 
306
+ throw new WC_Stripe_Exception( print_r( $response, true ), $response->error->message );
307
  }
308
 
309
  if ( WC_Stripe_Helper::is_pre_30() ) {
319
  'result' => 'success',
320
  'redirect' => esc_url_raw( $response->redirect->url ),
321
  );
322
+ } catch ( WC_Stripe_Exception $e ) {
323
+ wc_add_notice( $e->getLocalizedMessage(), 'error' );
324
  WC_Stripe_Logger::log( 'Error: ' . $e->getMessage() );
325
 
326
  do_action( 'wc_gateway_stripe_process_payment_error', $e, $order );
includes/payment-methods/class-wc-gateway-stripe-bancontact.php CHANGED
@@ -161,19 +161,6 @@ class WC_Gateway_Stripe_Bancontact extends WC_Stripe_Payment_Gateway {
161
  return parent::is_available();
162
  }
163
 
164
- /**
165
- * All payment icons that work with Stripe.
166
- *
167
- * @since 4.0.0
168
- * @version 4.0.0
169
- * @return array
170
- */
171
- public function payment_icons() {
172
- return apply_filters( 'wc_stripe_payment_icons', array(
173
- 'bancontact' => '<i class="stripe-pf stripe-pf-bancontact-mister-cash stripe-pf-right" alt="Bancontact" aria-hidden="true"></i>',
174
- ) );
175
- }
176
-
177
  /**
178
  * Get_icon function.
179
  *
@@ -306,7 +293,7 @@ class WC_Gateway_Stripe_Bancontact extends WC_Stripe_Payment_Gateway {
306
  if ( ! empty( $response->error ) ) {
307
  $order->add_order_note( $response->error->message );
308
 
309
- throw new Exception( $response->error->message );
310
  }
311
 
312
  if ( WC_Stripe_Helper::is_pre_30() ) {
@@ -322,8 +309,8 @@ class WC_Gateway_Stripe_Bancontact extends WC_Stripe_Payment_Gateway {
322
  'result' => 'success',
323
  'redirect' => esc_url_raw( $response->redirect->url ),
324
  );
325
- } catch ( Exception $e ) {
326
- wc_add_notice( $e->getMessage(), 'error' );
327
  WC_Stripe_Logger::log( 'Error: ' . $e->getMessage() );
328
 
329
  do_action( 'wc_gateway_stripe_process_payment_error', $e, $order );
161
  return parent::is_available();
162
  }
163
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
  /**
165
  * Get_icon function.
166
  *
293
  if ( ! empty( $response->error ) ) {
294
  $order->add_order_note( $response->error->message );
295
 
296
+ throw new WC_Stripe_Exception( print_r( $response, true ), $response->error->message );
297
  }
298
 
299
  if ( WC_Stripe_Helper::is_pre_30() ) {
309
  'result' => 'success',
310
  'redirect' => esc_url_raw( $response->redirect->url ),
311
  );
312
+ } catch ( WC_Stripe_Exception $e ) {
313
+ wc_add_notice( $e->getLocalizedMessage(), 'error' );
314
  WC_Stripe_Logger::log( 'Error: ' . $e->getMessage() );
315
 
316
  do_action( 'wc_gateway_stripe_process_payment_error', $e, $order );
includes/payment-methods/class-wc-gateway-stripe-bitcoin.php CHANGED
@@ -172,19 +172,6 @@ class WC_Gateway_Stripe_Bitcoin extends WC_Stripe_Payment_Gateway {
172
  return parent::is_available();
173
  }
174
 
175
- /**
176
- * All payment icons that work with Stripe.
177
- *
178
- * @since 4.0.0
179
- * @version 4.0.0
180
- * @return array
181
- */
182
- public function payment_icons() {
183
- return apply_filters( 'wc_stripe_payment_icons', array(
184
- 'bitcoin' => '<i class="stripe-pf stripe-pf-bitcoin stripe-pf-right" alt="Bitcoin" aria-hidden="true"></i>',
185
- ) );
186
- }
187
-
188
  /**
189
  * Get_icon function.
190
  *
@@ -380,8 +367,8 @@ class WC_Gateway_Stripe_Bitcoin extends WC_Stripe_Payment_Gateway {
380
  $prepared_source = $this->prepare_source( get_current_user_id(), $force_save_source );
381
 
382
  if ( empty( $prepared_source->source ) ) {
383
- $error_msg = __( 'Payment processing failed. Please retry.', 'woocommerce-gateway-stripe' );
384
- throw new Exception( $error_msg );
385
  }
386
 
387
  // Store source to order meta.
@@ -406,8 +393,8 @@ class WC_Gateway_Stripe_Bitcoin extends WC_Stripe_Payment_Gateway {
406
  'result' => 'success',
407
  'redirect' => $this->get_return_url( $order ),
408
  );
409
- } catch ( Exception $e ) {
410
- wc_add_notice( $e->getMessage(), 'error' );
411
  WC_Stripe_Logger::log( 'Error: ' . $e->getMessage() );
412
 
413
  do_action( 'wc_gateway_stripe_process_payment_error', $e, $order );
172
  return parent::is_available();
173
  }
174
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
  /**
176
  * Get_icon function.
177
  *
367
  $prepared_source = $this->prepare_source( get_current_user_id(), $force_save_source );
368
 
369
  if ( empty( $prepared_source->source ) ) {
370
+ $localized_message = __( 'Payment processing failed. Please retry.', 'woocommerce-gateway-stripe' );
371
+ throw new WC_Stripe_Exception( print_r( $prepared_source, true ), $localized_message );
372
  }
373
 
374
  // Store source to order meta.
393
  'result' => 'success',
394
  'redirect' => $this->get_return_url( $order ),
395
  );
396
+ } catch ( WC_Stripe_Exception $e ) {
397
+ wc_add_notice( $e->getLocalizedMessage(), 'error' );
398
  WC_Stripe_Logger::log( 'Error: ' . $e->getMessage() );
399
 
400
  do_action( 'wc_gateway_stripe_process_payment_error', $e, $order );
includes/payment-methods/class-wc-gateway-stripe-giropay.php CHANGED
@@ -161,19 +161,6 @@ class WC_Gateway_Stripe_Giropay extends WC_Stripe_Payment_Gateway {
161
  return parent::is_available();
162
  }
163
 
164
- /**
165
- * All payment icons that work with Stripe.
166
- *
167
- * @since 4.0.0
168
- * @version 4.0.0
169
- * @return array
170
- */
171
- public function payment_icons() {
172
- return apply_filters( 'wc_stripe_payment_icons', array(
173
- 'giropay' => '<i class="stripe-pf stripe-pf-giropay stripe-pf-right" alt="Giropay" aria-hidden="true"></i>',
174
- ) );
175
- }
176
-
177
  /**
178
  * Get_icon function.
179
  *
@@ -306,7 +293,7 @@ class WC_Gateway_Stripe_Giropay extends WC_Stripe_Payment_Gateway {
306
  if ( ! empty( $response->error ) ) {
307
  $order->add_order_note( $response->error->message );
308
 
309
- throw new Exception( $response->error->message );
310
  }
311
 
312
  if ( WC_Stripe_Helper::is_pre_30() ) {
@@ -322,8 +309,8 @@ class WC_Gateway_Stripe_Giropay extends WC_Stripe_Payment_Gateway {
322
  'result' => 'success',
323
  'redirect' => esc_url_raw( $response->redirect->url ),
324
  );
325
- } catch ( Exception $e ) {
326
- wc_add_notice( $e->getMessage(), 'error' );
327
  WC_Stripe_Logger::log( 'Error: ' . $e->getMessage() );
328
 
329
  do_action( 'wc_gateway_stripe_process_payment_error', $e, $order );
161
  return parent::is_available();
162
  }
163
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
  /**
165
  * Get_icon function.
166
  *
293
  if ( ! empty( $response->error ) ) {
294
  $order->add_order_note( $response->error->message );
295
 
296
+ throw new WC_Stripe_Exception( print_r( $response, true ), $response->error->message );
297
  }
298
 
299
  if ( WC_Stripe_Helper::is_pre_30() ) {
309
  'result' => 'success',
310
  'redirect' => esc_url_raw( $response->redirect->url ),
311
  );
312
+ } catch ( WC_Stripe_Exception $e ) {
313
+ wc_add_notice( $e->getLocalizedMessage(), 'error' );
314
  WC_Stripe_Logger::log( 'Error: ' . $e->getMessage() );
315
 
316
  do_action( 'wc_gateway_stripe_process_payment_error', $e, $order );
includes/payment-methods/class-wc-gateway-stripe-ideal.php CHANGED
@@ -161,19 +161,6 @@ class WC_Gateway_Stripe_Ideal extends WC_Stripe_Payment_Gateway {
161
  return parent::is_available();
162
  }
163
 
164
- /**
165
- * All payment icons that work with Stripe.
166
- *
167
- * @since 4.0.0
168
- * @version 4.0.0
169
- * @return array
170
- */
171
- public function payment_icons() {
172
- return apply_filters( 'wc_stripe_payment_icons', array(
173
- 'ideal' => '<i class="stripe-pf stripe-pf-ideal stripe-pf-right" alt="iDeal" aria-hidden="true"></i>',
174
- ) );
175
- }
176
-
177
  /**
178
  * Get_icon function.
179
  *
@@ -306,7 +293,7 @@ class WC_Gateway_Stripe_Ideal extends WC_Stripe_Payment_Gateway {
306
  if ( ! empty( $response->error ) ) {
307
  $order->add_order_note( $response->error->message );
308
 
309
- throw new Exception( $response->error->message );
310
  }
311
 
312
  if ( WC_Stripe_Helper::is_pre_30() ) {
@@ -322,8 +309,8 @@ class WC_Gateway_Stripe_Ideal extends WC_Stripe_Payment_Gateway {
322
  'result' => 'success',
323
  'redirect' => esc_url_raw( $response->redirect->url ),
324
  );
325
- } catch ( Exception $e ) {
326
- wc_add_notice( $e->getMessage(), 'error' );
327
  WC_Stripe_Logger::log( 'Error: ' . $e->getMessage() );
328
 
329
  do_action( 'wc_gateway_stripe_process_payment_error', $e, $order );
161
  return parent::is_available();
162
  }
163
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
  /**
165
  * Get_icon function.
166
  *
293
  if ( ! empty( $response->error ) ) {
294
  $order->add_order_note( $response->error->message );
295
 
296
+ throw new WC_Stripe_Exception( print_r( $response, true ), $response->error->message );
297
  }
298
 
299
  if ( WC_Stripe_Helper::is_pre_30() ) {
309
  'result' => 'success',
310
  'redirect' => esc_url_raw( $response->redirect->url ),
311
  );
312
+ } catch ( WC_Stripe_Exception $e ) {
313
+ wc_add_notice( $e->getLocalizedMessage(), 'error' );
314
  WC_Stripe_Logger::log( 'Error: ' . $e->getMessage() );
315
 
316
  do_action( 'wc_gateway_stripe_process_payment_error', $e, $order );
includes/payment-methods/class-wc-gateway-stripe-p24.php CHANGED
@@ -162,19 +162,6 @@ class WC_Gateway_Stripe_P24 extends WC_Stripe_Payment_Gateway {
162
  return parent::is_available();
163
  }
164
 
165
- /**
166
- * All payment icons that work with Stripe.
167
- *
168
- * @since 4.0.0
169
- * @version 4.0.0
170
- * @return array
171
- */
172
- public function payment_icons() {
173
- return apply_filters( 'wc_stripe_payment_icons', array(
174
- 'p24' => '<i class="stripe-pf stripe-pf-p24 stripe-pf-right" alt="P24" aria-hidden="true"></i>',
175
- ) );
176
- }
177
-
178
  /**
179
  * Get_icon function.
180
  *
@@ -303,7 +290,7 @@ class WC_Gateway_Stripe_P24 extends WC_Stripe_Payment_Gateway {
303
  if ( ! empty( $response->error ) ) {
304
  $order->add_order_note( $response->error->message );
305
 
306
- throw new Exception( $response->error->message );
307
  }
308
 
309
  if ( WC_Stripe_Helper::is_pre_30() ) {
@@ -319,8 +306,8 @@ class WC_Gateway_Stripe_P24 extends WC_Stripe_Payment_Gateway {
319
  'result' => 'success',
320
  'redirect' => esc_url_raw( $response->redirect->url ),
321
  );
322
- } catch ( Exception $e ) {
323
- wc_add_notice( $e->getMessage(), 'error' );
324
  WC_Stripe_Logger::log( 'Error: ' . $e->getMessage() );
325
 
326
  do_action( 'wc_gateway_stripe_process_payment_error', $e, $order );
162
  return parent::is_available();
163
  }
164
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
  /**
166
  * Get_icon function.
167
  *
290
  if ( ! empty( $response->error ) ) {
291
  $order->add_order_note( $response->error->message );
292
 
293
+ throw new WC_Stripe_Exception( print_r( $response, true ), $response->error->message );
294
  }
295
 
296
  if ( WC_Stripe_Helper::is_pre_30() ) {
306
  'result' => 'success',
307
  'redirect' => esc_url_raw( $response->redirect->url ),
308
  );
309
+ } catch ( WC_Stripe_Exception $e ) {
310
+ wc_add_notice( $e->getLocalizedMessage(), 'error' );
311
  WC_Stripe_Logger::log( 'Error: ' . $e->getMessage() );
312
 
313
  do_action( 'wc_gateway_stripe_process_payment_error', $e, $order );
includes/payment-methods/class-wc-gateway-stripe-sepa.php CHANGED
@@ -171,20 +171,11 @@ class WC_Gateway_Stripe_Sepa extends WC_Stripe_Payment_Gateway {
171
  return false;
172
  }
173
 
174
- return parent::is_available();
175
- }
 
176
 
177
- /**
178
- * All payment icons that work with Stripe.
179
- *
180
- * @since 4.0.0
181
- * @version 4.0.0
182
- * @return array
183
- */
184
- public function payment_icons() {
185
- return apply_filters( 'wc_stripe_payment_icons', array(
186
- 'sepa' => '<i class="stripe-pf stripe-pf-sepa stripe-pf-right" alt="SEPA" aria-hidden="true"></i>',
187
- ) );
188
  }
189
 
190
  /**
@@ -249,18 +240,18 @@ class WC_Gateway_Stripe_Sepa extends WC_Stripe_Payment_Gateway {
249
  ?>
250
  <fieldset id="wc-<?php echo esc_attr( $this->id ); ?>-form" class="wc-payment-form">
251
  <?php do_action( 'woocommerce_credit_card_form_start', $this->id ); ?>
252
- <p class="wc-stripe-sepa-mandate"><?php $this->mandate_display(); ?></p>
253
  <p class="form-row form-row-wide validate-required">
254
  <label for="stripe-sepa-owner">
255
  <?php esc_html_e( 'IBAN Account Name.', 'woocommerce-gateway-stripe' ); ?>
256
  </label>
257
- <input id="stripe-sepa-owner" name="stripe_sepa_owner" value="" />
258
  </p>
259
  <p class="form-row form-row-wide validate-required">
260
  <label for="stripe-sepa-iban">
261
  <?php esc_html_e( 'IBAN Account Number.', 'woocommerce-gateway-stripe' ); ?>
262
  </label>
263
- <input id="stripe-sepa-iban" name="stripe_sepa_iban" value="" />
264
  </p>
265
  <!-- Used to display form errors -->
266
  <div class="stripe-source-errors" role="alert"></div>
@@ -366,9 +357,9 @@ class WC_Gateway_Stripe_Sepa extends WC_Stripe_Payment_Gateway {
366
  sleep( 5 );
367
  return $this->process_payment( $order_id, false, $force_save_source );
368
  } else {
369
- $message = 'API connection error and retries exhausted.';
370
- $order->add_order_note( $message );
371
- throw new Exception( $message );
372
  }
373
  }
374
 
@@ -381,18 +372,22 @@ class WC_Gateway_Stripe_Sepa extends WC_Stripe_Payment_Gateway {
381
  // Source param wrong? The CARD may have been deleted on stripe's end. Remove token and show message.
382
  $wc_token = WC_Payment_Tokens::get( $prepared_source->token_id );
383
  $wc_token->delete();
384
- $message = __( 'This card is no longer available and has been removed.', 'woocommerce-gateway-stripe' );
385
- $order->add_order_note( $message );
386
- throw new Exception( $message );
387
  }
388
 
389
  $localized_messages = WC_Stripe_Helper::get_localized_messages();
390
 
391
- $message = isset( $localized_messages[ $response->error->type ] ) ? $localized_messages[ $response->error->type ] : $response->error->message;
 
 
 
 
392
 
393
- $order->add_order_note( $message );
394
 
395
- throw new Exception( $message );
396
  }
397
 
398
  do_action( 'wc_gateway_stripe_process_payment', $response, $order );
@@ -412,8 +407,8 @@ class WC_Gateway_Stripe_Sepa extends WC_Stripe_Payment_Gateway {
412
  'redirect' => $this->get_return_url( $order ),
413
  );
414
 
415
- } catch ( Exception $e ) {
416
- wc_add_notice( $e->getMessage(), 'error' );
417
  WC_Stripe_Logger::log( 'Error: ' . $e->getMessage() );
418
 
419
  do_action( 'wc_gateway_stripe_process_payment_error', $e, $order );
171
  return false;
172
  }
173
 
174
+ if ( is_add_payment_method_page() && ! $this->saved_cards ) {
175
+ return false;
176
+ }
177
 
178
+ return parent::is_available();
 
 
 
 
 
 
 
 
 
 
179
  }
180
 
181
  /**
240
  ?>
241
  <fieldset id="wc-<?php echo esc_attr( $this->id ); ?>-form" class="wc-payment-form">
242
  <?php do_action( 'woocommerce_credit_card_form_start', $this->id ); ?>
243
+ <p class="wc-stripe-sepa-mandate" style="margin-bottom:40px;"><?php $this->mandate_display(); ?></p>
244
  <p class="form-row form-row-wide validate-required">
245
  <label for="stripe-sepa-owner">
246
  <?php esc_html_e( 'IBAN Account Name.', 'woocommerce-gateway-stripe' ); ?>
247
  </label>
248
+ <input id="stripe-sepa-owner" name="stripe_sepa_owner" value="" style="border:1px solid #ddd;margin:5px 0;padding:10px 5px;background-color:#fff;outline:0;" />
249
  </p>
250
  <p class="form-row form-row-wide validate-required">
251
  <label for="stripe-sepa-iban">
252
  <?php esc_html_e( 'IBAN Account Number.', 'woocommerce-gateway-stripe' ); ?>
253
  </label>
254
+ <input id="stripe-sepa-iban" name="stripe_sepa_iban" value="" style="border:1px solid #ddd;margin:5px 0;padding:10px 5px;background-color:#fff;outline:0;" />
255
  </p>
256
  <!-- Used to display form errors -->
257
  <div class="stripe-source-errors" role="alert"></div>
357
  sleep( 5 );
358
  return $this->process_payment( $order_id, false, $force_save_source );
359
  } else {
360
+ $localized_message = 'API connection error and retries exhausted.';
361
+ $order->add_order_note( $localized_message );
362
+ throw new WC_Stripe_Exception( print_r( $response, true ), $localized_message );
363
  }
364
  }
365
 
372
  // Source param wrong? The CARD may have been deleted on stripe's end. Remove token and show message.
373
  $wc_token = WC_Payment_Tokens::get( $prepared_source->token_id );
374
  $wc_token->delete();
375
+ $localized_message = __( 'This card is no longer available and has been removed.', 'woocommerce-gateway-stripe' );
376
+ $order->add_order_note( $localized_message );
377
+ throw new WC_Stripe_Exception( print_r( $response, true ), $localized_message );
378
  }
379
 
380
  $localized_messages = WC_Stripe_Helper::get_localized_messages();
381
 
382
+ if ( 'card_error' === $response->error->type ) {
383
+ $localized_message = isset( $localized_messages[ $response->error->code ] ) ? $localized_messages[ $response->error->code ] : $response->error->message;
384
+ } else {
385
+ $localized_message = isset( $localized_messages[ $response->error->type ] ) ? $localized_messages[ $response->error->type ] : $response->error->message;
386
+ }
387
 
388
+ $order->add_order_note( $localized_message );
389
 
390
+ throw new WC_Stripe_Exception( print_r( $response, true ), $localized_message );
391
  }
392
 
393
  do_action( 'wc_gateway_stripe_process_payment', $response, $order );
407
  'redirect' => $this->get_return_url( $order ),
408
  );
409
 
410
+ } catch ( WC_Stripe_Exception $e ) {
411
+ wc_add_notice( $e->getLocalizedMessage(), 'error' );
412
  WC_Stripe_Logger::log( 'Error: ' . $e->getMessage() );
413
 
414
  do_action( 'wc_gateway_stripe_process_payment_error', $e, $order );
includes/payment-methods/class-wc-gateway-stripe-sofort.php CHANGED
@@ -161,19 +161,6 @@ class WC_Gateway_Stripe_Sofort extends WC_Stripe_Payment_Gateway {
161
  return parent::is_available();
162
  }
163
 
164
- /**
165
- * All payment icons that work with Stripe.
166
- *
167
- * @since 4.0.0
168
- * @version 4.0.0
169
- * @return array
170
- */
171
- public function payment_icons() {
172
- return apply_filters( 'wc_stripe_payment_icons', array(
173
- 'sofort' => '<i class="stripe-pf stripe-pf-sofort stripe-pf-right" alt="SOFORT" aria-hidden="true"></i>',
174
- ) );
175
- }
176
-
177
  /**
178
  * Get_icon function.
179
  *
@@ -214,51 +201,12 @@ class WC_Gateway_Stripe_Sofort extends WC_Stripe_Payment_Gateway {
214
  $this->form_fields = require( WC_STRIPE_PLUGIN_PATH . '/includes/admin/stripe-sofort-settings.php' );
215
  }
216
 
217
- /**
218
- * Renders the Stripe elements form.
219
- *
220
- * @since 4.0.0
221
- * @version 4.0.0
222
- */
223
- public function form() {
224
- $supported_countries = array(
225
- 'AT' => 'Austria',
226
- 'BE' => 'Belgium',
227
- 'DE' => 'Germany',
228
- 'NL' => 'Netherlands',
229
- 'ES' => 'Spain',
230
- 'IT' => 'Italy',
231
- );
232
- ?>
233
- <fieldset id="wc-<?php echo esc_attr( $this->id ); ?>-form" class="wc-payment-form">
234
- <?php do_action( 'woocommerce_credit_card_form_start', $this->id ); ?>
235
- <label for="stripe-bank-country">
236
- <?php _e( 'Country origin of your bank.', 'woocommerce-gateway-stripe' ); ?>
237
- </label>
238
- <br />
239
- <p class="form-row form-row-wide validate-required">
240
- <select id="stripe-bank-country" class="wc-enhanced-select" name="stripe_sofort_bank_country">
241
- <option value="-1"><?php esc_html_e( 'Choose Bank Country', 'woocommerce-gateway-stripe' ); ?></option>
242
- <?php foreach ( $supported_countries as $code => $country ) { ?>
243
- <option value="<?php echo esc_attr( $code ); ?>"><?php echo esc_html( $country ); ?></option>
244
- <?php } ?>
245
- </select>
246
- </p>
247
-
248
- <!-- Used to display form errors -->
249
- <div class="stripe-source-errors" role="alert"></div>
250
- <?php do_action( 'woocommerce_credit_card_form_end', $this->id ); ?>
251
- <div class="clear"></div>
252
- </fieldset>
253
- <?php
254
- }
255
-
256
  /**
257
  * Payment form on checkout page
258
  */
259
  public function payment_fields() {
260
- $user = wp_get_current_user();
261
- $total = WC()->cart->total;
262
 
263
  // If paying from order, we need to get total from order not cart.
264
  if ( isset( $_GET['pay_for_order'] ) && ! empty( $_GET['key'] ) ) {
@@ -282,8 +230,6 @@ class WC_Gateway_Stripe_Sofort extends WC_Stripe_Payment_Gateway {
282
  echo apply_filters( 'wc_stripe_description', wpautop( wp_kses_post( $this->description ) ) );
283
  }
284
 
285
- $this->form();
286
-
287
  echo '</div>';
288
  }
289
 
@@ -296,17 +242,16 @@ class WC_Gateway_Stripe_Sofort extends WC_Stripe_Payment_Gateway {
296
  * @return mixed
297
  */
298
  public function create_source( $order ) {
299
- $currency = WC_Stripe_Helper::is_pre_30() ? $order->get_order_currency() : $order->get_currency();
300
- $order_id = WC_Stripe_Helper::is_pre_30() ? $order->id : $order->get_id();
301
- $bank_country = wc_clean( $_POST['stripe_sofort_bank_country'] );
302
- $return_url = $this->get_stripe_return_url( $order );
303
- $post_data = array();
304
- $post_data['amount'] = WC_Stripe_Helper::get_stripe_amount( $order->get_total(), $currency );
305
- $post_data['currency'] = strtolower( $currency );
306
- $post_data['type'] = 'sofort';
307
- $post_data['owner'] = $this->get_owner_details( $order );
308
- $post_data['redirect'] = array( 'return_url' => $return_url );
309
- $post_data['sofort'] = array( 'country' => $bank_country );
310
 
311
  if ( ! empty( $this->statement_descriptor ) ) {
312
  $post_data['statement_descriptor'] = WC_Stripe_Helper::clean_statement_descriptor( $this->statement_descriptor );
@@ -349,7 +294,7 @@ class WC_Gateway_Stripe_Sofort extends WC_Stripe_Payment_Gateway {
349
  if ( ! empty( $response->error ) ) {
350
  $order->add_order_note( $response->error->message );
351
 
352
- throw new Exception( $response->error->message );
353
  }
354
 
355
  if ( WC_Stripe_Helper::is_pre_30() ) {
@@ -365,8 +310,8 @@ class WC_Gateway_Stripe_Sofort extends WC_Stripe_Payment_Gateway {
365
  'result' => 'success',
366
  'redirect' => esc_url_raw( $response->redirect->url ),
367
  );
368
- } catch ( Exception $e ) {
369
- wc_add_notice( $e->getMessage(), 'error' );
370
  WC_Stripe_Logger::log( 'Error: ' . $e->getMessage() );
371
 
372
  do_action( 'wc_gateway_stripe_process_payment_error', $e, $order );
161
  return parent::is_available();
162
  }
163
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
  /**
165
  * Get_icon function.
166
  *
201
  $this->form_fields = require( WC_STRIPE_PLUGIN_PATH . '/includes/admin/stripe-sofort-settings.php' );
202
  }
203
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
204
  /**
205
  * Payment form on checkout page
206
  */
207
  public function payment_fields() {
208
+ $user = wp_get_current_user();
209
+ $total = WC()->cart->total;
210
 
211
  // If paying from order, we need to get total from order not cart.
212
  if ( isset( $_GET['pay_for_order'] ) && ! empty( $_GET['key'] ) ) {
230
  echo apply_filters( 'wc_stripe_description', wpautop( wp_kses_post( $this->description ) ) );
231
  }
232
 
 
 
233
  echo '</div>';
234
  }
235
 
242
  * @return mixed
243
  */
244
  public function create_source( $order ) {
245
+ $currency = WC_Stripe_Helper::is_pre_30() ? $order->get_order_currency() : $order->get_currency();
246
+ $bank_country = WC_Stripe_Helper::is_pre_30() ? $order->billing_country : $order->get_billing_country();
247
+ $return_url = $this->get_stripe_return_url( $order );
248
+ $post_data = array();
249
+ $post_data['amount'] = WC_Stripe_Helper::get_stripe_amount( $order->get_total(), $currency );
250
+ $post_data['currency'] = strtolower( $currency );
251
+ $post_data['type'] = 'sofort';
252
+ $post_data['owner'] = $this->get_owner_details( $order );
253
+ $post_data['redirect'] = array( 'return_url' => $return_url );
254
+ $post_data['sofort'] = array( 'country' => $bank_country );
 
255
 
256
  if ( ! empty( $this->statement_descriptor ) ) {
257
  $post_data['statement_descriptor'] = WC_Stripe_Helper::clean_statement_descriptor( $this->statement_descriptor );
294
  if ( ! empty( $response->error ) ) {
295
  $order->add_order_note( $response->error->message );
296
 
297
+ throw new WC_Stripe_Exception( print_r( $response, true ), $response->error->message );
298
  }
299
 
300
  if ( WC_Stripe_Helper::is_pre_30() ) {
310
  'result' => 'success',
311
  'redirect' => esc_url_raw( $response->redirect->url ),
312
  );
313
+ } catch ( WC_Stripe_Exception $e ) {
314
+ wc_add_notice( $e->getLocalizedMessage(), 'error' );
315
  WC_Stripe_Logger::log( 'Error: ' . $e->getMessage() );
316
 
317
  do_action( 'wc_gateway_stripe_process_payment_error', $e, $order );
includes/payment-methods/class-wc-stripe-payment-request.php CHANGED
@@ -98,6 +98,11 @@ class WC_Stripe_Payment_Request {
98
  add_action( 'woocommerce_proceed_to_checkout', array( $this, 'display_payment_request_button_html' ), 1 );
99
  add_action( 'woocommerce_proceed_to_checkout', array( $this, 'display_payment_request_button_separator_html' ), 2 );
100
 
 
 
 
 
 
101
  add_action( 'wc_ajax_wc_stripe_get_cart_details', array( $this, 'ajax_get_cart_details' ) );
102
  add_action( 'wc_ajax_wc_stripe_get_shipping_options', array( $this, 'ajax_get_shipping_options' ) );
103
  add_action( 'wc_ajax_wc_stripe_update_shipping_method', array( $this, 'ajax_update_shipping_method' ) );
@@ -585,8 +590,6 @@ class WC_Stripe_Payment_Request {
585
 
586
  $currency = get_woocommerce_currency();
587
 
588
- $display_items = $this->build_display_items();
589
-
590
  // Set mandatory payment details.
591
  $data = array(
592
  'shipping_required' => WC()->cart->needs_shipping(),
@@ -1068,7 +1071,7 @@ class WC_Stripe_Payment_Request {
1068
  'displayItems' => $items,
1069
  'total' => array(
1070
  'label' => $this->total_label,
1071
- 'amount' => max( 0, apply_filters( 'woocommerce_calculated_total', WC_Stripe_Helper::get_stripe_amount( $order_total ), $order_total, WC()->cart ) ),
1072
  'pending' => false,
1073
  ),
1074
  );
98
  add_action( 'woocommerce_proceed_to_checkout', array( $this, 'display_payment_request_button_html' ), 1 );
99
  add_action( 'woocommerce_proceed_to_checkout', array( $this, 'display_payment_request_button_separator_html' ), 2 );
100
 
101
+ if ( apply_filters( 'wc_stripe_show_payment_request_on_checkout', false ) ) {
102
+ add_action( 'woocommerce_checkout_before_customer_details', array( $this, 'display_payment_request_button_html' ), 1 );
103
+ add_action( 'woocommerce_checkout_before_customer_details', array( $this, 'display_payment_request_button_separator_html' ), 2 );
104
+ }
105
+
106
  add_action( 'wc_ajax_wc_stripe_get_cart_details', array( $this, 'ajax_get_cart_details' ) );
107
  add_action( 'wc_ajax_wc_stripe_get_shipping_options', array( $this, 'ajax_get_shipping_options' ) );
108
  add_action( 'wc_ajax_wc_stripe_update_shipping_method', array( $this, 'ajax_update_shipping_method' ) );
590
 
591
  $currency = get_woocommerce_currency();
592
 
 
 
593
  // Set mandatory payment details.
594
  $data = array(
595
  'shipping_required' => WC()->cart->needs_shipping(),
1071
  'displayItems' => $items,
1072
  'total' => array(
1073
  'label' => $this->total_label,
1074
+ 'amount' => max( 0, apply_filters( 'woocommerce_stripe_calculated_total', WC_Stripe_Helper::get_stripe_amount( $order_total ), $order_total, WC()->cart ) ),
1075
  'pending' => false,
1076
  ),
1077
  );
languages/woocommerce-gateway-stripe.pot DELETED
@@ -1,957 +0,0 @@
1
- msgid ""
2
- msgstr ""
3
- "Project-Id-Version: WooCommerce Stripe Gateway\n"
4
- "POT-Creation-Date: 2017-03-30 12:28-0800\n"
5
- "PO-Revision-Date: 2017-03-30 12:28-0800\n"
6
- "Last-Translator: \n"
7
- "Language-Team: \n"
8
- "Language: en_US\n"
9
- "MIME-Version: 1.0\n"
10
- "Content-Type: text/plain; charset=UTF-8\n"
11
- "Content-Transfer-Encoding: 8bit\n"
12
- "X-Generator: Poedit 1.7.3\n"
13
- "X-Poedit-Basepath: ..\n"
14
- "X-Poedit-SourceCharset: UTF-8\n"
15
- "X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;esc_attr__;"
16
- "esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c;_n_noop:1,2;"
17
- "_nx_noop:3c,1,2;__ngettext_noop:1,2\n"
18
- "Plural-Forms: nplurals=2; plural=(n != 1);\n"
19
- "X-Poedit-SearchPath-0: .\n"
20
- "X-Poedit-SearchPathExcluded-0: *.js\n"
21
-
22
- #: includes/class-wc-gateway-stripe-addons.php:106
23
- #: includes/class-wc-gateway-stripe-addons.php:153
24
- #: includes/class-wc-gateway-stripe.php:745
25
- #: includes/class-wc-stripe-apple-pay.php:684
26
- #: includes/legacy/class-wc-gateway-stripe.php:446
27
- #, php-format
28
- msgid ""
29
- "Sorry, the minimum allowed order total is %1$s to use this payment method."
30
- msgstr ""
31
-
32
- #: includes/class-wc-gateway-stripe-addons.php:119
33
- msgid "Customer not found"
34
- msgstr ""
35
-
36
- #: includes/class-wc-gateway-stripe-addons.php:160
37
- msgid "Unable to store payment details. Please try again."
38
- msgstr ""
39
-
40
- #: includes/class-wc-gateway-stripe-addons.php:217
41
- #: includes/class-wc-gateway-stripe-addons.php:260
42
- #, php-format
43
- msgid "Stripe Transaction Failed (%s)"
44
- msgstr ""
45
-
46
- #: includes/class-wc-gateway-stripe-addons.php:384
47
- #: includes/class-wc-gateway-stripe-addons.php:389
48
- #, php-format
49
- msgid "Via %1$s card ending in %2$s"
50
- msgstr ""
51
-
52
- #: includes/class-wc-gateway-stripe.php:123
53
- #: includes/legacy/class-wc-gateway-stripe.php:18
54
- msgid "Stripe"
55
- msgstr ""
56
-
57
- #: includes/class-wc-gateway-stripe.php:124
58
- #: includes/legacy/class-wc-gateway-stripe.php:19
59
- msgid ""
60
- "Stripe works by adding credit card fields on the checkout and then sending "
61
- "the details to Stripe for verification."
62
- msgstr ""
63
-
64
- #: includes/class-wc-gateway-stripe.php:172
65
- #: includes/legacy/class-wc-gateway-stripe.php:60
66
- msgid "Continue to payment"
67
- msgstr ""
68
-
69
- #: includes/class-wc-gateway-stripe.php:176
70
- #: includes/legacy/class-wc-gateway-stripe.php:64
71
- #, php-format
72
- msgid ""
73
- "TEST MODE ENABLED. In test mode, you can use the card number "
74
- "4242424242424242 with any CVC and a valid expiration date or check the "
75
- "documentation \"<a href=\"%s\">Testing Stripe</a>\" for more card numbers."
76
- msgstr ""
77
-
78
- #: includes/class-wc-gateway-stripe.php:282
79
- msgid "Unable to verify domain - missing secret key."
80
- msgstr ""
81
-
82
- #: includes/class-wc-gateway-stripe.php:306
83
- #, php-format
84
- msgid "Unable to verify domain - %s"
85
- msgstr ""
86
-
87
- #: includes/class-wc-gateway-stripe.php:331
88
- msgid "Unable to create domain association folder to domain root."
89
- msgstr ""
90
-
91
- #: includes/class-wc-gateway-stripe.php:337
92
- msgid "Unable to copy domain association file to domain root."
93
- msgstr ""
94
-
95
- #: includes/class-wc-gateway-stripe.php:351
96
- msgid "Your domain has been verified with Apple Pay!"
97
- msgstr ""
98
-
99
- #: includes/class-wc-gateway-stripe.php:358
100
- #: includes/class-wc-gateway-stripe.php:795
101
- #: includes/class-wc-stripe-apple-pay.php:718
102
- #: includes/legacy/class-wc-gateway-stripe.php:481
103
- #, php-format
104
- msgid "Error: %s"
105
- msgstr ""
106
-
107
- #: includes/class-wc-gateway-stripe.php:380
108
- #, php-format
109
- msgid ""
110
- "Apple Pay domain verification failed. Please check the %1$slog%2$s to see "
111
- "the issue. (Logging must be enabled to see recorded logs)"
112
- msgstr ""
113
-
114
- #: includes/class-wc-gateway-stripe.php:385
115
- #: includes/legacy/class-wc-gateway-stripe.php:165
116
- #, php-format
117
- msgid ""
118
- "Stripe is enabled, but the <a href=\"%s\">force SSL option</a> is disabled; "
119
- "your checkout may not be secure! Please enable SSL and ensure your server "
120
- "has a valid SSL certificate - Stripe will only work in test mode."
121
- msgstr ""
122
-
123
- #: includes/class-wc-gateway-stripe.php:434
124
- msgid "Add Card"
125
- msgstr ""
126
-
127
- #: includes/class-wc-gateway-stripe.php:481
128
- msgid "The card number is not a valid credit card number."
129
- msgstr ""
130
-
131
- #: includes/class-wc-gateway-stripe.php:482
132
- msgid "The card's expiration month is invalid."
133
- msgstr ""
134
-
135
- #: includes/class-wc-gateway-stripe.php:483
136
- msgid "The card's expiration year is invalid."
137
- msgstr ""
138
-
139
- #: includes/class-wc-gateway-stripe.php:484
140
- msgid "The card's security code is invalid."
141
- msgstr ""
142
-
143
- #: includes/class-wc-gateway-stripe.php:485
144
- msgid "The card number is incorrect."
145
- msgstr ""
146
-
147
- #: includes/class-wc-gateway-stripe.php:486
148
- msgid "The card has expired."
149
- msgstr ""
150
-
151
- #: includes/class-wc-gateway-stripe.php:487
152
- msgid "The card's security code is incorrect."
153
- msgstr ""
154
-
155
- #: includes/class-wc-gateway-stripe.php:488
156
- msgid "The card's zip code failed validation."
157
- msgstr ""
158
-
159
- #: includes/class-wc-gateway-stripe.php:489
160
- msgid "The card was declined."
161
- msgstr ""
162
-
163
- #: includes/class-wc-gateway-stripe.php:490
164
- msgid "There is no card on a customer that is being charged."
165
- msgstr ""
166
-
167
- #: includes/class-wc-gateway-stripe.php:491
168
- msgid "An error occurred while processing the card."
169
- msgstr ""
170
-
171
- #: includes/class-wc-gateway-stripe.php:492
172
- msgid "Could not find payment information."
173
- msgstr ""
174
-
175
- #: includes/class-wc-gateway-stripe.php:513
176
- msgid ""
177
- "This is not a valid live key. Live keys start with \"sk_live_\" and "
178
- "\"pk_live_\"."
179
- msgstr ""
180
-
181
- #: includes/class-wc-gateway-stripe.php:514
182
- msgid ""
183
- "This is not a valid test key. Test keys start with \"sk_test_\" and "
184
- "\"pk_test_\"."
185
- msgstr ""
186
-
187
- #: includes/class-wc-gateway-stripe.php:515
188
- msgid "Re-verify Domain"
189
- msgstr ""
190
-
191
- #: includes/class-wc-gateway-stripe.php:516
192
- msgid "Missing Secret Key. Please set the secret key field above and re-try."
193
- msgstr ""
194
-
195
- #: includes/class-wc-gateway-stripe.php:551
196
- #: includes/legacy/class-wc-gateway-stripe.php:296
197
- msgid "Please accept the terms and conditions first"
198
- msgstr ""
199
-
200
- #: includes/class-wc-gateway-stripe.php:552
201
- #: includes/legacy/class-wc-gateway-stripe.php:297
202
- msgid "Please fill in required checkout fields first"
203
- msgstr ""
204
-
205
- #: includes/class-wc-gateway-stripe.php:570
206
- #: includes/class-wc-stripe-payment-request.php:95
207
- msgid "Sorry, we're not accepting prepaid cards at this time."
208
- msgstr ""
209
-
210
- #: includes/class-wc-gateway-stripe.php:590
211
- #: includes/class-wc-stripe-apple-pay.php:738
212
- #, php-format
213
- msgid "%1$s - Order %2$s"
214
- msgstr ""
215
-
216
- #: includes/class-wc-gateway-stripe.php:604
217
- msgid "Customer Name"
218
- msgstr ""
219
-
220
- #: includes/class-wc-gateway-stripe.php:605
221
- msgid "Customer Email"
222
- msgstr ""
223
-
224
- #: includes/class-wc-gateway-stripe.php:668
225
- msgid "Invalid payment method. Please input a new card number."
226
- msgstr ""
227
-
228
- #: includes/class-wc-gateway-stripe.php:733
229
- #: includes/legacy/class-wc-gateway-stripe.php:434
230
- msgid "Please enter your card details to make a payment."
231
- msgstr ""
232
-
233
- #: includes/class-wc-gateway-stripe.php:734
234
- #: includes/legacy/class-wc-gateway-stripe.php:435
235
- msgid ""
236
- "Developers: Please make sure that you are including jQuery and there are no "
237
- "JavaScript errors on the page."
238
- msgstr ""
239
-
240
- #: includes/class-wc-gateway-stripe.php:762
241
- msgid "This card is no longer available and has been removed."
242
- msgstr ""
243
-
244
- #: includes/class-wc-gateway-stripe.php:853 woocommerce-gateway-stripe.php:470
245
- #, php-format
246
- msgid "Stripe charge complete (Charge ID: %s)"
247
- msgstr ""
248
-
249
- #: includes/class-wc-gateway-stripe.php:864
250
- #: includes/legacy/class-wc-gateway-stripe.php:526
251
- #, php-format
252
- msgid ""
253
- "Stripe charge authorized (Charge ID: %s). Process order to take payment, or "
254
- "cancel to remove the pre-authorization."
255
- msgstr ""
256
-
257
- #: includes/class-wc-gateway-stripe.php:878
258
- #: includes/class-wc-gateway-stripe.php:887
259
- #: includes/legacy/class-wc-gateway-stripe.php:540
260
- msgid "There was a problem adding the card."
261
- msgstr ""
262
-
263
- #: includes/class-wc-gateway-stripe.php:939
264
- #, php-format
265
- msgid "Refunded %1$s - Refund ID: %2$s - Reason: %3$s"
266
- msgstr ""
267
-
268
- #: includes/class-wc-stripe-api.php:73
269
- msgid "There was a problem connecting to the payment gateway."
270
- msgstr ""
271
-
272
- #: includes/class-wc-stripe-apple-pay.php:192
273
- #: includes/class-wc-stripe-apple-pay.php:416
274
- #: includes/class-wc-stripe-apple-pay.php:470
275
- #: includes/class-wc-stripe-apple-pay.php:559
276
- #: includes/class-wc-stripe-apple-pay.php:622
277
- #: includes/class-wc-stripe-apple-pay.php:670
278
- msgid "Cheatin&#8217; huh?"
279
- msgstr ""
280
-
281
- #: includes/class-wc-stripe-apple-pay.php:265
282
- #: includes/class-wc-stripe-apple-pay.php:821
283
- msgid "Sub-Total"
284
- msgstr ""
285
-
286
- #: includes/class-wc-stripe-apple-pay.php:404
287
- msgid "Or"
288
- msgstr ""
289
-
290
- #: includes/class-wc-stripe-apple-pay.php:503
291
- msgid "Please enter a valid postcode/ZIP."
292
- msgstr ""
293
-
294
- #: includes/class-wc-stripe-apple-pay.php:580
295
- #: includes/class-wc-stripe-apple-pay.php:603
296
- msgid "Unable to find shipping method for address."
297
- msgstr ""
298
-
299
- #: includes/class-wc-stripe-apple-pay.php:650
300
- #: includes/class-wc-stripe-apple-pay.php:835
301
- #: includes/class-wc-stripe-payment-request.php:348
302
- msgid "Tax"
303
- msgstr ""
304
-
305
- #: includes/class-wc-stripe-apple-pay.php:843
306
- msgid "Shipping"
307
- msgstr ""
308
-
309
- #: includes/class-wc-stripe-apple-pay.php:851
310
- msgid "Discount"
311
- msgstr ""
312
-
313
- #: includes/class-wc-stripe-apple-pay.php:869
314
- #: includes/class-wc-stripe-apple-pay.php:876
315
- #: includes/class-wc-stripe-apple-pay.php:878
316
- #: includes/class-wc-stripe-apple-pay.php:901
317
- #: includes/class-wc-stripe-apple-pay.php:933
318
- #: includes/class-wc-stripe-apple-pay.php:965
319
- #: includes/class-wc-stripe-apple-pay.php:989
320
- #, php-format
321
- msgid "Error %d: Unable to create order. Please try again."