WooCommerce Stripe Payment Gateway - Version 3.0.6

Version Description

  • Fix - When adding declined cards, fatal error is thrown.
  • Fix - After a failed/declined process, valid cards are not accepted.
  • Fix - When paying via pay order page/link, billing info is not sent.
  • Fix - Account for all types of errors for proper localization.
  • Fix - Correctly reference Stripe fees/net based on Stripe account locale.
  • Fix - Bitcoin image not showing.
  • New - Introduce "wc_gateway_stripe_process_payment_error" action hook.
  • New - Introduce "wc_gateway_stripe_process_payment" action hook.
Download this release

Release Info

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

Code changes from version 3.0.5 to 3.0.6

assets/js/stripe.js CHANGED
@@ -2,6 +2,8 @@
2
  Stripe.setPublishableKey( wc_stripe_params.key );
3
 
4
  jQuery( function( $ ) {
 
 
5
  /* Open and close for legacy class */
6
  $( 'form.checkout, form#order_review' ).on( 'change', 'input[name="wc-stripe-payment-token"]', function() {
7
  if ( 'new' === $( '.stripe-legacy-payment-fields input[name="wc-stripe-payment-token"]:checked' ).val() ) {
@@ -62,6 +64,10 @@ jQuery( function( $ ) {
62
  .on(
63
  'stripeError',
64
  this.onError
 
 
 
 
65
  );
66
  },
67
 
@@ -90,7 +96,19 @@ jQuery( function( $ ) {
90
  onError: function( e, responseObject ) {
91
  var message = responseObject.response.error.message;
92
 
93
- if ( wc_stripe_params.hasOwnProperty( responseObject.response.error.code ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
94
  message = wc_stripe_params[ responseObject.response.error.code ];
95
  }
96
 
@@ -112,12 +130,12 @@ jQuery( function( $ ) {
112
  data = {
113
  number : card,
114
  cvc : cvc,
115
- exp_month: parseInt( expires['month'], 10 ) || 0,
116
- exp_year : parseInt( expires['year'], 10 ) || 0
117
  };
118
 
119
  if ( first_name && last_name ) {
120
- data.name = first_name + ' ' + last_name
121
  }
122
 
123
  if ( $( '#billing_address_1' ).length > 0 ) {
@@ -161,12 +179,16 @@ jQuery( function( $ ) {
161
  }
162
 
163
  // token contains id, last4, and card type
164
- var token = response['id'];
165
 
166
  // insert the token into the form so it gets submitted to the server
167
  wc_stripe_form.form.append( "<input type='hidden' class='stripe_token' name='stripe_token' value='" + token + "'/>" );
168
  wc_stripe_form.form.submit();
169
  }
 
 
 
 
170
  }
171
  };
172
 
2
  Stripe.setPublishableKey( wc_stripe_params.key );
3
 
4
  jQuery( function( $ ) {
5
+ 'use strict';
6
+
7
  /* Open and close for legacy class */
8
  $( 'form.checkout, form#order_review' ).on( 'change', 'input[name="wc-stripe-payment-token"]', function() {
9
  if ( 'new' === $( '.stripe-legacy-payment-fields input[name="wc-stripe-payment-token"]:checked' ).val() ) {
64
  .on(
65
  'stripeError',
66
  this.onError
67
+ )
68
+ .on(
69
+ 'checkout_error',
70
+ this.clearToken
71
  );
72
  },
73
 
96
  onError: function( e, responseObject ) {
97
  var message = responseObject.response.error.message;
98
 
99
+ // Customers do not need to know the specifics of the below type of errors
100
+ // therefore return a generic localizable error message.
101
+ if (
102
+ 'invalid_request_error' === responseObject.response.error.type ||
103
+ 'api_connection_error' === responseObject.response.error.type ||
104
+ 'api_error' === responseObject.response.error.type ||
105
+ 'authentication_error' === responseObject.response.error.type ||
106
+ 'rate_limit_error' === responseObject.response.error.type
107
+ ) {
108
+ message = wc_stripe_params.invalid_request_error;
109
+ }
110
+
111
+ if ( 'card_error' === responseObject.response.error.type && wc_stripe_params.hasOwnProperty( responseObject.response.error.code ) ) {
112
  message = wc_stripe_params[ responseObject.response.error.code ];
113
  }
114
 
130
  data = {
131
  number : card,
132
  cvc : cvc,
133
+ exp_month: parseInt( expires.month, 10 ) || 0,
134
+ exp_year : parseInt( expires.year, 10 ) || 0
135
  };
136
 
137
  if ( first_name && last_name ) {
138
+ data.name = first_name + ' ' + last_name;
139
  }
140
 
141
  if ( $( '#billing_address_1' ).length > 0 ) {
179
  }
180
 
181
  // token contains id, last4, and card type
182
+ var token = response.id;
183
 
184
  // insert the token into the form so it gets submitted to the server
185
  wc_stripe_form.form.append( "<input type='hidden' class='stripe_token' name='stripe_token' value='" + token + "'/>" );
186
  wc_stripe_form.form.submit();
187
  }
188
+ },
189
+
190
+ clearToken: function() {
191
+ $( '.stripe_token' ).remove();
192
  }
193
  };
194
 
assets/js/stripe.min.js CHANGED
@@ -1 +1 @@
1
- Stripe.setPublishableKey(wc_stripe_params.key),jQuery(function(a){a("form.checkout, form#order_review").on("change",'input[name="wc-stripe-payment-token"]',function(){"new"===a('.stripe-legacy-payment-fields input[name="wc-stripe-payment-token"]:checked').val()?a(".stripe-legacy-payment-fields #stripe-payment-data").slideDown(200):a(".stripe-legacy-payment-fields #stripe-payment-data").slideUp(200)});var b={init:function(){a("form.woocommerce-checkout").length&&(this.form=a("form.woocommerce-checkout")),a("form.woocommerce-checkout").on("checkout_place_order_stripe",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(document).on("change","#wc-stripe-cc-form :input",this.onCCFormChange).on("stripeError",this.onError)},isStripeChosen:function(){return a("#payment_method_stripe").is(":checked")&&(!a('input[name="wc-stripe-payment-token"]:checked').length||"new"===a('input[name="wc-stripe-payment-token"]:checked').val())},hasToken:function(){return 0<a("input.stripe_token").length},block:function(){b.form.block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},unblock:function(){b.form.unblock()},onError:function(c,d){var e=d.response.error.message;wc_stripe_params.hasOwnProperty(d.response.error.code)&&(e=wc_stripe_params[d.response.error.code]),a(".woocommerce-error, .stripe_token").remove(),a("#stripe-card-number").closest("p").before('<ul class="woocommerce_error woocommerce-error"><li>'+e+"</li></ul>"),b.unblock()},onSubmit:function(c){if(b.isStripeChosen()&&!b.hasToken()){c.preventDefault(),b.block();var d=a("#stripe-card-number").val(),e=a("#stripe-card-cvc").val(),f=a("#stripe-card-expiry").payment("cardExpiryVal"),g=a("#billing_first_name").length?a("#billing_first_name").val():wc_stripe_params.billing_first_name,h=a("#billing_last_name").length?a("#billing_last_name").val():wc_stripe_params.billing_last_name,i={number:d,cvc:e,exp_month:parseInt(f.month,10)||0,exp_year:parseInt(f.year,10)||0};return g&&h&&(i.name=g+" "+h),a("#billing_address_1").length>0?(i.address_line1=a("#billing_address_1").val(),i.address_line2=a("#billing_address_2").val(),i.address_state=a("#billing_state").val(),i.address_city=a("#billing_city").val(),i.address_zip=a("#billing_postcode").val(),i.address_country=a("#billing_country").val()):wc_stripe_params.billing_address_1&&(i.address_line1=wc_stripe_params.billing_address_1,i.address_line2=wc_stripe_params.billing_address_2,i.address_state=wc_stripe_params.billing_state,i.address_city=wc_stripe_params.billing_city,i.address_zip=wc_stripe_params.billing_postcode,i.address_country=wc_stripe_params.billing_country),Stripe.createToken(i,b.onStripeResponse),!1}},onCCFormChange:function(){a(".woocommerce-error, .stripe_token").remove()},onStripeResponse:function(c,d){if(d.error)a(document).trigger("stripeError",{response:d});else{if("no"===wc_stripe_params.allow_prepaid_card&&"prepaid"===d.card.funding)return d.error={message:wc_stripe_params.no_prepaid_card_msg},a(document).trigger("stripeError",{response:d}),!1;var e=d.id;b.form.append("<input type='hidden' class='stripe_token' name='stripe_token' value='"+e+"'/>"),b.form.submit()}}};b.init()});
1
+ Stripe.setPublishableKey(wc_stripe_params.key),jQuery(function(a){"use strict";a("form.checkout, form#order_review").on("change",'input[name="wc-stripe-payment-token"]',function(){"new"===a('.stripe-legacy-payment-fields input[name="wc-stripe-payment-token"]:checked').val()?a(".stripe-legacy-payment-fields #stripe-payment-data").slideDown(200):a(".stripe-legacy-payment-fields #stripe-payment-data").slideUp(200)});var b={init:function(){a("form.woocommerce-checkout").length&&(this.form=a("form.woocommerce-checkout")),a("form.woocommerce-checkout").on("checkout_place_order_stripe",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(document).on("change","#wc-stripe-cc-form :input",this.onCCFormChange).on("stripeError",this.onError).on("checkout_error",this.clearToken)},isStripeChosen:function(){return a("#payment_method_stripe").is(":checked")&&(!a('input[name="wc-stripe-payment-token"]:checked').length||"new"===a('input[name="wc-stripe-payment-token"]:checked').val())},hasToken:function(){return 0<a("input.stripe_token").length},block:function(){b.form.block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},unblock:function(){b.form.unblock()},onError:function(c,d){var e=d.response.error.message;("invalid_request_error"===d.response.error.type||"api_connection_error"===d.response.error.type||"api_error"===d.response.error.type||"authentication_error"===d.response.error.type||"rate_limit_error"===d.response.error.type)&&(e=wc_stripe_params.invalid_request_error),"card_error"===d.response.error.type&&wc_stripe_params.hasOwnProperty(d.response.error.code)&&(e=wc_stripe_params[d.response.error.code]),a(".woocommerce-error, .stripe_token").remove(),a("#stripe-card-number").closest("p").before('<ul class="woocommerce_error woocommerce-error"><li>'+e+"</li></ul>"),b.unblock()},onSubmit:function(c){if(b.isStripeChosen()&&!b.hasToken()){c.preventDefault(),b.block();var d=a("#stripe-card-number").val(),e=a("#stripe-card-cvc").val(),f=a("#stripe-card-expiry").payment("cardExpiryVal"),g=a("#billing_first_name").length?a("#billing_first_name").val():wc_stripe_params.billing_first_name,h=a("#billing_last_name").length?a("#billing_last_name").val():wc_stripe_params.billing_last_name,i={number:d,cvc:e,exp_month:parseInt(f.month,10)||0,exp_year:parseInt(f.year,10)||0};return g&&h&&(i.name=g+" "+h),a("#billing_address_1").length>0?(i.address_line1=a("#billing_address_1").val(),i.address_line2=a("#billing_address_2").val(),i.address_state=a("#billing_state").val(),i.address_city=a("#billing_city").val(),i.address_zip=a("#billing_postcode").val(),i.address_country=a("#billing_country").val()):wc_stripe_params.billing_address_1&&(i.address_line1=wc_stripe_params.billing_address_1,i.address_line2=wc_stripe_params.billing_address_2,i.address_state=wc_stripe_params.billing_state,i.address_city=wc_stripe_params.billing_city,i.address_zip=wc_stripe_params.billing_postcode,i.address_country=wc_stripe_params.billing_country),Stripe.createToken(i,b.onStripeResponse),!1}},onCCFormChange:function(){a(".woocommerce-error, .stripe_token").remove()},onStripeResponse:function(c,d){if(d.error)a(document).trigger("stripeError",{response:d});else{if("no"===wc_stripe_params.allow_prepaid_card&&"prepaid"===d.card.funding)return d.error={message:wc_stripe_params.no_prepaid_card_msg},a(document).trigger("stripeError",{response:d}),!1;var e=d.id;b.form.append("<input type='hidden' class='stripe_token' name='stripe_token' value='"+e+"'/>"),b.form.submit()}},clearToken:function(){a(".stripe_token").remove()}};b.init()});
assets/js/stripe_checkout.js CHANGED
@@ -1,4 +1,6 @@
1
  jQuery( function( $ ) {
 
 
2
  /**
3
  * Object to handle Stripe payment forms.
4
  */
@@ -18,6 +20,8 @@ jQuery( function( $ ) {
18
 
19
  // WooCommerce lets us return a false on checkout_place_order_{gateway} to keep the form from submitting
20
  .on( 'submit checkout_place_order_stripe' );
 
 
21
  },
22
 
23
  isStripeChosen: function() {
@@ -127,6 +131,11 @@ jQuery( function( $ ) {
127
  }
128
 
129
  return true;
 
 
 
 
 
130
  }
131
  };
132
 
1
  jQuery( function( $ ) {
2
+ 'use strict';
3
+
4
  /**
5
  * Object to handle Stripe payment forms.
6
  */
20
 
21
  // WooCommerce lets us return a false on checkout_place_order_{gateway} to keep the form from submitting
22
  .on( 'submit checkout_place_order_stripe' );
23
+
24
+ $( document.body ).on( 'checkout_error', this.resetModal );
25
  },
26
 
27
  isStripeChosen: function() {
131
  }
132
 
133
  return true;
134
+ },
135
+
136
+ resetModal: function() {
137
+ wc_stripe_form.form.find( 'input.stripe_token' ).remove();
138
+ wc_stripe_form.stripe_submit = false;
139
  }
140
  };
141
 
assets/js/stripe_checkout.min.js CHANGED
@@ -1 +1 @@
1
- jQuery(function(a){var b={init:function(b){this.form=b,this.stripe_submit=!1,a(this.form).on("click","#place_order",this.onSubmit).on("submit checkout_place_order_stripe")},isStripeChosen:function(){return a("#payment_method_stripe").is(":checked")&&(!a('input[name="wc-stripe-payment-token"]:checked').length||"new"===a('input[name="wc-stripe-payment-token"]:checked').val())},isStripeModalNeeded:function(c){var d,e=b.form.find("input.stripe_token");if(b.stripe_submit&&e)return!1;if(!b.isStripeChosen())return!1;if(1===a("input#terms").length&&0===a("input#terms:checked").length)return!1;if(a("#createaccount").is(":checked")&&a("#account_password").length&&""===a("#account_password").val())return!1;if(d=a(a("#ship-to-different-address-checkbox").is(":checked")?".woocommerce-billing-fields .validate-required, .woocommerce-shipping-fields .validate-required":".woocommerce-billing-fields .validate-required"),d.length){var f=!1;if(d.each(function(){""===a(this).find("input.input-text, select").not(a("#account_password, #account_username")).val()&&(f=!0)}),f)return!1}return!0},block:function(){b.form.block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},unblock:function(){b.form.unblock()},onClose:function(){b.unblock()},onSubmit:function(c){if(b.isStripeModalNeeded()){c.preventDefault();var d=b.form,e=a("#stripe-payment-data"),f=d.find("input.stripe_token");f.val("");var g=function(a){d.find("input.stripe_token").remove(),d.append('<input type="hidden" class="stripe_token" name="stripe_token" value="'+a.id+'"/>'),b.stripe_submit=!0,d.submit()};return StripeCheckout.open({key:wc_stripe_params.key,billingAddress:"yes"===wc_stripe_params.stripe_checkout_require_billing_address?!0:!1,amount:e.data("amount"),name:e.data("name"),description:e.data("description"),currency:e.data("currency"),image:e.data("image"),bitcoin:e.data("bitcoin"),locale:e.data("locale"),email:a("#billing_email").val()||e.data("email"),panelLabel:e.data("panel-label"),token:g,closed:b.onClose()}),!1}return!0}};b.init(a("form.checkout, form#order_review, form#add_payment_method"))});
1
+ jQuery(function(a){"use strict";var b={init:function(b){this.form=b,this.stripe_submit=!1,a(this.form).on("click","#place_order",this.onSubmit).on("submit checkout_place_order_stripe"),a(document.body).on("checkout_error",this.resetModal)},isStripeChosen:function(){return a("#payment_method_stripe").is(":checked")&&(!a('input[name="wc-stripe-payment-token"]:checked').length||"new"===a('input[name="wc-stripe-payment-token"]:checked').val())},isStripeModalNeeded:function(c){var d,e=b.form.find("input.stripe_token");if(b.stripe_submit&&e)return!1;if(!b.isStripeChosen())return!1;if(1===a("input#terms").length&&0===a("input#terms:checked").length)return!1;if(a("#createaccount").is(":checked")&&a("#account_password").length&&""===a("#account_password").val())return!1;if(d=a(a("#ship-to-different-address-checkbox").is(":checked")?".woocommerce-billing-fields .validate-required, .woocommerce-shipping-fields .validate-required":".woocommerce-billing-fields .validate-required"),d.length){var f=!1;if(d.each(function(){""===a(this).find("input.input-text, select").not(a("#account_password, #account_username")).val()&&(f=!0)}),f)return!1}return!0},block:function(){b.form.block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},unblock:function(){b.form.unblock()},onClose:function(){b.unblock()},onSubmit:function(c){if(b.isStripeModalNeeded()){c.preventDefault();var d=b.form,e=a("#stripe-payment-data"),f=d.find("input.stripe_token");f.val("");var g=function(a){d.find("input.stripe_token").remove(),d.append('<input type="hidden" class="stripe_token" name="stripe_token" value="'+a.id+'"/>'),b.stripe_submit=!0,d.submit()};return StripeCheckout.open({key:wc_stripe_params.key,billingAddress:"yes"===wc_stripe_params.stripe_checkout_require_billing_address?!0:!1,amount:e.data("amount"),name:e.data("name"),description:e.data("description"),currency:e.data("currency"),image:e.data("image"),bitcoin:e.data("bitcoin"),locale:e.data("locale"),email:a("#billing_email").val()||e.data("email"),panelLabel:e.data("panel-label"),token:g,closed:b.onClose()}),!1}return!0},resetModal:function(){b.form.find("input.stripe_token").remove(),b.stripe_submit=!1}};b.init(a("form.checkout, form#order_review, form#add_payment_method"))});
includes/class-wc-gateway-stripe.php CHANGED
@@ -104,6 +104,7 @@ class WC_Gateway_Stripe extends WC_Payment_Gateway_CC {
104
  'multiple_subscriptions',
105
  'pre-orders',
106
  'tokenization',
 
107
  );
108
 
109
  // Load the form fields.
@@ -164,8 +165,8 @@ class WC_Gateway_Stripe extends WC_Payment_Gateway_CC {
164
  $icon .= '<img src="' . WC_HTTPS::force_https_url( WC()->plugin_url() . '/assets/images/icons/credit-cards/diners' . $ext ) . '" alt="Diners" width="32" ' . $style . ' />';
165
  }
166
 
167
- if ( 'yes' === $this->bitcoin && 'yes' === $this->stripe_checkout ) {
168
- $icon .= '<img src="' . WC_HTTPS::force_https_url( plugins_url( '/assets/images/bitcoin' . $ext, WC_STRIPE_MAIN_FILE ) ) . '" alt="Bitcoin" width="32" ' . $style . ' />';
169
  }
170
 
171
  return apply_filters( 'woocommerce_gateway_icon', $icon, $this->id );
@@ -306,7 +307,7 @@ class WC_Gateway_Stripe extends WC_Payment_Gateway_CC {
306
  data-description=""
307
  data-email="' . esc_attr( $user_email ) . '"
308
  data-amount="' . esc_attr( $this->get_stripe_amount( WC()->cart->total ) ) . '"
309
- data-name="' . esc_attr( sprintf( __( '%s', 'woocommerce-gateway-stripe' ), get_bloginfo( 'name', 'display' ) ) ) . '"
310
  data-currency="' . esc_attr( strtolower( get_woocommerce_currency() ) ) . '"
311
  data-image="' . esc_attr( $this->stripe_checkout_image ) . '"
312
  data-bitcoin="' . esc_attr( $this->bitcoin ? 'true' : 'false' ) . '"
@@ -332,6 +333,30 @@ class WC_Gateway_Stripe extends WC_Payment_Gateway_CC {
332
  echo '</div>';
333
  }
334
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
335
  /**
336
  * payment_scripts function.
337
  *
@@ -357,40 +382,26 @@ class WC_Gateway_Stripe extends WC_Payment_Gateway_CC {
357
  );
358
 
359
  // If we're on the pay page we need to pass stripe.js the address of the order.
360
- if ( is_checkout_pay_page() && isset( $_GET['order'] ) && isset( $_GET['order_id'] ) ) {
361
- $order_key = urldecode( $_GET['order'] );
362
- $order_id = absint( $_GET['order_id'] );
363
- $order = wc_get_order( $order_id );
364
-
365
- if ( $order->id === $order_id && $order->order_key === $order_key ) {
366
- $stripe_params['billing_first_name'] = $order->billing_first_name;
367
- $stripe_params['billing_last_name'] = $order->billing_last_name;
368
- $stripe_params['billing_address_1'] = $order->billing_address_1;
369
- $stripe_params['billing_address_2'] = $order->billing_address_2;
370
- $stripe_params['billing_state'] = $order->billing_state;
371
- $stripe_params['billing_city'] = $order->billing_city;
372
- $stripe_params['billing_postcode'] = $order->billing_postcode;
373
- $stripe_params['billing_country'] = $order->billing_country;
374
- }
375
  }
376
 
377
  $stripe_params['no_prepaid_card_msg'] = __( 'Sorry, we\'re not accepting prepaid cards at this time.', 'woocommerce-gateway-stripe' );
378
  $stripe_params['allow_prepaid_card'] = apply_filters( 'wc_stripe_allow_prepaid_card', true ) ? 'yes' : 'no';
379
  $stripe_params['stripe_checkout_require_billing_address'] = apply_filters( 'wc_stripe_checkout_require_billing_address', false ) ? 'yes' : 'no';
380
 
381
- // localize error messages from Stripe
382
- $stripe_params['invalid_number'] = __( 'The card number is not a valid credit card number.', 'woocommerce-gateway-stripe' );
383
- $stripe_params['invalid_expiry_month'] = __( 'The card\'s expiration month is invalid.', 'woocommerce-gateway-stripe' );
384
- $stripe_params['invalid_expiry_year'] = __( 'The card\'s expiration year is invalid.', 'woocommerce-gateway-stripe' );
385
- $stripe_params['invalid_cvc'] = __( 'The card\'s security code is invalid.', 'woocommerce-gateway-stripe' );
386
- $stripe_params['incorrect_number'] = __( 'The card number is incorrect.', 'woocommerce-gateway-stripe' );
387
- $stripe_params['expired_card'] = __( 'The card has expired.', 'woocommerce-gateway-stripe' );
388
- $stripe_params['incorrect_cvc'] = __( 'The card\'s security code is incorrect.', 'woocommerce-gateway-stripe' );
389
- $stripe_params['incorrect_zip'] = __( 'The card\'s zip code failed validation.', 'woocommerce-gateway-stripe' );
390
- $stripe_params['card_declined'] = __( 'The card was declined.', 'woocommerce-gateway-stripe' );
391
- $stripe_params['missing'] = __( 'There is no card on a customer that is being charged.', 'woocommerce-gateway-stripe' );
392
- $stripe_params['processing_error'] = __( 'An error occurred while processing the card.', 'woocommerce-gateway-stripe' );
393
- $stripe_params['invalid_request_error'] = __( 'Could not find payment information.', 'woocommerce-gateway-stripe' );
394
 
395
  wp_localize_script( 'woocommerce_stripe', 'wc_stripe_params', apply_filters( 'wc_stripe_params', $stripe_params ) );
396
  }
@@ -421,7 +432,7 @@ class WC_Gateway_Stripe extends WC_Payment_Gateway_CC {
421
  if ( $source->source ) {
422
  $post_data['source'] = $source->source;
423
  }
424
-
425
  /**
426
  * Filter the return value of the WC_Payment_Gateway_CC::generate_payment_request.
427
  *
@@ -567,7 +578,9 @@ class WC_Gateway_Stripe extends WC_Payment_Gateway_CC {
567
  $token->delete();
568
  throw new Exception( __( 'This card is no longer available and has been removed.', 'woocommerce-gateway-stripe' ) );
569
  }
570
- throw new Exception( $response->get_error_code() . ': ' . $response->get_error_message() );
 
 
571
  }
572
 
573
  // Process valid response.
@@ -579,6 +592,8 @@ class WC_Gateway_Stripe extends WC_Payment_Gateway_CC {
579
  // Remove cart.
580
  WC()->cart->empty_cart();
581
 
 
 
582
  // Return thank you page redirect.
583
  return array(
584
  'result' => 'success',
@@ -587,14 +602,18 @@ class WC_Gateway_Stripe extends WC_Payment_Gateway_CC {
587
 
588
  } catch ( Exception $e ) {
589
  wc_add_notice( $e->getMessage(), 'error' );
590
- WC()->session->set( 'refresh_totals', true );
591
  WC_Stripe::log( sprintf( __( 'Error: %s', 'woocommerce-gateway-stripe' ), $e->getMessage() ) );
592
 
593
  if ( $order->has_status( array( 'pending', 'failed' ) ) ) {
594
  $this->send_failed_order_email( $order_id );
595
  }
596
 
597
- return;
 
 
 
 
 
598
  }
599
  }
600
 
@@ -626,9 +645,12 @@ class WC_Gateway_Stripe extends WC_Payment_Gateway_CC {
626
 
627
  // Store other data such as fees
628
  if ( isset( $response->balance_transaction ) && isset( $response->balance_transaction->fee ) ) {
629
- $fee = number_format( $response->balance_transaction->fee / 100, 2, '.', '' );
 
 
 
630
  update_post_meta( $order->id, 'Stripe Fee', $fee );
631
- update_post_meta( $order->id, 'Net Revenue From Stripe', $order->get_total() - $fee );
632
  }
633
 
634
  if ( $response->captured ) {
@@ -667,7 +689,18 @@ class WC_Gateway_Stripe extends WC_Payment_Gateway_CC {
667
  $card = $stripe_customer->add_card( wc_clean( $_POST['stripe_token'] ) );
668
 
669
  if ( is_wp_error( $card ) ) {
670
- throw new Exception( $card->get_error_message() );
 
 
 
 
 
 
 
 
 
 
 
671
  }
672
 
673
  return array(
104
  'multiple_subscriptions',
105
  'pre-orders',
106
  'tokenization',
107
+ 'add_payment_method'
108
  );
109
 
110
  // Load the form fields.
165
  $icon .= '<img src="' . WC_HTTPS::force_https_url( WC()->plugin_url() . '/assets/images/icons/credit-cards/diners' . $ext ) . '" alt="Diners" width="32" ' . $style . ' />';
166
  }
167
 
168
+ if ( $this->bitcoin && $this->stripe_checkout ) {
169
+ $icon .= '<img src="' . WC_HTTPS::force_https_url( plugins_url( '/assets/images/bitcoin' . $ext, WC_STRIPE_MAIN_FILE ) ) . '" alt="Bitcoin" width="24" ' . $style . ' />';
170
  }
171
 
172
  return apply_filters( 'woocommerce_gateway_icon', $icon, $this->id );
307
  data-description=""
308
  data-email="' . esc_attr( $user_email ) . '"
309
  data-amount="' . esc_attr( $this->get_stripe_amount( WC()->cart->total ) ) . '"
310
+ data-name="' . esc_attr( get_bloginfo( 'name', 'display' ) ) . '"
311
  data-currency="' . esc_attr( strtolower( get_woocommerce_currency() ) ) . '"
312
  data-image="' . esc_attr( $this->stripe_checkout_image ) . '"
313
  data-bitcoin="' . esc_attr( $this->bitcoin ? 'true' : 'false' ) . '"
333
  echo '</div>';
334
  }
335
 
336
+ /**
337
+ * Localize Stripe messages based on code
338
+ *
339
+ * @since 3.0.6
340
+ * @version 3.0.6
341
+ * @return array
342
+ */
343
+ public function get_localized_messages() {
344
+ return apply_filters( 'wc_stripe_localized_messages', array(
345
+ 'invalid_number' => __( 'The card number is not a valid credit card number.', 'woocommerce-gateway-stripe' ),
346
+ 'invalid_expiry_month' => __( 'The card\'s expiration month is invalid.', 'woocommerce-gateway-stripe' ),
347
+ 'invalid_expiry_year' => __( 'The card\'s expiration year is invalid.', 'woocommerce-gateway-stripe' ),
348
+ 'invalid_cvc' => __( 'The card\'s security code is invalid.', 'woocommerce-gateway-stripe' ),
349
+ 'incorrect_number' => __( 'The card number is incorrect.', 'woocommerce-gateway-stripe' ),
350
+ 'expired_card' => __( 'The card has expired.', 'woocommerce-gateway-stripe' ),
351
+ 'incorrect_cvc' => __( 'The card\'s security code is incorrect.', 'woocommerce-gateway-stripe' ),
352
+ 'incorrect_zip' => __( 'The card\'s zip code failed validation.', 'woocommerce-gateway-stripe' ),
353
+ 'card_declined' => __( 'The card was declined.', 'woocommerce-gateway-stripe' ),
354
+ 'missing' => __( 'There is no card on a customer that is being charged.', 'woocommerce-gateway-stripe' ),
355
+ 'processing_error' => __( 'An error occurred while processing the card.', 'woocommerce-gateway-stripe' ),
356
+ 'invalid_request_error' => __( 'Could not find payment information.', 'woocommerce-gateway-stripe' ),
357
+ ) );
358
+ }
359
+
360
  /**
361
  * payment_scripts function.
362
  *
382
  );
383
 
384
  // If we're on the pay page we need to pass stripe.js the address of the order.
385
+ if ( isset( $_GET['pay_for_order'] ) && 'true' === $_GET['pay_for_order'] ) {
386
+ $order_id = wc_get_order_id_by_order_key( urldecode( $_GET['key'] ) );
387
+ $order = wc_get_order( $order_id );
388
+
389
+ $stripe_params['billing_first_name'] = $order->billing_first_name;
390
+ $stripe_params['billing_last_name'] = $order->billing_last_name;
391
+ $stripe_params['billing_address_1'] = $order->billing_address_1;
392
+ $stripe_params['billing_address_2'] = $order->billing_address_2;
393
+ $stripe_params['billing_state'] = $order->billing_state;
394
+ $stripe_params['billing_city'] = $order->billing_city;
395
+ $stripe_params['billing_postcode'] = $order->billing_postcode;
396
+ $stripe_params['billing_country'] = $order->billing_country;
 
 
 
397
  }
398
 
399
  $stripe_params['no_prepaid_card_msg'] = __( 'Sorry, we\'re not accepting prepaid cards at this time.', 'woocommerce-gateway-stripe' );
400
  $stripe_params['allow_prepaid_card'] = apply_filters( 'wc_stripe_allow_prepaid_card', true ) ? 'yes' : 'no';
401
  $stripe_params['stripe_checkout_require_billing_address'] = apply_filters( 'wc_stripe_checkout_require_billing_address', false ) ? 'yes' : 'no';
402
 
403
+ // merge localized messages to be use in JS
404
+ $stripe_params = array_merge( $stripe_params, $this->get_localized_messages() );
 
 
 
 
 
 
 
 
 
 
 
405
 
406
  wp_localize_script( 'woocommerce_stripe', 'wc_stripe_params', apply_filters( 'wc_stripe_params', $stripe_params ) );
407
  }
432
  if ( $source->source ) {
433
  $post_data['source'] = $source->source;
434
  }
435
+
436
  /**
437
  * Filter the return value of the WC_Payment_Gateway_CC::generate_payment_request.
438
  *
578
  $token->delete();
579
  throw new Exception( __( 'This card is no longer available and has been removed.', 'woocommerce-gateway-stripe' ) );
580
  }
581
+ $localized_messages = $this->get_localized_messages();
582
+
583
+ throw new Exception( ( isset( $localized_messages[ $response->get_error_code() ] ) ? $localized_messages[ $response->get_error_code() ] : $response->get_error_message() ) );
584
  }
585
 
586
  // Process valid response.
592
  // Remove cart.
593
  WC()->cart->empty_cart();
594
 
595
+ do_action( 'wc_gateway_stripe_process_payment', $response, $order );
596
+
597
  // Return thank you page redirect.
598
  return array(
599
  'result' => 'success',
602
 
603
  } catch ( Exception $e ) {
604
  wc_add_notice( $e->getMessage(), 'error' );
 
605
  WC_Stripe::log( sprintf( __( 'Error: %s', 'woocommerce-gateway-stripe' ), $e->getMessage() ) );
606
 
607
  if ( $order->has_status( array( 'pending', 'failed' ) ) ) {
608
  $this->send_failed_order_email( $order_id );
609
  }
610
 
611
+ do_action( 'wc_gateway_stripe_process_payment_error', $e, $order );
612
+
613
+ return array(
614
+ 'result' => 'fail',
615
+ 'redirect' => ''
616
+ );
617
  }
618
  }
619
 
645
 
646
  // Store other data such as fees
647
  if ( isset( $response->balance_transaction ) && isset( $response->balance_transaction->fee ) ) {
648
+ // Fees and Net needs to both come from Stripe to be accurate as the returned
649
+ // values are in the local currency of the Stripe account, not from WC.
650
+ $fee = ! empty( $response->balance_transaction->fee ) ? number_format( $response->balance_transaction->fee / 100, 2, '.', '' ) : 0;
651
+ $net = ! empty( $response->balance_transaction->net ) ? number_format( $response->balance_transaction->net / 100, 2, '.', '' ) : 0;
652
  update_post_meta( $order->id, 'Stripe Fee', $fee );
653
+ update_post_meta( $order->id, 'Net Revenue From Stripe', $net );
654
  }
655
 
656
  if ( $response->captured ) {
689
  $card = $stripe_customer->add_card( wc_clean( $_POST['stripe_token'] ) );
690
 
691
  if ( is_wp_error( $card ) ) {
692
+ $localized_messages = $this->get_localized_messages();
693
+ $error_msg = __( 'There was a problem adding the card.', 'woocommerce-gateway-stripe' );
694
+
695
+ // loop through the errors to find matching localized message
696
+ foreach ( $card->errors as $error => $msg ) {
697
+ if ( isset( $localized_messages[ $error ] ) ) {
698
+ $error_msg = $localized_messages[ $error ];
699
+ }
700
+ }
701
+
702
+ wc_add_notice( $error_msg, 'error' );
703
+ return;
704
  }
705
 
706
  return array(
includes/legacy/class-wc-gateway-stripe.php CHANGED
@@ -259,7 +259,7 @@ class WC_Gateway_Stripe extends WC_Payment_Gateway {
259
  data-description=""
260
  data-email="' . esc_attr( $user_email ) . '"
261
  data-amount="' . esc_attr( $this->get_stripe_amount( WC()->cart->total ) ) . '"
262
- data-name="' . esc_attr( sprintf( __( '%s', 'woocommerce-gateway-stripe' ), get_bloginfo( 'name', 'display' ) ) ) . '"
263
  data-currency="' . esc_attr( strtolower( get_woocommerce_currency() ) ) . '"
264
  data-image="' . esc_attr( $this->stripe_checkout_image ) . '"
265
  data-bitcoin="' . esc_attr( $this->bitcoin ? 'true' : 'false' ) . '"
@@ -345,7 +345,7 @@ class WC_Gateway_Stripe extends WC_Payment_Gateway {
345
  $post_data['source'] = $source->source;
346
  }
347
 
348
- return $post_data;
349
  }
350
 
351
  /**
259
  data-description=""
260
  data-email="' . esc_attr( $user_email ) . '"
261
  data-amount="' . esc_attr( $this->get_stripe_amount( WC()->cart->total ) ) . '"
262
+ data-name="' . esc_attr( get_bloginfo( 'name', 'display' ) ) . '"
263
  data-currency="' . esc_attr( strtolower( get_woocommerce_currency() ) ) . '"
264
  data-image="' . esc_attr( $this->stripe_checkout_image ) . '"
265
  data-bitcoin="' . esc_attr( $this->bitcoin ? 'true' : 'false' ) . '"
345
  $post_data['source'] = $source->source;
346
  }
347
 
348
+ return apply_filters( 'wc_stripe_generate_payment_request', $post_data, $order, $source );
349
  }
350
 
351
  /**
readme.txt CHANGED
@@ -1,9 +1,9 @@
1
  === WooCommerce Stripe Payment Gateway ===
2
- Contributors: automattic, woothemes, mikejolley, akeda, royho, slash1andy, woosteve, spraveenitpro, mikedmoore, fernashes, shellbeezy, danieldudzic, mikaey
3
  Tags: credit card, stripe, woocommerce
4
  Requires at least: 4.4
5
  Tested up to: 4.5
6
- Stable tag: 3.0.5
7
  License: GPLv3
8
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
9
 
@@ -87,6 +87,16 @@ If you get stuck, you can ask for help in the Plugin Forum.
87
 
88
  == Changelog ==
89
 
 
 
 
 
 
 
 
 
 
 
90
  = 3.0.5 =
91
  * Fix - Previous upload of files didn't take. Retry.
92
 
@@ -119,5 +129,12 @@ If you get stuck, you can ask for help in the Plugin Forum.
119
 
120
  == Upgrade Notice ==
121
 
122
- = 3.0.5 =
123
- * Fix - Previous upload of files didn't take. Retry.
 
 
 
 
 
 
 
1
  === WooCommerce Stripe Payment Gateway ===
2
+ Contributors: automattic, woothemes, mikejolley, akeda, royho, slash1andy, woosteve, spraveenitpro, mikedmoore, fernashes, shellbeezy, danieldudzic, mikaey, dsmithweb, fullysupportedphil, corsonr
3
  Tags: credit card, stripe, woocommerce
4
  Requires at least: 4.4
5
  Tested up to: 4.5
6
+ Stable tag: 3.0.6
7
  License: GPLv3
8
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
9
 
87
 
88
  == Changelog ==
89
 
90
+ = 3.0.6 =
91
+ * Fix - When adding declined cards, fatal error is thrown.
92
+ * Fix - After a failed/declined process, valid cards are not accepted.
93
+ * Fix - When paying via pay order page/link, billing info is not sent.
94
+ * Fix - Account for all types of errors for proper localization.
95
+ * Fix - Correctly reference Stripe fees/net based on Stripe account locale.
96
+ * Fix - Bitcoin image not showing.
97
+ * New - Introduce "wc_gateway_stripe_process_payment_error" action hook.
98
+ * New - Introduce "wc_gateway_stripe_process_payment" action hook.
99
+
100
  = 3.0.5 =
101
  * Fix - Previous upload of files didn't take. Retry.
102
 
129
 
130
  == Upgrade Notice ==
131
 
132
+ = 3.0.6 =
133
+ * Fix - When adding declined cards, fatal error is thrown.
134
+ * Fix - After a failed/declined process, valid cards are not accepted.
135
+ * Fix - When paying via pay order page/link, billing info is not sent.
136
+ * Fix - Account for all types of errors for proper localization.
137
+ * Fix - Correctly reference Stripe fees/net based on Stripe account locale.
138
+ * Fix - Bitcoin image not showing.
139
+ * New - Introduce "wc_gateway_stripe_process_payment_error" action hook.
140
+ * New - Introduce "wc_gateway_stripe_process_payment" action hook.
woocommerce-gateway-stripe.php CHANGED
@@ -5,7 +5,7 @@
5
  * Description: Take credit card payments on your store using Stripe.
6
  * Author: Automattic
7
  * Author URI: https://woocommerce.com/
8
- * Version: 3.0.5
9
  * Text Domain: woocommerce-gateway-stripe
10
  * Domain Path: /languages
11
  *
@@ -32,13 +32,13 @@ if ( ! defined( 'ABSPATH' ) ) {
32
  /**
33
  * Required minimums and constants
34
  */
35
- define( 'WC_STRIPE_VERSION', '3.0.5' );
36
  define( 'WC_STRIPE_MIN_PHP_VER', '5.3.0' );
37
  define( 'WC_STRIPE_MIN_WC_VER', '2.5.0' );
38
  define( 'WC_STRIPE_MAIN_FILE', __FILE__ );
39
  define( 'WC_STRIPE_PLUGIN_URL', untrailingslashit( plugins_url( basename( plugin_dir_path( __FILE__ ) ), basename( __FILE__ ) ) ) );
40
 
41
- if ( ! class_exists( 'WC_Stripe' ) ) {
42
 
43
  class WC_Stripe {
44
 
@@ -121,8 +121,8 @@ class WC_Stripe {
121
  return;
122
  }
123
 
124
- include_once( plugin_basename( 'includes/class-wc-stripe-api.php' ) );
125
- include_once( plugin_basename( 'includes/class-wc-stripe-customer.php' ) );
126
 
127
  // Init the gateway itself
128
  $this->init_gateways();
@@ -161,7 +161,7 @@ class WC_Stripe {
161
  // Check if secret key present. Otherwise prompt, via notice, to go to
162
  // setting.
163
  if ( ! class_exists( 'WC_Stripe_API' ) ) {
164
- include_once( plugin_basename( 'includes/class-wc-stripe-api.php' ) );
165
  }
166
 
167
  $secret = WC_Stripe_API::get_secret_key();
@@ -261,10 +261,10 @@ class WC_Stripe {
261
  }
262
 
263
  if ( class_exists( 'WC_Payment_Gateway_CC' ) ) {
264
- include_once( plugin_basename( 'includes/class-wc-gateway-stripe.php' ) );
265
  } else {
266
- include_once( plugin_basename( 'includes/legacy/class-wc-gateway-stripe.php' ) );
267
- include_once( plugin_basename( 'includes/legacy/class-wc-gateway-stripe-saved-cards.php' ) );
268
  }
269
 
270
  load_plugin_textdomain( 'woocommerce-gateway-stripe', false, plugin_basename( dirname( __FILE__ ) ) . '/languages' );
@@ -277,7 +277,7 @@ class WC_Stripe {
277
  );
278
 
279
  if ( $load_addons ) {
280
- require_once( plugin_basename( 'includes/class-wc-gateway-stripe-addons.php' ) );
281
  }
282
  }
283
 
@@ -323,8 +323,12 @@ class WC_Stripe {
323
  update_post_meta( $order->id, 'Stripe Payment ID', $result->id );
324
 
325
  if ( isset( $result->balance_transaction ) && isset( $result->balance_transaction->fee ) ) {
326
- update_post_meta( $order->id, 'Stripe Fee', number_format( $result->balance_transaction->fee / 100, 2, '.', '' ) );
327
- update_post_meta( $order->id, 'Net Revenue From Stripe', ( $order->order_total - number_format( $result->balance_transaction->fee / 100, 2, '.', '' ) ) );
 
 
 
 
328
  }
329
  }
330
  }
@@ -435,4 +439,4 @@ class WC_Stripe {
435
 
436
  $GLOBALS['wc_stripe'] = WC_Stripe::get_instance();
437
 
438
- }
5
  * Description: Take credit card payments on your store using Stripe.
6
  * Author: Automattic
7
  * Author URI: https://woocommerce.com/
8
+ * Version: 3.0.6
9
  * Text Domain: woocommerce-gateway-stripe
10
  * Domain Path: /languages
11
  *
32
  /**
33
  * Required minimums and constants
34
  */
35
+ define( 'WC_STRIPE_VERSION', '3.0.6' );
36
  define( 'WC_STRIPE_MIN_PHP_VER', '5.3.0' );
37
  define( 'WC_STRIPE_MIN_WC_VER', '2.5.0' );
38
  define( 'WC_STRIPE_MAIN_FILE', __FILE__ );
39
  define( 'WC_STRIPE_PLUGIN_URL', untrailingslashit( plugins_url( basename( plugin_dir_path( __FILE__ ) ), basename( __FILE__ ) ) ) );
40
 
41
+ if ( ! class_exists( 'WC_Stripe' ) ) :
42
 
43
  class WC_Stripe {
44
 
121
  return;
122
  }
123
 
124
+ include_once( dirname( __FILE__ ) . '/includes/class-wc-stripe-api.php' );
125
+ include_once( dirname( __FILE__ ) . '/includes/class-wc-stripe-customer.php' );
126
 
127
  // Init the gateway itself
128
  $this->init_gateways();
161
  // Check if secret key present. Otherwise prompt, via notice, to go to
162
  // setting.
163
  if ( ! class_exists( 'WC_Stripe_API' ) ) {
164
+ include_once( dirname( __FILE__ ) . '/includes/class-wc-stripe-api.php' );
165
  }
166
 
167
  $secret = WC_Stripe_API::get_secret_key();
261
  }
262
 
263
  if ( class_exists( 'WC_Payment_Gateway_CC' ) ) {
264
+ include_once( dirname( __FILE__ ) . '/includes/class-wc-gateway-stripe.php' );
265
  } else {
266
+ include_once( dirname( __FILE__ ) . '/includes/legacy/class-wc-gateway-stripe.php' );
267
+ include_once( dirname( __FILE__ ) . '/includes/legacy/class-wc-gateway-stripe-saved-cards.php' );
268
  }
269
 
270
  load_plugin_textdomain( 'woocommerce-gateway-stripe', false, plugin_basename( dirname( __FILE__ ) ) . '/languages' );
277
  );
278
 
279
  if ( $load_addons ) {
280
+ require_once( dirname( __FILE__ ) . '/includes/class-wc-gateway-stripe-addons.php' );
281
  }
282
  }
283
 
323
  update_post_meta( $order->id, 'Stripe Payment ID', $result->id );
324
 
325
  if ( isset( $result->balance_transaction ) && isset( $result->balance_transaction->fee ) ) {
326
+ // Fees and Net needs to both come from Stripe to be accurate as the returned
327
+ // values are in the local currency of the Stripe account, not from WC.
328
+ $fee = ! empty( $result->balance_transaction->fee ) ? number_format( $result->balance_transaction->fee / 100, 2, '.', '' ) : 0;
329
+ $net = ! empty( $result->balance_transaction->net ) ? number_format( $result->balance_transaction->net / 100, 2, '.', '' ) : 0;
330
+ update_post_meta( $order->id, 'Stripe Fee', $fee );
331
+ update_post_meta( $order->id, 'Net Revenue From Stripe', $net );
332
  }
333
  }
334
  }
439
 
440
  $GLOBALS['wc_stripe'] = WC_Stripe::get_instance();
441
 
442
+ endif;