WooCommerce Stripe Payment Gateway - Version 5.0.0

Version Description

  • 2021-03-17 =

  • Add - Display time of last Stripe webhook in settings.

  • Add - wc_stripe_webhook_validate_user_agent filter to customize webhook user-agent validation.

  • Fix - Payment Request Buttons for Chinese provinces in Chrome.

  • Fix - Enable wc_stripe_send_stripe_receipt filter to send Stripe emails.

  • Fix - Check for more errors when attaching sources to customers.

See changelog for all versions.

Download this release

Release Info

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

Code changes from version 4.9.0 to 5.0.0

Files changed (57) hide show
  1. changelog.txt +7 -0
  2. includes/abstracts/abstract-wc-stripe-connect-rest-controller.php +21 -19
  3. includes/abstracts/abstract-wc-stripe-payment-gateway.php +139 -116
  4. includes/admin/class-wc-stripe-admin-notices.php +21 -11
  5. includes/admin/class-wc-stripe-inbox-notes.php +7 -7
  6. includes/admin/class-wc-stripe-privacy.php +75 -78
  7. includes/admin/stripe-alipay-settings.php +16 -16
  8. includes/admin/stripe-bancontact-settings.php +16 -16
  9. includes/admin/stripe-eps-settings.php +14 -14
  10. includes/admin/stripe-giropay-settings.php +16 -16
  11. includes/admin/stripe-ideal-settings.php +16 -16
  12. includes/admin/stripe-multibanco-settings.php +14 -14
  13. includes/admin/stripe-p24-settings.php +14 -14
  14. includes/admin/stripe-sepa-settings.php +16 -16
  15. includes/admin/stripe-settings.php +67 -67
  16. includes/admin/stripe-sofort-settings.php +16 -16
  17. includes/class-wc-gateway-stripe.php +74 -67
  18. includes/class-wc-stripe-api.php +22 -19
  19. includes/class-wc-stripe-apple-pay-registration.php +23 -23
  20. includes/class-wc-stripe-customer.php +39 -25
  21. includes/class-wc-stripe-exception.php +4 -1
  22. includes/class-wc-stripe-helper.php +15 -15
  23. includes/class-wc-stripe-intent-controller.php +11 -8
  24. includes/class-wc-stripe-logger.php +1 -1
  25. includes/class-wc-stripe-order-handler.php +29 -28
  26. includes/class-wc-stripe-payment-tokens.php +8 -8
  27. includes/class-wc-stripe-sepa-payment-token.php +10 -3
  28. includes/class-wc-stripe-webhook-handler.php +79 -48
  29. includes/class-wc-stripe-webhook-state.php +248 -0
  30. includes/compat/class-wc-stripe-email-failed-authentication-retry.php +5 -5
  31. includes/compat/class-wc-stripe-email-failed-authentication.php +8 -8
  32. includes/compat/class-wc-stripe-email-failed-preorder-authentication.php +5 -5
  33. includes/compat/class-wc-stripe-email-failed-renewal-authentication.php +6 -6
  34. includes/compat/class-wc-stripe-pre-orders-compat.php +14 -11
  35. includes/compat/class-wc-stripe-sepa-subs-compat.php +46 -42
  36. includes/compat/class-wc-stripe-subs-compat.php +71 -62
  37. includes/connect/class-wc-stripe-connect-api.php +15 -15
  38. includes/connect/class-wc-stripe-connect-rest-oauth-connect-controller.php +3 -3
  39. includes/connect/class-wc-stripe-connect-rest-oauth-init-controller.php +3 -3
  40. includes/connect/class-wc-stripe-connect.php +11 -11
  41. includes/payment-methods/class-wc-gateway-stripe-alipay.php +16 -15
  42. includes/payment-methods/class-wc-gateway-stripe-bancontact.php +17 -20
  43. includes/payment-methods/class-wc-gateway-stripe-eps.php +16 -19
  44. includes/payment-methods/class-wc-gateway-stripe-giropay.php +16 -19
  45. includes/payment-methods/class-wc-gateway-stripe-ideal.php +16 -19
  46. includes/payment-methods/class-wc-gateway-stripe-multibanco.php +22 -25
  47. includes/payment-methods/class-wc-gateway-stripe-p24.php +16 -19
  48. includes/payment-methods/class-wc-gateway-stripe-sepa.php +15 -18
  49. includes/payment-methods/class-wc-gateway-stripe-sofort.php +18 -21
  50. includes/payment-methods/class-wc-stripe-payment-request.php +180 -146
  51. languages/woocommerce-gateway-stripe.pot +333 -223
  52. readme.txt +7 -9
  53. templates/emails/failed-preorder-authentication.php +5 -3
  54. templates/emails/failed-renewal-authentication.php +2 -1
  55. templates/emails/plain/failed-preorder-authentication.php +1 -1
  56. uninstall.php +2 -2
  57. woocommerce-gateway-stripe.php +21 -21
changelog.txt CHANGED
@@ -1,4 +1,11 @@
1
  *** Changelog ***
 
 
 
 
 
 
 
2
  = 4.9.0 - 2021-02-24 =
3
  * Fix - Add fees as line items sent to Stripe to prevent Level 3 errors.
4
  * Fix - Adding a SEPA payment method doesn't work.
1
  *** Changelog ***
2
+ = 5.0.0 - 2021-03-17 =
3
+ * Add - Display time of last Stripe webhook in settings.
4
+ * Add - wc_stripe_webhook_validate_user_agent filter to customize webhook user-agent validation.
5
+ * Fix - Payment Request Buttons for Chinese provinces in Chrome.
6
+ * Fix - Enable wc_stripe_send_stripe_receipt filter to send Stripe emails.
7
+ * Fix - Check for more errors when attaching sources to customers.
8
+
9
  = 4.9.0 - 2021-02-24 =
10
  * Fix - Add fees as line items sent to Stripe to prevent Level 3 errors.
11
  * Fix - Adding a SEPA payment method doesn't work.
includes/abstracts/abstract-wc-stripe-connect-rest-controller.php CHANGED
@@ -4,6 +4,8 @@ if ( ! defined( 'ABSPATH' ) ) {
4
  exit;
5
  }
6
 
 
 
7
  /**
8
  * Stripe Connect base REST controller class.
9
  */
@@ -42,13 +44,13 @@ abstract class WC_Stripe_Connect_REST_Controller extends WP_REST_Controller {
42
  register_rest_route(
43
  $this->namespace,
44
  '/' . $this->rest_base,
45
- array(
46
- array(
47
  'methods' => 'GET',
48
- 'callback' => array( $this, 'get_internal' ),
49
- 'permission_callback' => array( $this, 'check_permission' ),
50
- ),
51
- )
52
  );
53
  }
54
 
@@ -56,13 +58,13 @@ abstract class WC_Stripe_Connect_REST_Controller extends WP_REST_Controller {
56
  register_rest_route(
57
  $this->namespace,
58
  '/' . $this->rest_base,
59
- array(
60
- array(
61
  'methods' => 'POST',
62
- 'callback' => array( $this, 'post_internal' ),
63
- 'permission_callback' => array( $this, 'check_permission' ),
64
- ),
65
- )
66
  );
67
  }
68
 
@@ -70,13 +72,13 @@ abstract class WC_Stripe_Connect_REST_Controller extends WP_REST_Controller {
70
  register_rest_route(
71
  $this->namespace,
72
  '/' . $this->rest_base,
73
- array(
74
- array(
75
  'methods' => 'DELETE',
76
- 'callback' => array( $this, 'delete_internal' ),
77
- 'permission_callback' => array( $this, 'check_permission' ),
78
- ),
79
- )
80
  );
81
  }
82
  }
@@ -145,7 +147,7 @@ abstract class WC_Stripe_Connect_REST_Controller extends WP_REST_Controller {
145
  }
146
 
147
  // Prevent our REST API endpoint responses from being added to browser cache.
148
- add_filter( 'rest_post_dispatch', array( $this, 'send_nocache_header' ), PHP_INT_MAX, 2 );
149
  }
150
 
151
  /**
4
  exit;
5
  }
6
 
7
+ // phpcs:disable WordPress.Files.FileName
8
+
9
  /**
10
  * Stripe Connect base REST controller class.
11
  */
44
  register_rest_route(
45
  $this->namespace,
46
  '/' . $this->rest_base,
47
+ [
48
+ [
49
  'methods' => 'GET',
50
+ 'callback' => [ $this, 'get_internal' ],
51
+ 'permission_callback' => [ $this, 'check_permission' ],
52
+ ],
53
+ ]
54
  );
55
  }
56
 
58
  register_rest_route(
59
  $this->namespace,
60
  '/' . $this->rest_base,
61
+ [
62
+ [
63
  'methods' => 'POST',
64
+ 'callback' => [ $this, 'post_internal' ],
65
+ 'permission_callback' => [ $this, 'check_permission' ],
66
+ ],
67
+ ]
68
  );
69
  }
70
 
72
  register_rest_route(
73
  $this->namespace,
74
  '/' . $this->rest_base,
75
+ [
76
+ [
77
  'methods' => 'DELETE',
78
+ 'callback' => [ $this, 'delete_internal' ],
79
+ 'permission_callback' => [ $this, 'check_permission' ],
80
+ ],
81
+ ]
82
  );
83
  }
84
  }
147
  }
148
 
149
  // Prevent our REST API endpoint responses from being added to browser cache.
150
+ add_filter( 'rest_post_dispatch', [ $this, 'send_nocache_header' ], PHP_INT_MAX, 2 );
151
  }
152
 
153
  /**
includes/abstracts/abstract-wc-stripe-payment-gateway.php CHANGED
@@ -17,11 +17,16 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
17
  * Displays the admin settings webhook description.
18
  *
19
  * @since 4.1.0
 
20
  * @return mixed
21
  */
22
  public function display_admin_settings_webhook_description() {
23
  /* translators: 1) webhook url */
24
- return sprintf( __( 'You must add the following webhook endpoint <strong style="background-color:#ddd;">&nbsp;%s&nbsp;</strong> to your <a href="https://dashboard.stripe.com/account/webhooks" target="_blank">Stripe account settings</a>. This will enable you to receive notifications on the charge statuses.', 'woocommerce-gateway-stripe' ), WC_Stripe_Helper::get_webhook_url() );
 
 
 
 
25
  }
26
 
27
  /**
@@ -166,7 +171,7 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
166
  && preg_match( '/^[rs]k_test_/', $this->secret_key );
167
  } else {
168
  return preg_match( '/^pk_live_/', $this->publishable_key )
169
- && preg_match( '/^[rs]k_live_/', $this->secret_key );
170
  }
171
  }
172
 
@@ -211,7 +216,7 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
211
  public function payment_icons() {
212
  return apply_filters(
213
  'wc_stripe_payment_icons',
214
- array(
215
  'visa' => '<img src="' . WC_STRIPE_PLUGIN_URL . '/assets/images/visa.svg" class="stripe-visa-icon stripe-icon" alt="Visa" />',
216
  'amex' => '<img src="' . WC_STRIPE_PLUGIN_URL . '/assets/images/amex.svg" class="stripe-amex-icon stripe-icon" alt="American Express" />',
217
  'mastercard' => '<img src="' . WC_STRIPE_PLUGIN_URL . '/assets/images/mastercard.svg" class="stripe-mastercard-icon stripe-icon" alt="Mastercard" />',
@@ -228,7 +233,7 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
228
  'multibanco' => '<img src="' . WC_STRIPE_PLUGIN_URL . '/assets/images/multibanco.svg" class="stripe-multibanco-icon stripe-icon" alt="Multibanco" />',
229
  'sofort' => '<img src="' . WC_STRIPE_PLUGIN_URL . '/assets/images/sofort.svg" class="stripe-sofort-icon stripe-icon" alt="SOFORT" />',
230
  'sepa' => '<img src="' . WC_STRIPE_PLUGIN_URL . '/assets/images/sepa.svg" class="stripe-sepa-icon stripe-icon" alt="SEPA" />',
231
- )
232
  );
233
  }
234
 
@@ -288,7 +293,7 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
288
  * @since 4.0.0
289
  * @version 4.0.0
290
  * @param object $order
291
- * @param int $id Stripe session id.
292
  */
293
  public function get_stripe_return_url( $order = null, $id = null ) {
294
  if ( is_object( $order ) ) {
@@ -298,20 +303,21 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
298
 
299
  $order_id = $order->get_id();
300
 
301
- $args = array(
302
  'utm_nooverride' => '1',
303
  'order_id' => $order_id,
304
- );
305
 
306
  return wp_sanitize_redirect( esc_url_raw( add_query_arg( $args, $this->get_return_url( $order ) ) ) );
307
  }
308
 
309
- return wp_sanitize_redirect( esc_url_raw( add_query_arg( array( 'utm_nooverride' => '1' ), $this->get_return_url() ) ) );
310
  }
311
 
312
  /**
313
  * Is $order_id a subscription?
314
- * @param int $order_id
 
315
  * @return boolean
316
  */
317
  public function has_subscription( $order_id ) {
@@ -324,14 +330,14 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
324
  * @since 3.1.0
325
  * @version 4.5.4
326
  * @param WC_Order $order
327
- * @param object $prepared_source
328
  * @return array()
329
  */
330
  public function generate_payment_request( $order, $prepared_source ) {
331
- $settings = get_option( 'woocommerce_stripe_settings', array() );
332
  $statement_descriptor = ! empty( $settings['statement_descriptor'] ) ? str_replace( "'", '', $settings['statement_descriptor'] ) : '';
333
  $capture = ! empty( $settings['capture'] ) && 'yes' === $settings['capture'] ? true : false;
334
- $post_data = array();
335
  $post_data['currency'] = strtolower( $order->get_currency() );
336
  $post_data['amount'] = WC_Stripe_Helper::get_stripe_amount( $order->get_total(), $post_data['currency'] );
337
  /* translators: 1) blog name 2) order number */
@@ -360,32 +366,32 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
360
  }
361
 
362
  if ( method_exists( $order, 'get_shipping_postcode' ) && ! empty( $order->get_shipping_postcode() ) ) {
363
- $post_data['shipping'] = array(
364
  'name' => trim( $order->get_shipping_first_name() . ' ' . $order->get_shipping_last_name() ),
365
- 'address' => array(
366
  'line1' => $order->get_shipping_address_1(),
367
  'line2' => $order->get_shipping_address_2(),
368
  'city' => $order->get_shipping_city(),
369
  'country' => $order->get_shipping_country(),
370
  'postal_code' => $order->get_shipping_postcode(),
371
  'state' => $order->get_shipping_state(),
372
- )
373
- );
374
  }
375
 
376
  $post_data['expand[]'] = 'balance_transaction';
377
 
378
- $metadata = array(
379
  __( 'customer_name', 'woocommerce-gateway-stripe' ) => sanitize_text_field( $billing_first_name ) . ' ' . sanitize_text_field( $billing_last_name ),
380
  __( 'customer_email', 'woocommerce-gateway-stripe' ) => sanitize_email( $billing_email ),
381
  'order_id' => $order->get_order_number(),
382
  'site_url' => esc_url( get_site_url() ),
383
- );
384
 
385
  if ( $this->has_subscription( $order->get_id() ) ) {
386
- $metadata += array(
387
  'payment_type' => 'recurring',
388
- );
389
  }
390
 
391
  $post_data['metadata'] = apply_filters( 'wc_stripe_payment_metadata', $metadata, $order, $prepared_source );
@@ -459,7 +465,7 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
459
  } else {
460
  $order->set_transaction_id( $response->id );
461
 
462
- if ( $order->has_status( array( 'pending', 'failed' ) ) ) {
463
  wc_reduce_stock_levels( $order_id );
464
  }
465
 
@@ -467,7 +473,7 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
467
  $order->update_status( 'on-hold', sprintf( __( 'Stripe charge authorized (Charge ID: %s). Process order to take payment, or cancel to remove the pre-authorization. Attempting to refund the order in part or in full will release the authorization and cancel the payment.', 'woocommerce-gateway-stripe' ), $response->id ) );
468
  }
469
 
470
- if ( is_callable( array( $order, 'save' ) ) ) {
471
  $order->save();
472
  }
473
 
@@ -503,7 +509,7 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
503
  $billing_first_name = $order->get_billing_first_name();
504
  $billing_last_name = $order->get_billing_last_name();
505
 
506
- $details = array();
507
 
508
  $name = $billing_first_name . ' ' . $billing_last_name;
509
  $email = $order->get_billing_email();
@@ -584,7 +590,7 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
584
  * @return bool
585
  */
586
  public function is_using_saved_payment_method() {
587
- $payment_method = isset( $_POST['payment_method'] ) ? wc_clean( $_POST['payment_method'] ) : 'stripe';
588
 
589
  return ( isset( $_POST[ 'wc-' . $payment_method . '-payment-token' ] ) && 'new' !== $_POST[ 'wc-' . $payment_method . '-payment-token' ] );
590
  }
@@ -597,7 +603,7 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
597
  * @since 3.1.0
598
  * @version 4.0.0
599
  * @param string $user_id
600
- * @param bool $force_save_source Should we force save payment source.
601
  *
602
  * @throws Exception When card was not added or for and invalid card.
603
  * @return object
@@ -612,12 +618,12 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
612
  $source_object = '';
613
  $source_id = '';
614
  $wc_token_id = false;
615
- $payment_method = isset( $_POST['payment_method'] ) ? wc_clean( $_POST['payment_method'] ) : 'stripe';
616
  $is_token = false;
617
 
618
  // New CC info was entered and we have a new source to process.
619
  if ( ! empty( $_POST['stripe_source'] ) ) {
620
- $source_object = self::get_source_object( wc_clean( $_POST['stripe_source'] ) );
621
  $source_id = $source_object->id;
622
 
623
  // This checks to see if customer opted to save the payment method to file.
@@ -634,10 +640,13 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
634
  if ( ! empty( $response->error ) ) {
635
  throw new WC_Stripe_Exception( print_r( $response, true ), $this->get_localized_error_message_from_response( $response ) );
636
  }
 
 
 
637
  }
638
  } elseif ( $this->is_using_saved_payment_method() ) {
639
  // Use an existing token, and then process the payment.
640
- $wc_token_id = wc_clean( $_POST[ 'wc-' . $payment_method . '-payment-token' ] );
641
  $wc_token = WC_Payment_Tokens::get( $wc_token_id );
642
 
643
  if ( ! $wc_token || $wc_token->get_user_id() !== get_current_user_id() ) {
@@ -651,7 +660,7 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
651
  $is_token = true;
652
  }
653
  } elseif ( isset( $_POST['stripe_token'] ) && 'new' !== $_POST['stripe_token'] ) {
654
- $stripe_token = wc_clean( $_POST['stripe_token'] );
655
  $maybe_saved_card = isset( $_POST[ 'wc-' . $payment_method . '-new-payment-method' ] ) && ! empty( $_POST[ 'wc-' . $payment_method . '-new-payment-method' ] );
656
 
657
  // This is true if the user wants to store the card to their account.
@@ -661,10 +670,13 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
661
  if ( ! empty( $response->error ) ) {
662
  throw new WC_Stripe_Exception( print_r( $response, true ), $response->error->message );
663
  }
664
- $source_id = $response;
 
 
 
665
  } else {
666
- $source_id = $stripe_token;
667
- $is_token = true;
668
  }
669
  }
670
 
@@ -680,12 +692,12 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
680
  $source_object = self::get_source_object( $source_id );
681
  }
682
 
683
- return (object) array(
684
  'token_id' => $wc_token_id,
685
  'customer' => $customer_id,
686
  'source' => $source_id,
687
  'source_object' => $source_object,
688
- );
689
  }
690
 
691
  /**
@@ -725,7 +737,7 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
725
  // Take this opportunity to update the key name.
726
  $order->update_meta_data( '_stripe_source_id', $source_id );
727
 
728
- if ( is_callable( array( $order, 'save' ) ) ) {
729
  $order->save();
730
  }
731
  }
@@ -742,12 +754,12 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
742
  }
743
  }
744
 
745
- return (object) array(
746
  'token_id' => $token_id,
747
  'customer' => $stripe_customer ? $stripe_customer->get_id() : false,
748
  'source' => $stripe_source,
749
  'source_object' => $source_object,
750
- );
751
  }
752
 
753
  /**
@@ -768,7 +780,7 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
768
  $order->update_meta_data( '_stripe_source_id', $source->source );
769
  }
770
 
771
- if ( is_callable( array( $order, 'save' ) ) ) {
772
  $order->save();
773
  }
774
  }
@@ -780,7 +792,7 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
780
  * @since 4.0.0
781
  * @version 4.0.6
782
  * @param object $order The order object
783
- * @param int $balance_transaction_id
784
  */
785
  public function update_fees( $order, $balance_transaction_id ) {
786
  $balance_transaction = WC_Stripe_API::retrieve( 'balance/history/' . $balance_transaction_id );
@@ -806,7 +818,7 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
806
  $currency = ! empty( $balance_transaction->currency ) ? strtoupper( $balance_transaction->currency ) : null;
807
  WC_Stripe_Helper::update_stripe_currency( $order, $currency );
808
 
809
- if ( is_callable( array( $order, 'save' ) ) ) {
810
  $order->save();
811
  }
812
  }
@@ -833,7 +845,7 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
833
  return false;
834
  }
835
 
836
- $request = array();
837
 
838
  $order_currency = $order->get_currency();
839
  $captured = $order->get_meta( '_stripe_charge_captured', true );
@@ -860,9 +872,9 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
860
  $reason = $reason . '... [See WooCommerce order page for full text.]';
861
  }
862
 
863
- $request['metadata'] = array(
864
  'reason' => $reason,
865
- );
866
  }
867
 
868
  $request['charge'] = $charge_id;
@@ -870,16 +882,16 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
870
 
871
  $request = apply_filters( 'wc_stripe_refund_request', $request, $order );
872
 
873
- $intent = $this->get_intent_from_order( $order );
874
  $intent_cancelled = false;
875
  if ( $intent ) {
876
  // If the order has a Payment Intent pending capture, then the Intent itself must be refunded (cancelled), not the Charge.
877
  if ( ! empty( $intent->error ) ) {
878
- $response = $intent;
879
  $intent_cancelled = true;
880
  } elseif ( 'requires_capture' === $intent->status ) {
881
- $result = WC_Stripe_API::request(
882
- array(),
883
  'payment_intents/' . $intent->id . '/cancel'
884
  );
885
  $intent_cancelled = true;
@@ -887,7 +899,7 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
887
  if ( ! empty( $result->error ) ) {
888
  $response = $result;
889
  } else {
890
- $charge = end( $result->charges->data );
891
  $response = end( $charge->refunds->data );
892
  }
893
  }
@@ -957,7 +969,7 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
957
 
958
  $stripe_customer = new WC_Stripe_Customer( get_current_user_id() );
959
 
960
- $source = ! empty( $_POST['stripe_source'] ) ? wc_clean( $_POST['stripe_source'] ) : '';
961
 
962
  $source_object = WC_Stripe_API::retrieve( 'sources/' . $source );
963
 
@@ -968,7 +980,7 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
968
 
969
  $source_id = $source_object->id;
970
  } elseif ( isset( $_POST['stripe_token'] ) ) {
971
- $source_id = wc_clean( $_POST['stripe_token'] );
972
  }
973
 
974
  $response = $stripe_customer->add_source( $source_id );
@@ -983,12 +995,12 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
983
  return;
984
  }
985
 
986
- do_action( 'wc_stripe_add_payment_method_' . $_POST['payment_method'] . '_success', $source_id, $source_object );
987
 
988
- return array(
989
  'result' => 'success',
990
  'redirect' => wc_get_endpoint_url( 'payment-methods' ),
991
- );
992
  }
993
 
994
  /**
@@ -1019,7 +1031,7 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
1019
  *
1020
  * @since 4.0.6
1021
  * @param string $idempotency_key
1022
- * @param array $request
1023
  */
1024
  public function change_idempotency_key( $idempotency_key, $request ) {
1025
  $customer = ! empty( $request['customer'] ) ? $request['customer'] : '';
@@ -1056,17 +1068,17 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
1056
  // The request for a charge contains metadata for the intent.
1057
  $full_request = $this->generate_payment_request( $order, $prepared_source );
1058
 
1059
- $request = array(
1060
  'source' => $prepared_source->source,
1061
  'amount' => WC_Stripe_Helper::get_stripe_amount( $order->get_total() ),
1062
  'currency' => strtolower( $order->get_currency() ),
1063
  'description' => $full_request['description'],
1064
  'metadata' => $full_request['metadata'],
1065
  'capture_method' => ( 'true' === $full_request['capture'] ) ? 'automatic' : 'manual',
1066
- 'payment_method_types' => array(
1067
  'card',
1068
- ),
1069
- );
1070
 
1071
  if ( $prepared_source->customer ) {
1072
  $request['customer'] = $prepared_source->customer;
@@ -1080,6 +1092,10 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
1080
  $request['shipping'] = $full_request['shipping'];
1081
  }
1082
 
 
 
 
 
1083
  /**
1084
  * Filter the return value of the WC_Payment_Gateway_CC::generate_create_intent_request.
1085
  *
@@ -1103,38 +1119,41 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
1103
  $order_items = array_values( $order->get_items( [ 'line_item', 'fee' ] ) );
1104
  $currency = $order->get_currency();
1105
 
1106
- $stripe_line_items = array_map( function( $item ) use ( $currency ) {
1107
- if ( is_a( $item, 'WC_Order_Item_Product' ) ) {
1108
- $product_id = $item->get_variation_id()
1109
- ? $item->get_variation_id()
1110
- : $item->get_product_id();
1111
- $subtotal = $item->get_subtotal();
1112
- } else {
1113
- $product_id = substr( sanitize_title( $item->get_name() ), 0, 12 );
1114
- $subtotal = $item->get_total();
1115
- }
1116
- $product_description = substr( $item->get_name(), 0, 26 );
1117
- $quantity = $item->get_quantity();
1118
- $unit_cost = WC_Stripe_Helper::get_stripe_amount( ( $subtotal / $quantity ), $currency );
1119
- $tax_amount = WC_Stripe_Helper::get_stripe_amount( $item->get_total_tax(), $currency );
1120
- $discount_amount = WC_Stripe_Helper::get_stripe_amount( $subtotal - $item->get_total(), $currency );
1121
-
1122
- return (object) array(
1123
- 'product_code' => (string) $product_id, // Up to 12 characters that uniquely identify the product.
1124
- 'product_description' => $product_description, // Up to 26 characters long describing the product.
1125
- 'unit_cost' => $unit_cost, // Cost of the product, in cents, as a non-negative integer.
1126
- 'quantity' => $quantity, // The number of items of this type sold, as a non-negative integer.
1127
- 'tax_amount' => $tax_amount, // The amount of tax this item had added to it, in cents, as a non-negative integer.
1128
- 'discount_amount' => $discount_amount, // The amount an item was discounted—if there was a sale,for example, as a non-negative integer.
1129
- );
1130
- }, $order_items);
1131
-
1132
- $level3_data = array(
1133
- 'merchant_reference' => $order->get_id(), // An alphanumeric string of up to characters in length. This unique value is assigned by the merchant to identify the order. Also known as an “Order ID”.
1134
- 'shipping_amount' => WC_Stripe_Helper::get_stripe_amount( (float) $order->get_shipping_total() + (float) $order->get_shipping_tax(), $currency), // The shipping cost, in cents, as a non-negative integer.
1135
- 'line_items' => $stripe_line_items,
1136
  );
1137
 
 
 
 
 
 
 
1138
  // The customer’s U.S. shipping ZIP code.
1139
  $shipping_address_zip = $order->get_shipping_postcode();
1140
  if ( $this->is_valid_us_zip_code( $shipping_address_zip ) ) {
@@ -1184,7 +1203,7 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
1184
  * @return object An updated intent.
1185
  */
1186
  public function update_existing_intent( $intent, $order, $prepared_source ) {
1187
- $request = array();
1188
 
1189
  if ( $prepared_source->source !== $intent->source ) {
1190
  $request['source'] = $prepared_source->source;
@@ -1233,11 +1252,11 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
1233
  }
1234
 
1235
  // Try to confirm the intent & capture the charge (if 3DS is not required).
1236
- $confirm_request = array(
1237
  'source' => $prepared_source->source,
1238
- );
1239
 
1240
- $level3_data = $this->get_level3_data_from_order( $order );
1241
  $confirmed_intent = WC_Stripe_API::request_with_level3_data(
1242
  $confirm_request,
1243
  "payment_intents/$intent->id/confirm",
@@ -1270,7 +1289,7 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
1270
  public function save_intent_to_order( $order, $intent ) {
1271
  $order->update_meta_data( '_stripe_intent_id', $intent->id );
1272
 
1273
- if ( is_callable( array( $order, 'save' ) ) ) {
1274
  $order->save();
1275
  }
1276
  }
@@ -1302,22 +1321,22 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
1302
  /**
1303
  * Retrieves intent from Stripe API by intent id.
1304
  *
1305
- * @param string $intent_type Either 'payment_intents' or 'setup_intents'.
1306
- * @param string $intent_id Intent id.
1307
- * @return object|bool Either the intent object or `false`.
1308
- * @throws Exception Throws exception for unknown $intent_type.
1309
  */
1310
  private function get_intent( $intent_type, $intent_id ) {
1311
  if ( ! in_array( $intent_type, [ 'payment_intents', 'setup_intents' ] ) ) {
1312
  throw new Exception( "Failed to get intent of type $intent_type. Type is not allowed" );
1313
  }
1314
 
1315
- $response = WC_Stripe_API::request( array(), "$intent_type/$intent_id", 'GET' );
1316
 
1317
  if ( $response && isset( $response->{ 'error' } ) ) {
1318
  $error_response_message = print_r( $response, true );
1319
- WC_Stripe_Logger::log("Failed to get Stripe intent $intent_type/$intent_id.");
1320
- WC_Stripe_Logger::log("Response: $error_response_message");
1321
  return false;
1322
  }
1323
 
@@ -1338,7 +1357,7 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
1338
  $processing = get_transient( $transient_name );
1339
 
1340
  // Block the process if the same intent is already being handled.
1341
- if ( "-1" === $processing || ( isset( $intent->id ) && $processing === $intent->id ) ) {
1342
  return true;
1343
  }
1344
 
@@ -1380,11 +1399,14 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
1380
  */
1381
  public function setup_intent( $order, $prepared_source ) {
1382
  $order_id = $order->get_id();
1383
- $setup_intent = WC_Stripe_API::request( array(
1384
- 'payment_method' => $prepared_source->source,
1385
- 'customer' => $prepared_source->customer,
1386
- 'confirm' => 'true',
1387
- ), 'setup_intents' );
 
 
 
1388
 
1389
  if ( is_wp_error( $setup_intent ) ) {
1390
  WC_Stripe_Logger::log( "Unable to create SetupIntent for Order #$order_id: " . print_r( $setup_intent, true ) );
@@ -1404,22 +1426,22 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
1404
  * @param float $amount The amount to charge. If not specified, it will be read from the order.
1405
  * @return object An intent or an error.
1406
  */
1407
- public function create_and_confirm_intent_for_off_session( $order, $prepared_source, $amount = NULL ) {
1408
  // The request for a charge contains metadata for the intent.
1409
  $full_request = $this->generate_payment_request( $order, $prepared_source );
1410
 
1411
- $request = array(
1412
  'amount' => $amount ? WC_Stripe_Helper::get_stripe_amount( $amount, $full_request['currency'] ) : $full_request['amount'],
1413
  'currency' => $full_request['currency'],
1414
  'description' => $full_request['description'],
1415
  'metadata' => $full_request['metadata'],
1416
- 'payment_method_types' => array(
1417
  'card',
1418
- ),
1419
  'off_session' => 'true',
1420
  'confirm' => 'true',
1421
  'confirmation_method' => 'automatic',
1422
- );
1423
 
1424
  if ( isset( $full_request['statement_descriptor'] ) ) {
1425
  $request['statement_descriptor'] = $full_request['statement_descriptor'];
@@ -1442,14 +1464,14 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
1442
  * @param WC_Order $order
1443
  * @param object $source
1444
  */
1445
- $request = apply_filters('wc_stripe_generate_create_intent_request', $request, $order, $prepared_source );
1446
 
1447
  if ( isset( $full_request['shipping'] ) ) {
1448
  $request['shipping'] = $full_request['shipping'];
1449
  }
1450
 
1451
- $level3_data = $this->get_level3_data_from_order( $order );
1452
- $intent = WC_Stripe_API::request_with_level3_data(
1453
  $request,
1454
  'payment_intents',
1455
  $level3_data,
@@ -1482,11 +1504,12 @@ abstract class WC_Stripe_Payment_Gateway extends WC_Payment_Gateway_CC {
1482
  * Checks if subscription has a Stripe customer ID and adds it if doesn't.
1483
  *
1484
  * Fix renewal for existing subscriptions affected by https://github.com/woocommerce/woocommerce-gateway-stripe/issues/1072.
 
1485
  * @param int $order_id subscription renewal order id.
1486
  */
1487
  public function ensure_subscription_has_customer_id( $order_id ) {
1488
- $subscriptions_ids = wcs_get_subscriptions_for_order( $order_id, array( 'order_type' => 'any' ) );
1489
- foreach( $subscriptions_ids as $subscription_id => $subscription ) {
1490
  if ( ! metadata_exists( 'post', $subscription_id, '_stripe_customer_id' ) ) {
1491
  $stripe_customer = new WC_Stripe_Customer( $subscription->get_user_id() );
1492
  update_post_meta( $subscription_id, '_stripe_customer_id', $stripe_customer->get_id() );
17
  * Displays the admin settings webhook description.
18
  *
19
  * @since 4.1.0
20
+ * @version 5.0.0
21
  * @return mixed
22
  */
23
  public function display_admin_settings_webhook_description() {
24
  /* translators: 1) webhook url */
25
+ $description = sprintf( __( 'You must add the following webhook endpoint <strong style="background-color:#ddd;">&nbsp;%s&nbsp;</strong> to your <a href="https://dashboard.stripe.com/account/webhooks" target="_blank">Stripe account settings</a> (if there isn\'t one already enabled). This will enable you to receive notifications on the charge statuses.', 'woocommerce-gateway-stripe' ), WC_Stripe_Helper::get_webhook_url() );
26
+
27
+ $webhook_status = WC_Stripe_Webhook_State::get_webhook_status_message();
28
+
29
+ return $description . '<br><br>' . $webhook_status;
30
  }
31
 
32
  /**
171
  && preg_match( '/^[rs]k_test_/', $this->secret_key );
172
  } else {
173
  return preg_match( '/^pk_live_/', $this->publishable_key )
174
+ && preg_match( '/^[rs]k_live_/', $this->secret_key );
175
  }
176
  }
177
 
216
  public function payment_icons() {
217
  return apply_filters(
218
  'wc_stripe_payment_icons',
219
+ [
220
  'visa' => '<img src="' . WC_STRIPE_PLUGIN_URL . '/assets/images/visa.svg" class="stripe-visa-icon stripe-icon" alt="Visa" />',
221
  'amex' => '<img src="' . WC_STRIPE_PLUGIN_URL . '/assets/images/amex.svg" class="stripe-amex-icon stripe-icon" alt="American Express" />',
222
  'mastercard' => '<img src="' . WC_STRIPE_PLUGIN_URL . '/assets/images/mastercard.svg" class="stripe-mastercard-icon stripe-icon" alt="Mastercard" />',
233
  'multibanco' => '<img src="' . WC_STRIPE_PLUGIN_URL . '/assets/images/multibanco.svg" class="stripe-multibanco-icon stripe-icon" alt="Multibanco" />',
234
  'sofort' => '<img src="' . WC_STRIPE_PLUGIN_URL . '/assets/images/sofort.svg" class="stripe-sofort-icon stripe-icon" alt="SOFORT" />',
235
  'sepa' => '<img src="' . WC_STRIPE_PLUGIN_URL . '/assets/images/sepa.svg" class="stripe-sepa-icon stripe-icon" alt="SEPA" />',
236
+ ]
237
  );
238
  }
239
 
293
  * @since 4.0.0
294
  * @version 4.0.0
295
  * @param object $order
296
+ * @param int $id Stripe session id.
297
  */
298
  public function get_stripe_return_url( $order = null, $id = null ) {
299
  if ( is_object( $order ) ) {
303
 
304
  $order_id = $order->get_id();
305
 
306
+ $args = [
307
  'utm_nooverride' => '1',
308
  'order_id' => $order_id,
309
+ ];
310
 
311
  return wp_sanitize_redirect( esc_url_raw( add_query_arg( $args, $this->get_return_url( $order ) ) ) );
312
  }
313
 
314
+ return wp_sanitize_redirect( esc_url_raw( add_query_arg( [ 'utm_nooverride' => '1' ], $this->get_return_url() ) ) );
315
  }
316
 
317
  /**
318
  * Is $order_id a subscription?
319
+ *
320
+ * @param int $order_id
321
  * @return boolean
322
  */
323
  public function has_subscription( $order_id ) {
330
  * @since 3.1.0
331
  * @version 4.5.4
332
  * @param WC_Order $order
333
+ * @param object $prepared_source
334
  * @return array()
335
  */
336
  public function generate_payment_request( $order, $prepared_source ) {
337
+ $settings = get_option( 'woocommerce_stripe_settings', [] );
338
  $statement_descriptor = ! empty( $settings['statement_descriptor'] ) ? str_replace( "'", '', $settings['statement_descriptor'] ) : '';
339
  $capture = ! empty( $settings['capture'] ) && 'yes' === $settings['capture'] ? true : false;
340
+ $post_data = [];
341
  $post_data['currency'] = strtolower( $order->get_currency() );
342
  $post_data['amount'] = WC_Stripe_Helper::get_stripe_amount( $order->get_total(), $post_data['currency'] );
343
  /* translators: 1) blog name 2) order number */
366
  }
367
 
368
  if ( method_exists( $order, 'get_shipping_postcode' ) && ! empty( $order->get_shipping_postcode() ) ) {
369
+ $post_data['shipping'] = [
370
  'name' => trim( $order->get_shipping_first_name() . ' ' . $order->get_shipping_last_name() ),
371
+ 'address' => [
372
  'line1' => $order->get_shipping_address_1(),
373
  'line2' => $order->get_shipping_address_2(),
374
  'city' => $order->get_shipping_city(),
375
  'country' => $order->get_shipping_country(),
376
  'postal_code' => $order->get_shipping_postcode(),
377
  'state' => $order->get_shipping_state(),
378
+ ],
379
+ ];
380
  }
381
 
382
  $post_data['expand[]'] = 'balance_transaction';
383
 
384
+ $metadata = [
385
  __( 'customer_name', 'woocommerce-gateway-stripe' ) => sanitize_text_field( $billing_first_name ) . ' ' . sanitize_text_field( $billing_last_name ),
386
  __( 'customer_email', 'woocommerce-gateway-stripe' ) => sanitize_email( $billing_email ),
387
  'order_id' => $order->get_order_number(),
388
  'site_url' => esc_url( get_site_url() ),
389
+ ];
390
 
391
  if ( $this->has_subscription( $order->get_id() ) ) {
392
+ $metadata += [
393
  'payment_type' => 'recurring',
394
+ ];
395
  }
396
 
397
  $post_data['metadata'] = apply_filters( 'wc_stripe_payment_metadata', $metadata, $order, $prepared_source );
465
  } else {
466
  $order->set_transaction_id( $response->id );
467
 
468
+ if ( $order->has_status( [ 'pending', 'failed' ] ) ) {
469
  wc_reduce_stock_levels( $order_id );
470
  }
471
 
473
  $order->update_status( 'on-hold', sprintf( __( 'Stripe charge authorized (Charge ID: %s). Process order to take payment, or cancel to remove the pre-authorization. Attempting to refund the order in part or in full will release the authorization and cancel the payment.', 'woocommerce-gateway-stripe' ), $response->id ) );
474
  }
475
 
476
+ if ( is_callable( [ $order, 'save' ] ) ) {
477
  $order->save();
478
  }
479
 
509
  $billing_first_name = $order->get_billing_first_name();
510
  $billing_last_name = $order->get_billing_last_name();
511
 
512
+ $details = [];
513
 
514
  $name = $billing_first_name . ' ' . $billing_last_name;
515
  $email = $order->get_billing_email();
590
  * @return bool
591
  */
592
  public function is_using_saved_payment_method() {
593
+ $payment_method = isset( $_POST['payment_method'] ) ? wc_clean( wp_unslash( $_POST['payment_method'] ) ) : 'stripe';
594
 
595
  return ( isset( $_POST[ 'wc-' . $payment_method . '-payment-token' ] ) && 'new' !== $_POST[ 'wc-' . $payment_method . '-payment-token' ] );
596
  }
603
  * @since 3.1.0
604
  * @version 4.0.0
605
  * @param string $user_id
606
+ * @param bool $force_save_source Should we force save payment source.
607
  *
608
  * @throws Exception When card was not added or for and invalid card.
609
  * @return object
618
  $source_object = '';
619
  $source_id = '';
620
  $wc_token_id = false;
621
+ $payment_method = isset( $_POST['payment_method'] ) ? wc_clean( wp_unslash( $_POST['payment_method'] ) ) : 'stripe';
622
  $is_token = false;
623
 
624
  // New CC info was entered and we have a new source to process.
625
  if ( ! empty( $_POST['stripe_source'] ) ) {
626
+ $source_object = self::get_source_object( wc_clean( wp_unslash( $_POST['stripe_source'] ) ) );
627
  $source_id = $source_object->id;
628
 
629
  // This checks to see if customer opted to save the payment method to file.
640
  if ( ! empty( $response->error ) ) {
641
  throw new WC_Stripe_Exception( print_r( $response, true ), $this->get_localized_error_message_from_response( $response ) );
642
  }
643
+ if ( is_wp_error( $response ) ) {
644
+ throw new WC_Stripe_Exception( $response->get_error_message(), $response->get_error_message() );
645
+ }
646
  }
647
  } elseif ( $this->is_using_saved_payment_method() ) {
648
  // Use an existing token, and then process the payment.
649
+ $wc_token_id = isset( $_POST[ 'wc-' . $payment_method . '-payment-token' ] ) ? wc_clean( wp_unslash( $_POST[ 'wc-' . $payment_method . '-payment-token' ] ) ) : '';
650
  $wc_token = WC_Payment_Tokens::get( $wc_token_id );
651
 
652
  if ( ! $wc_token || $wc_token->get_user_id() !== get_current_user_id() ) {
660
  $is_token = true;
661
  }
662
  } elseif ( isset( $_POST['stripe_token'] ) && 'new' !== $_POST['stripe_token'] ) {
663
+ $stripe_token = wc_clean( wp_unslash( $_POST['stripe_token'] ) );
664
  $maybe_saved_card = isset( $_POST[ 'wc-' . $payment_method . '-new-payment-method' ] ) && ! empty( $_POST[ 'wc-' . $payment_method . '-new-payment-method' ] );
665
 
666
  // This is true if the user wants to store the card to their account.
670
  if ( ! empty( $response->error ) ) {
671
  throw new WC_Stripe_Exception( print_r( $response, true ), $response->error->message );
672
  }
673
+ if ( is_wp_error( $response ) ) {
674
+ throw new WC_Stripe_Exception( $response->get_error_message(), $response->get_error_message() );
675
+ }
676
+ $source_id = $response;
677
  } else {
678
+ $source_id = $stripe_token;
679
+ $is_token = true;
680
  }
681
  }
682
 
692
  $source_object = self::get_source_object( $source_id );
693
  }
694
 
695
+ return (object) [
696
  'token_id' => $wc_token_id,
697
  'customer' => $customer_id,
698
  'source' => $source_id,
699
  'source_object' => $source_object,
700
+ ];
701
  }
702
 
703
  /**
737
  // Take this opportunity to update the key name.
738
  $order->update_meta_data( '_stripe_source_id', $source_id );
739
 
740
+ if ( is_callable( [ $order, 'save' ] ) ) {
741
  $order->save();
742
  }
743
  }
754
  }
755
  }
756
 
757
+ return (object) [
758
  'token_id' => $token_id,
759
  'customer' => $stripe_customer ? $stripe_customer->get_id() : false,
760
  'source' => $stripe_source,
761
  'source_object' => $source_object,
762
+ ];
763
  }
764
 
765
  /**
780
  $order->update_meta_data( '_stripe_source_id', $source->source );
781
  }
782
 
783
+ if ( is_callable( [ $order, 'save' ] ) ) {
784
  $order->save();
785
  }
786
  }
792
  * @since 4.0.0
793
  * @version 4.0.6
794
  * @param object $order The order object
795
+ * @param int $balance_transaction_id
796
  */
797
  public function update_fees( $order, $balance_transaction_id ) {
798
  $balance_transaction = WC_Stripe_API::retrieve( 'balance/history/' . $balance_transaction_id );
818
  $currency = ! empty( $balance_transaction->currency ) ? strtoupper( $balance_transaction->currency ) : null;
819
  WC_Stripe_Helper::update_stripe_currency( $order, $currency );
820
 
821
+ if ( is_callable( [ $order, 'save' ] ) ) {
822
  $order->save();
823
  }
824
  }
845
  return false;
846
  }
847
 
848
+ $request = [];
849
 
850
  $order_currency = $order->get_currency();
851
  $captured = $order->get_meta( '_stripe_charge_captured', true );
872
  $reason = $reason . '... [See WooCommerce order page for full text.]';
873
  }
874
 
875
+ $request['metadata'] = [
876
  'reason' => $reason,
877
+ ];
878
  }
879
 
880
  $request['charge'] = $charge_id;
882
 
883
  $request = apply_filters( 'wc_stripe_refund_request', $request, $order );
884
 
885
+ $intent = $this->get_intent_from_order( $order );
886
  $intent_cancelled = false;
887
  if ( $intent ) {
888
  // If the order has a Payment Intent pending capture, then the Intent itself must be refunded (cancelled), not the Charge.
889
  if ( ! empty( $intent->error ) ) {
890
+ $response = $intent;
891
  $intent_cancelled = true;
892
  } elseif ( 'requires_capture' === $intent->status ) {
893
+ $result = WC_Stripe_API::request(
894
+ [],
895
  'payment_intents/' . $intent->id . '/cancel'
896
  );
897
  $intent_cancelled = true;
899
  if ( ! empty( $result->error ) ) {
900
  $response = $result;
901
  } else {
902
+ $charge = end( $result->charges->data );
903
  $response = end( $charge->refunds->data );
904
  }
905
  }
969
 
970
  $stripe_customer = new WC_Stripe_Customer( get_current_user_id() );
971
 
972
+ $source = ! empty( $_POST['stripe_source'] ) ? wc_clean( wp_unslash( $_POST['stripe_source'] ) ) : '';
973
 
974
  $source_object = WC_Stripe_API::retrieve( 'sources/' . $source );
975
 
980
 
981
  $source_id = $source_object->id;
982
  } elseif ( isset( $_POST['stripe_token'] ) ) {
983
+ $source_id = wc_clean( wp_unslash( $_POST['stripe_token'] ) );
984
  }
985
 
986
  $response = $stripe_customer->add_source( $source_id );
995
  return;
996
  }
997
 
998
+ do_action( 'wc_stripe_add_payment_method_' . ( isset( $_POST['payment_method'] ) ? wc_clean( wp_unslash( $_POST['payment_method'] ) ) : '' ) . '_success', $source_id, $source_object );
999
 
1000
+ return [
1001
  'result' => 'success',
1002
  'redirect' => wc_get_endpoint_url( 'payment-methods' ),
1003
+ ];
1004
  }
1005
 
1006
  /**
1031
  *
1032
  * @since 4.0.6
1033
  * @param string $idempotency_key
1034
+ * @param array $request
1035
  */
1036
  public function change_idempotency_key( $idempotency_key, $request ) {
1037
  $customer = ! empty( $request['customer'] ) ? $request['customer'] : '';
1068
  // The request for a charge contains metadata for the intent.
1069
  $full_request = $this->generate_payment_request( $order, $prepared_source );
1070
 
1071
+ $request = [
1072
  'source' => $prepared_source->source,
1073
  'amount' => WC_Stripe_Helper::get_stripe_amount( $order->get_total() ),
1074
  'currency' => strtolower( $order->get_currency() ),
1075
  'description' => $full_request['description'],
1076
  'metadata' => $full_request['metadata'],
1077
  'capture_method' => ( 'true' === $full_request['capture'] ) ? 'automatic' : 'manual',
1078
+ 'payment_method_types' => [
1079
  'card',
1080
+ ],
1081
+ ];
1082
 
1083
  if ( $prepared_source->customer ) {
1084
  $request['customer'] = $prepared_source->customer;
1092
  $request['shipping'] = $full_request['shipping'];
1093
  }
1094
 
1095
+ if ( isset( $full_request['receipt_email'] ) ) {
1096
+ $request['receipt_email'] = $full_request['receipt_email'];
1097
+ }
1098
+
1099
  /**
1100
  * Filter the return value of the WC_Payment_Gateway_CC::generate_create_intent_request.
1101
  *
1119
  $order_items = array_values( $order->get_items( [ 'line_item', 'fee' ] ) );
1120
  $currency = $order->get_currency();
1121
 
1122
+ $stripe_line_items = array_map(
1123
+ function( $item ) use ( $currency ) {
1124
+ if ( is_a( $item, 'WC_Order_Item_Product' ) ) {
1125
+ $product_id = $item->get_variation_id()
1126
+ ? $item->get_variation_id()
1127
+ : $item->get_product_id();
1128
+ $subtotal = $item->get_subtotal();
1129
+ } else {
1130
+ $product_id = substr( sanitize_title( $item->get_name() ), 0, 12 );
1131
+ $subtotal = $item->get_total();
1132
+ }
1133
+ $product_description = substr( $item->get_name(), 0, 26 );
1134
+ $quantity = $item->get_quantity();
1135
+ $unit_cost = WC_Stripe_Helper::get_stripe_amount( ( $subtotal / $quantity ), $currency );
1136
+ $tax_amount = WC_Stripe_Helper::get_stripe_amount( $item->get_total_tax(), $currency );
1137
+ $discount_amount = WC_Stripe_Helper::get_stripe_amount( $subtotal - $item->get_total(), $currency );
1138
+
1139
+ return (object) [
1140
+ 'product_code' => (string) $product_id, // Up to 12 characters that uniquely identify the product.
1141
+ 'product_description' => $product_description, // Up to 26 characters long describing the product.
1142
+ 'unit_cost' => $unit_cost, // Cost of the product, in cents, as a non-negative integer.
1143
+ 'quantity' => $quantity, // The number of items of this type sold, as a non-negative integer.
1144
+ 'tax_amount' => $tax_amount, // The amount of tax this item had added to it, in cents, as a non-negative integer.
1145
+ 'discount_amount' => $discount_amount, // The amount an item was discounted—if there was a sale,for example, as a non-negative integer.
1146
+ ];
1147
+ },
1148
+ $order_items
 
 
 
1149
  );
1150
 
1151
+ $level3_data = [
1152
+ 'merchant_reference' => $order->get_id(), // An alphanumeric string of up to characters in length. This unique value is assigned by the merchant to identify the order. Also known as an “Order ID”.
1153
+ 'shipping_amount' => WC_Stripe_Helper::get_stripe_amount( (float) $order->get_shipping_total() + (float) $order->get_shipping_tax(), $currency ), // The shipping cost, in cents, as a non-negative integer.
1154
+ 'line_items' => $stripe_line_items,
1155
+ ];
1156
+
1157
  // The customer’s U.S. shipping ZIP code.
1158
  $shipping_address_zip = $order->get_shipping_postcode();
1159
  if ( $this->is_valid_us_zip_code( $shipping_address_zip ) ) {
1203
  * @return object An updated intent.
1204
  */
1205
  public function update_existing_intent( $intent, $order, $prepared_source ) {
1206
+ $request = [];
1207
 
1208
  if ( $prepared_source->source !== $intent->source ) {
1209
  $request['source'] = $prepared_source->source;
1252
  }
1253
 
1254
  // Try to confirm the intent & capture the charge (if 3DS is not required).
1255
+ $confirm_request = [
1256
  'source' => $prepared_source->source,
1257
+ ];
1258
 
1259
+ $level3_data = $this->get_level3_data_from_order( $order );
1260
  $confirmed_intent = WC_Stripe_API::request_with_level3_data(
1261
  $confirm_request,
1262
  "payment_intents/$intent->id/confirm",
1289
  public function save_intent_to_order( $order, $intent ) {
1290
  $order->update_meta_data( '_stripe_intent_id', $intent->id );
1291
 
1292
+ if ( is_callable( [ $order, 'save' ] ) ) {
1293
  $order->save();
1294
  }
1295
  }
1321
  /**
1322
  * Retrieves intent from Stripe API by intent id.
1323
  *
1324
+ * @param string $intent_type Either 'payment_intents' or 'setup_intents'.
1325
+ * @param string $intent_id Intent id.
1326
+ * @return object|bool Either the intent object or `false`.
1327
+ * @throws Exception Throws exception for unknown $intent_type.
1328
  */
1329
  private function get_intent( $intent_type, $intent_id ) {
1330
  if ( ! in_array( $intent_type, [ 'payment_intents', 'setup_intents' ] ) ) {
1331
  throw new Exception( "Failed to get intent of type $intent_type. Type is not allowed" );
1332
  }
1333
 
1334
+ $response = WC_Stripe_API::request( [], "$intent_type/$intent_id", 'GET' );
1335
 
1336
  if ( $response && isset( $response->{ 'error' } ) ) {
1337
  $error_response_message = print_r( $response, true );
1338
+ WC_Stripe_Logger::log( "Failed to get Stripe intent $intent_type/$intent_id." );
1339
+ WC_Stripe_Logger::log( "Response: $error_response_message" );
1340
  return false;
1341
  }
1342
 
1357
  $processing = get_transient( $transient_name );
1358
 
1359
  // Block the process if the same intent is already being handled.
1360
+ if ( '-1' === $processing || ( isset( $intent->id ) && $processing === $intent->id ) ) {
1361
  return true;
1362
  }
1363
 
1399
  */
1400
  public function setup_intent( $order, $prepared_source ) {
1401
  $order_id = $order->get_id();
1402
+ $setup_intent = WC_Stripe_API::request(
1403
+ [
1404
+ 'payment_method' => $prepared_source->source,
1405
+ 'customer' => $prepared_source->customer,
1406
+ 'confirm' => 'true',
1407
+ ],
1408
+ 'setup_intents'
1409
+ );
1410
 
1411
  if ( is_wp_error( $setup_intent ) ) {
1412
  WC_Stripe_Logger::log( "Unable to create SetupIntent for Order #$order_id: " . print_r( $setup_intent, true ) );
1426
  * @param float $amount The amount to charge. If not specified, it will be read from the order.
1427
  * @return object An intent or an error.
1428
  */
1429
+ public function create_and_confirm_intent_for_off_session( $order, $prepared_source, $amount = null ) {
1430
  // The request for a charge contains metadata for the intent.
1431
  $full_request = $this->generate_payment_request( $order, $prepared_source );
1432
 
1433
+ $request = [
1434
  'amount' => $amount ? WC_Stripe_Helper::get_stripe_amount( $amount, $full_request['currency'] ) : $full_request['amount'],
1435
  'currency' => $full_request['currency'],
1436
  'description' => $full_request['description'],
1437
  'metadata' => $full_request['metadata'],
1438
+ 'payment_method_types' => [
1439
  'card',
1440
+ ],
1441
  'off_session' => 'true',
1442
  'confirm' => 'true',
1443
  'confirmation_method' => 'automatic',
1444
+ ];
1445
 
1446
  if ( isset( $full_request['statement_descriptor'] ) ) {
1447
  $request['statement_descriptor'] = $full_request['statement_descriptor'];
1464
  * @param WC_Order $order
1465
  * @param object $source
1466
  */
1467
+ $request = apply_filters( 'wc_stripe_generate_create_intent_request', $request, $order, $prepared_source );
1468
 
1469
  if ( isset( $full_request['shipping'] ) ) {
1470
  $request['shipping'] = $full_request['shipping'];
1471
  }
1472
 
1473
+ $level3_data = $this->get_level3_data_from_order( $order );
1474
+ $intent = WC_Stripe_API::request_with_level3_data(
1475
  $request,
1476
  'payment_intents',
1477
  $level3_data,
1504
  * Checks if subscription has a Stripe customer ID and adds it if doesn't.
1505
  *
1506
  * Fix renewal for existing subscriptions affected by https://github.com/woocommerce/woocommerce-gateway-stripe/issues/1072.
1507
+ *
1508
  * @param int $order_id subscription renewal order id.
1509
  */
1510
  public function ensure_subscription_has_customer_id( $order_id ) {
1511
+ $subscriptions_ids = wcs_get_subscriptions_for_order( $order_id, [ 'order_type' => 'any' ] );
1512
+ foreach ( $subscriptions_ids as $subscription_id => $subscription ) {
1513
  if ( ! metadata_exists( 'post', $subscription_id, '_stripe_customer_id' ) ) {
1514
  $stripe_customer = new WC_Stripe_Customer( $subscription->get_user_id() );
1515
  update_post_meta( $subscription_id, '_stripe_customer_id', $stripe_customer->get_id() );
includes/admin/class-wc-stripe-admin-notices.php CHANGED
@@ -11,9 +11,10 @@ if ( ! defined( 'ABSPATH' ) ) {
11
  class WC_Stripe_Admin_Notices {
12
  /**
13
  * Notices (array)
 
14
  * @var array
15
  */
16
- public $notices = array();
17
 
18
  /**
19
  * Constructor
@@ -21,9 +22,9 @@ class WC_Stripe_Admin_Notices {
21
  * @since 4.1.0
22
  */
23
  public function __construct() {
24
- add_action( 'admin_notices', array( $this, 'admin_notices' ) );
25
- add_action( 'wp_loaded', array( $this, 'hide_notices' ) );
26
- add_action( 'woocommerce_stripe_updated', array( $this, 'stripe_updated' ) );
27
  }
28
 
29
  /**
@@ -33,11 +34,11 @@ class WC_Stripe_Admin_Notices {
33
  * @version 4.0.0
34
  */
35
  public function add_admin_notice( $slug, $class, $message, $dismissible = false ) {
36
- $this->notices[ $slug ] = array(
37
  'class' => $class,
38
  'message' => $message,
39
  'dismissible' => $dismissible,
40
- );
41
  }
42
 
43
  /**
@@ -67,7 +68,15 @@ class WC_Stripe_Admin_Notices {
67
  }
68
 
69
  echo '<p>';
70
- echo wp_kses( $notice['message'], array( 'a' => array( 'href' => array(), 'target' => array() ) ) );
 
 
 
 
 
 
 
 
71
  echo '</p></div>';
72
  }
73
  }
@@ -79,7 +88,7 @@ class WC_Stripe_Admin_Notices {
79
  * @return array
80
  */
81
  public function get_payment_methods() {
82
- return array(
83
  'Alipay' => 'WC_Gateway_Stripe_Alipay',
84
  'Bancontact' => 'WC_Gateway_Stripe_Bancontact',
85
  'EPS' => 'WC_Gateway_Stripe_EPS',
@@ -89,7 +98,7 @@ class WC_Stripe_Admin_Notices {
89
  'P24' => 'WC_Gateway_Stripe_p24',
90
  'SEPA' => 'WC_Gateway_Stripe_Sepa',
91
  'SOFORT' => 'WC_Gateway_Stripe_Sofort',
92
- );
93
  }
94
 
95
  /**
@@ -199,6 +208,7 @@ class WC_Stripe_Admin_Notices {
199
  }
200
 
201
  if ( empty( $show_sca_notice ) ) {
 
202
  $this->add_admin_notice( 'sca', 'notice notice-success', sprintf( __( 'Stripe is now ready for Strong Customer Authentication (SCA) and 3D Secure 2! <a href="%1$s" target="_blank">Read about SCA</a>', 'woocommerce-gateway-stripe' ), 'https://woocommerce.com/posts/introducing-strong-customer-authentication-sca/' ), true );
203
  }
204
 
@@ -240,7 +250,7 @@ class WC_Stripe_Admin_Notices {
240
  */
241
  public function hide_notices() {
242
  if ( isset( $_GET['wc-stripe-hide-notice'] ) && isset( $_GET['_wc_stripe_notice_nonce'] ) ) {
243
- if ( ! wp_verify_nonce( $_GET['_wc_stripe_notice_nonce'], 'wc_stripe_hide_notices_nonce' ) ) {
244
  wp_die( __( 'Action failed. Please refresh the page and retry.', 'woocommerce-gateway-stripe' ) );
245
  }
246
 
@@ -248,7 +258,7 @@ class WC_Stripe_Admin_Notices {
248
  wp_die( __( 'Cheatin&#8217; huh?', 'woocommerce-gateway-stripe' ) );
249
  }
250
 
251
- $notice = wc_clean( $_GET['wc-stripe-hide-notice'] );
252
 
253
  switch ( $notice ) {
254
  case 'style':
11
  class WC_Stripe_Admin_Notices {
12
  /**
13
  * Notices (array)
14
+ *
15
  * @var array
16
  */
17
+ public $notices = [];
18
 
19
  /**
20
  * Constructor
22
  * @since 4.1.0
23
  */
24
  public function __construct() {
25
+ add_action( 'admin_notices', [ $this, 'admin_notices' ] );
26
+ add_action( 'wp_loaded', [ $this, 'hide_notices' ] );
27
+ add_action( 'woocommerce_stripe_updated', [ $this, 'stripe_updated' ] );
28
  }
29
 
30
  /**
34
  * @version 4.0.0
35
  */
36
  public function add_admin_notice( $slug, $class, $message, $dismissible = false ) {
37
+ $this->notices[ $slug ] = [
38
  'class' => $class,
39
  'message' => $message,
40
  'dismissible' => $dismissible,
41
+ ];
42
  }
43
 
44
  /**
68
  }
69
 
70
  echo '<p>';
71
+ echo wp_kses(
72
+ $notice['message'],
73
+ [
74
+ 'a' => [
75
+ 'href' => [],
76
+ 'target' => [],
77
+ ],
78
+ ]
79
+ );
80
  echo '</p></div>';
81
  }
82
  }
88
  * @return array
89
  */
90
  public function get_payment_methods() {
91
+ return [
92
  'Alipay' => 'WC_Gateway_Stripe_Alipay',
93
  'Bancontact' => 'WC_Gateway_Stripe_Bancontact',
94
  'EPS' => 'WC_Gateway_Stripe_EPS',
98
  'P24' => 'WC_Gateway_Stripe_p24',
99
  'SEPA' => 'WC_Gateway_Stripe_Sepa',
100
  'SOFORT' => 'WC_Gateway_Stripe_Sofort',
101
+ ];
102
  }
103
 
104
  /**
208
  }
209
 
210
  if ( empty( $show_sca_notice ) ) {
211
+ /* translators: %1 is the URL for the link */
212
  $this->add_admin_notice( 'sca', 'notice notice-success', sprintf( __( 'Stripe is now ready for Strong Customer Authentication (SCA) and 3D Secure 2! <a href="%1$s" target="_blank">Read about SCA</a>', 'woocommerce-gateway-stripe' ), 'https://woocommerce.com/posts/introducing-strong-customer-authentication-sca/' ), true );
213
  }
214
 
250
  */
251
  public function hide_notices() {
252
  if ( isset( $_GET['wc-stripe-hide-notice'] ) && isset( $_GET['_wc_stripe_notice_nonce'] ) ) {
253
+ if ( ! wp_verify_nonce( wc_clean( wp_unslash( $_GET['_wc_stripe_notice_nonce'] ) ), 'wc_stripe_hide_notices_nonce' ) ) {
254
  wp_die( __( 'Action failed. Please refresh the page and retry.', 'woocommerce-gateway-stripe' ) );
255
  }
256
 
258
  wp_die( __( 'Cheatin&#8217; huh?', 'woocommerce-gateway-stripe' ) );
259
  }
260
 
261
+ $notice = wc_clean( wp_unslash( $_GET['wc-stripe-hide-notice'] ) );
262
 
263
  switch ( $notice ) {
264
  case 'style':
includes/admin/class-wc-stripe-inbox-notes.php CHANGED
@@ -19,13 +19,13 @@ class WC_Stripe_Inbox_Notes {
19
  const CAMPAIGN_2020_CLEANUP_ACTION = 'wc_stripe_apple_pay_2020_cleanup';
20
 
21
  public function __construct() {
22
- add_action( self::POST_SETUP_SUCCESS_ACTION, array( self::class, 'create_marketing_note' ) );
23
- add_action( self::CAMPAIGN_2020_CLEANUP_ACTION, array( self::class, 'cleanup_campaign_2020' ) );
24
 
25
  // Schedule a 2020 holiday campaign cleanup action if needed.
26
  // First, check to see if we are still before the cutoff.
27
  // We don't need to (re)schedule this after the cutoff.
28
- if ( current_time( 'timestamp', true ) < self::get_campaign_2020_cutoff() ) {
29
  // If we don't have the clean up action scheduled, add it.
30
  if ( ! wp_next_scheduled( self::CAMPAIGN_2020_CLEANUP_ACTION ) ) {
31
  wp_schedule_single_event( self::get_campaign_2020_cutoff(), self::CAMPAIGN_2020_CLEANUP_ACTION );
@@ -38,7 +38,7 @@ class WC_Stripe_Inbox_Notes {
38
  }
39
 
40
  public static function get_success_title() {
41
- if ( current_time( 'timestamp', true ) < self::get_campaign_2020_cutoff() ) {
42
  return __( 'Boost sales this holiday season with Apple Pay!', 'woocommerce-gateway-stripe' );
43
  }
44
 
@@ -89,7 +89,7 @@ class WC_Stripe_Inbox_Notes {
89
  }
90
 
91
  // Make sure Apple Pay is enabled and setup is successful.
92
- $stripe_settings = get_option( 'woocommerce_stripe_settings', array() );
93
  $stripe_enabled = isset( $stripe_settings['enabled'] ) && 'yes' === $stripe_settings['enabled'];
94
  $button_enabled = isset( $stripe_settings['payment_request'] ) && 'yes' === $stripe_settings['payment_request'];
95
  $verification_complete = isset( $stripe_settings['apple_pay_domain_set'] ) && 'yes' === $stripe_settings['apple_pay_domain_set'];
@@ -162,7 +162,7 @@ class WC_Stripe_Inbox_Notes {
162
  * on/about 2020 Dec 22.
163
  */
164
  public static function cleanup_campaign_2020() {
165
- if ( ! class_exists( 'Automattic\WooCommerce\Admin\Notes\WC_Admin_Notes') ) {
166
  return;
167
  }
168
 
@@ -170,7 +170,7 @@ class WC_Stripe_Inbox_Notes {
170
  return;
171
  }
172
 
173
- $note_ids = array();
174
 
175
  try {
176
  $data_store = WC_Data_Store::load( 'admin-note' );
19
  const CAMPAIGN_2020_CLEANUP_ACTION = 'wc_stripe_apple_pay_2020_cleanup';
20
 
21
  public function __construct() {
22
+ add_action( self::POST_SETUP_SUCCESS_ACTION, [ self::class, 'create_marketing_note' ] );
23
+ add_action( self::CAMPAIGN_2020_CLEANUP_ACTION, [ self::class, 'cleanup_campaign_2020' ] );
24
 
25
  // Schedule a 2020 holiday campaign cleanup action if needed.
26
  // First, check to see if we are still before the cutoff.
27
  // We don't need to (re)schedule this after the cutoff.
28
+ if ( time() < self::get_campaign_2020_cutoff() ) {
29
  // If we don't have the clean up action scheduled, add it.
30
  if ( ! wp_next_scheduled( self::CAMPAIGN_2020_CLEANUP_ACTION ) ) {
31
  wp_schedule_single_event( self::get_campaign_2020_cutoff(), self::CAMPAIGN_2020_CLEANUP_ACTION );
38
  }
39
 
40
  public static function get_success_title() {
41
+ if ( time() < self::get_campaign_2020_cutoff() ) {
42
  return __( 'Boost sales this holiday season with Apple Pay!', 'woocommerce-gateway-stripe' );
43
  }
44
 
89
  }
90
 
91
  // Make sure Apple Pay is enabled and setup is successful.
92
+ $stripe_settings = get_option( 'woocommerce_stripe_settings', [] );
93
  $stripe_enabled = isset( $stripe_settings['enabled'] ) && 'yes' === $stripe_settings['enabled'];
94
  $button_enabled = isset( $stripe_settings['payment_request'] ) && 'yes' === $stripe_settings['payment_request'];
95
  $verification_complete = isset( $stripe_settings['apple_pay_domain_set'] ) && 'yes' === $stripe_settings['apple_pay_domain_set'];
162
  * on/about 2020 Dec 22.
163
  */
164
  public static function cleanup_campaign_2020() {
165
+ if ( ! class_exists( 'Automattic\WooCommerce\Admin\Notes\WC_Admin_Notes' ) ) {
166
  return;
167
  }
168
 
170
  return;
171
  }
172
 
173
+ $note_ids = [];
174
 
175
  try {
176
  $data_store = WC_Data_Store::load( 'admin-note' );
includes/admin/class-wc-stripe-privacy.php CHANGED
@@ -6,23 +6,22 @@ if ( ! class_exists( 'WC_Abstract_Privacy' ) ) {
6
  class WC_Stripe_Privacy extends WC_Abstract_Privacy {
7
  /**
8
  * Constructor
9
- *
10
  */
11
  public function __construct() {
12
  parent::__construct( __( 'Stripe', 'woocommerce-gateway-stripe' ) );
13
 
14
- $this->add_exporter( 'woocommerce-gateway-stripe-order-data', __( 'WooCommerce Stripe Order Data', 'woocommerce-gateway-stripe' ), array( $this, 'order_data_exporter' ) );
15
 
16
  if ( function_exists( 'wcs_get_subscriptions' ) ) {
17
- $this->add_exporter( 'woocommerce-gateway-stripe-subscriptions-data', __( 'WooCommerce Stripe Subscriptions Data', 'woocommerce-gateway-stripe' ), array( $this, 'subscriptions_data_exporter' ) );
18
  }
19
 
20
- $this->add_exporter( 'woocommerce-gateway-stripe-customer-data', __( 'WooCommerce Stripe Customer Data', 'woocommerce-gateway-stripe' ), array( $this, 'customer_data_exporter' ) );
21
 
22
- $this->add_eraser( 'woocommerce-gateway-stripe-customer-data', __( 'WooCommerce Stripe Customer Data', 'woocommerce-gateway-stripe' ), array( $this, 'customer_data_eraser' ) );
23
- $this->add_eraser( 'woocommerce-gateway-stripe-order-data', __( 'WooCommerce Stripe Data', 'woocommerce-gateway-stripe' ), array( $this, 'order_data_eraser' ) );
24
 
25
- add_filter( 'woocommerce_get_settings_account', array( $this, 'account_settings' ) );
26
  }
27
 
28
  /**
@@ -32,8 +31,8 @@ class WC_Stripe_Privacy extends WC_Abstract_Privacy {
32
  * @return array $settings Updated
33
  */
34
  public function account_settings( $settings ) {
35
- $insert_setting = array(
36
- array(
37
  'title' => __( 'Retain Stripe Data', 'woocommerce-gateway-stripe' ),
38
  'desc_tip' => __( 'Retains any Stripe data such as Stripe customer ID, source ID.', 'woocommerce-gateway-stripe' ),
39
  'id' => 'woocommerce_gateway_stripe_retention',
@@ -41,13 +40,13 @@ class WC_Stripe_Privacy extends WC_Abstract_Privacy {
41
  'placeholder' => __( 'N/A', 'woocommerce-gateway-stripe' ),
42
  'default' => '',
43
  'autoload' => false,
44
- ),
45
- );
46
 
47
  $index = null;
48
 
49
- foreach ( $settings as $key => $value) {
50
- if ( 'sectionend' === $value[ 'type' ] && 'personal_data_retention' === $value[ 'id' ] ) {
51
  $index = $key;
52
  break;
53
  }
@@ -63,19 +62,19 @@ class WC_Stripe_Privacy extends WC_Abstract_Privacy {
63
  /**
64
  * Returns a list of orders that are using one of Stripe's payment methods.
65
  *
66
- * @param string $email_address
67
- * @param int $page
68
  *
69
  * @return array WP_Post
70
  */
71
  protected function get_stripe_orders( $email_address, $page ) {
72
  $user = get_user_by( 'email', $email_address ); // Check if user has an ID in the DB to load stored personal data.
73
 
74
- $order_query = array(
75
- 'payment_method' => array( 'stripe', 'stripe_alipay', 'stripe_bancontact', 'stripe_eps', 'stripe_giropay', 'stripe_ideal', 'stripe_multibanco', 'stripe_p24', 'stripe_sepa', 'stripe_sofort' ),
76
  'limit' => 10,
77
  'page' => $page,
78
- );
79
 
80
  if ( $user instanceof WP_User ) {
81
  $order_query['customer_id'] = (int) $user->ID;
@@ -88,7 +87,6 @@ class WC_Stripe_Privacy extends WC_Abstract_Privacy {
88
 
89
  /**
90
  * Gets the message of the privacy to display.
91
- *
92
  */
93
  public function get_privacy_message() {
94
  /* translators: %s URL to docs */
@@ -105,7 +103,7 @@ class WC_Stripe_Privacy extends WC_Abstract_Privacy {
105
  */
106
  public function order_data_exporter( $email_address, $page = 1 ) {
107
  $done = false;
108
- $data_to_export = array();
109
 
110
  $orders = $this->get_stripe_orders( $email_address, (int) $page );
111
 
@@ -113,30 +111,30 @@ class WC_Stripe_Privacy extends WC_Abstract_Privacy {
113
 
114
  if ( 0 < count( $orders ) ) {
115
  foreach ( $orders as $order ) {
116
- $data_to_export[] = array(
117
  'group_id' => 'woocommerce_orders',
118
  'group_label' => __( 'Orders', 'woocommerce-gateway-stripe' ),
119
  'item_id' => 'order-' . $order->get_id(),
120
- 'data' => array(
121
- array(
122
  'name' => __( 'Stripe payment id', 'woocommerce-gateway-stripe' ),
123
  'value' => get_post_meta( $order->get_id(), '_stripe_source_id', true ),
124
- ),
125
- array(
126
  'name' => __( 'Stripe customer id', 'woocommerce-gateway-stripe' ),
127
  'value' => get_post_meta( $order->get_id(), '_stripe_customer_id', true ),
128
- ),
129
- ),
130
- );
131
  }
132
 
133
  $done = 10 > count( $orders );
134
  }
135
 
136
- return array(
137
  'data' => $data_to_export,
138
  'done' => $done,
139
- );
140
  }
141
 
142
  /**
@@ -150,27 +148,27 @@ class WC_Stripe_Privacy extends WC_Abstract_Privacy {
150
  public function subscriptions_data_exporter( $email_address, $page = 1 ) {
151
  $done = false;
152
  $page = (int) $page;
153
- $data_to_export = array();
154
 
155
- $meta_query = array(
156
  'relation' => 'AND',
157
- array(
158
  'key' => '_payment_method',
159
- 'value' => array( 'stripe', 'stripe_alipay', 'stripe_bancontact', 'stripe_eps', 'stripe_giropay', 'stripe_ideal', 'stripe_multibanco', 'stripe_p24', 'stripe_sepa', 'stripe_sofort' ),
160
  'compare' => 'IN',
161
- ),
162
- array(
163
  'key' => '_billing_email',
164
  'value' => $email_address,
165
  'compare' => '=',
166
- ),
167
- );
168
 
169
- $subscription_query = array(
170
  'posts_per_page' => 10,
171
  'page' => $page,
172
  'meta_query' => $meta_query,
173
- );
174
 
175
  $subscriptions = wcs_get_subscriptions( $subscription_query );
176
 
@@ -178,30 +176,30 @@ class WC_Stripe_Privacy extends WC_Abstract_Privacy {
178
 
179
  if ( 0 < count( $subscriptions ) ) {
180
  foreach ( $subscriptions as $subscription ) {
181
- $data_to_export[] = array(
182
  'group_id' => 'woocommerce_subscriptions',
183
  'group_label' => __( 'Subscriptions', 'woocommerce-gateway-stripe' ),
184
  'item_id' => 'subscription-' . $subscription->get_id(),
185
- 'data' => array(
186
- array(
187
  'name' => __( 'Stripe payment id', 'woocommerce-gateway-stripe' ),
188
  'value' => get_post_meta( $subscription->get_id(), '_stripe_source_id', true ),
189
- ),
190
- array(
191
  'name' => __( 'Stripe customer id', 'woocommerce-gateway-stripe' ),
192
  'value' => get_post_meta( $subscription->get_id(), '_stripe_customer_id', true ),
193
- ),
194
- ),
195
- );
196
  }
197
 
198
  $done = 10 > count( $subscriptions );
199
  }
200
 
201
- return array(
202
  'data' => $data_to_export,
203
  'done' => $done,
204
- );
205
  }
206
 
207
  /**
@@ -213,32 +211,32 @@ class WC_Stripe_Privacy extends WC_Abstract_Privacy {
213
  */
214
  public function customer_data_exporter( $email_address, $page ) {
215
  $user = get_user_by( 'email', $email_address ); // Check if user has an ID in the DB to load stored personal data.
216
- $data_to_export = array();
217
 
218
  if ( $user instanceof WP_User ) {
219
  $stripe_user = new WC_Stripe_Customer( $user->ID );
220
 
221
- $data_to_export[] = array(
222
  'group_id' => 'woocommerce_customer',
223
  'group_label' => __( 'Customer Data', 'woocommerce-gateway-stripe' ),
224
  'item_id' => 'user',
225
- 'data' => array(
226
- array(
227
  'name' => __( 'Stripe payment id', 'woocommerce-gateway-stripe' ),
228
  'value' => get_user_option( '_stripe_source_id', $user->ID ),
229
- ),
230
- array(
231
  'name' => __( 'Stripe customer id', 'woocommerce-gateway-stripe' ),
232
  'value' => $stripe_user->get_id(),
233
- ),
234
- ),
235
- );
236
  }
237
 
238
- return array(
239
  'data' => $data_to_export,
240
  'done' => true,
241
- );
242
  }
243
 
244
  /**
@@ -260,7 +258,7 @@ class WC_Stripe_Privacy extends WC_Abstract_Privacy {
260
  }
261
 
262
  $items_removed = false;
263
- $messages = array();
264
 
265
  if ( ! empty( $stripe_customer_id ) || ! empty( $stripe_source_id ) ) {
266
  $items_removed = true;
@@ -269,12 +267,12 @@ class WC_Stripe_Privacy extends WC_Abstract_Privacy {
269
  $messages[] = __( 'Stripe User Data Erased.', 'woocommerce-gateway-stripe' );
270
  }
271
 
272
- return array(
273
  'items_removed' => $items_removed,
274
  'items_retained' => false,
275
  'messages' => $messages,
276
  'done' => true,
277
- );
278
  }
279
 
280
  /**
@@ -289,7 +287,7 @@ class WC_Stripe_Privacy extends WC_Abstract_Privacy {
289
 
290
  $items_removed = false;
291
  $items_retained = false;
292
- $messages = array();
293
 
294
  foreach ( (array) $orders as $order ) {
295
  $order = wc_get_order( $order->get_id() );
@@ -308,12 +306,12 @@ class WC_Stripe_Privacy extends WC_Abstract_Privacy {
308
  // Tell core if we have more orders to work on still
309
  $done = count( $orders ) < 10;
310
 
311
- return array(
312
  'items_removed' => $items_removed,
313
  'items_retained' => $items_retained,
314
  'messages' => $messages,
315
  'done' => $done,
316
- );
317
  }
318
 
319
  /**
@@ -324,11 +322,11 @@ class WC_Stripe_Privacy extends WC_Abstract_Privacy {
324
  */
325
  protected function maybe_handle_subscription( $order ) {
326
  if ( ! class_exists( 'WC_Subscriptions' ) ) {
327
- return array( false, false, array() );
328
  }
329
 
330
  if ( ! wcs_order_contains_subscription( $order ) ) {
331
- return array( false, false, array() );
332
  }
333
 
334
  $subscription = current( wcs_get_subscriptions_for_order( $order->get_id() ) );
@@ -337,17 +335,17 @@ class WC_Stripe_Privacy extends WC_Abstract_Privacy {
337
  $stripe_source_id = get_post_meta( $subscription_id, '_stripe_source_id', true );
338
 
339
  if ( empty( $stripe_source_id ) ) {
340
- return array( false, false, array() );
341
  }
342
 
343
  if ( ! $this->is_retention_expired( $order->get_date_created()->getTimestamp() ) ) {
344
  /* translators: %d Order ID */
345
- return array( false, true, array( sprintf( __( 'Order ID %d is less than set retention days. Personal data retained. (Stripe)', 'woocommerce-gateway-stripe' ), $order->get_id() ) ) );
346
  }
347
 
348
- if ( $subscription->has_status( apply_filters( 'wc_stripe_privacy_eraser_subs_statuses', array( 'on-hold', 'active' ) ) ) ) {
349
  /* translators: %d Order ID */
350
- return array( false, true, array( sprintf( __( 'Order ID %d contains an active Subscription. Personal data retained. (Stripe)', 'woocommerce-gateway-stripe' ), $order->get_id() ) ) );
351
  }
352
 
353
  $renewal_orders = WC_Subscriptions_Renewal_Order::get_renewal_orders( $order->get_id() );
@@ -362,7 +360,7 @@ class WC_Stripe_Privacy extends WC_Abstract_Privacy {
362
  delete_post_meta( $subscription_id, '_stripe_refund_id' );
363
  delete_post_meta( $subscription_id, '_stripe_customer_id' );
364
 
365
- return array( true, false, array( __( 'Stripe Subscription Data Erased.', 'woocommerce-gateway-stripe' ) ) );
366
  }
367
 
368
  /**
@@ -379,23 +377,22 @@ class WC_Stripe_Privacy extends WC_Abstract_Privacy {
379
 
380
  if ( ! $this->is_retention_expired( $order->get_date_created()->getTimestamp() ) ) {
381
  /* translators: %d Order ID */
382
- return array( false, true, array( sprintf( __( 'Order ID %d is less than set retention days. Personal data retained. (Stripe)', 'woocommerce-gateway-stripe' ), $order->get_id() ) ) );
383
  }
384
 
385
  if ( empty( $stripe_source_id ) && empty( $stripe_refund_id ) && empty( $stripe_customer_id ) ) {
386
- return array( false, false, array() );
387
  }
388
 
389
  delete_post_meta( $order_id, '_stripe_source_id' );
390
  delete_post_meta( $order_id, '_stripe_refund_id' );
391
  delete_post_meta( $order_id, '_stripe_customer_id' );
392
 
393
- return array( true, false, array( __( 'Stripe personal data erased.', 'woocommerce-gateway-stripe' ) ) );
394
  }
395
 
396
  /**
397
  * Checks if create date is passed retention duration.
398
- *
399
  */
400
  public function is_retention_expired( $created_date ) {
401
  $retention = wc_parse_relative_date_option( get_option( 'woocommerce_gateway_stripe_retention' ) );
6
  class WC_Stripe_Privacy extends WC_Abstract_Privacy {
7
  /**
8
  * Constructor
 
9
  */
10
  public function __construct() {
11
  parent::__construct( __( 'Stripe', 'woocommerce-gateway-stripe' ) );
12
 
13
+ $this->add_exporter( 'woocommerce-gateway-stripe-order-data', __( 'WooCommerce Stripe Order Data', 'woocommerce-gateway-stripe' ), [ $this, 'order_data_exporter' ] );
14
 
15
  if ( function_exists( 'wcs_get_subscriptions' ) ) {
16
+ $this->add_exporter( 'woocommerce-gateway-stripe-subscriptions-data', __( 'WooCommerce Stripe Subscriptions Data', 'woocommerce-gateway-stripe' ), [ $this, 'subscriptions_data_exporter' ] );
17
  }
18
 
19
+ $this->add_exporter( 'woocommerce-gateway-stripe-customer-data', __( 'WooCommerce Stripe Customer Data', 'woocommerce-gateway-stripe' ), [ $this, 'customer_data_exporter' ] );
20
 
21
+ $this->add_eraser( 'woocommerce-gateway-stripe-customer-data', __( 'WooCommerce Stripe Customer Data', 'woocommerce-gateway-stripe' ), [ $this, 'customer_data_eraser' ] );
22
+ $this->add_eraser( 'woocommerce-gateway-stripe-order-data', __( 'WooCommerce Stripe Data', 'woocommerce-gateway-stripe' ), [ $this, 'order_data_eraser' ] );
23
 
24
+ add_filter( 'woocommerce_get_settings_account', [ $this, 'account_settings' ] );
25
  }
26
 
27
  /**
31
  * @return array $settings Updated
32
  */
33
  public function account_settings( $settings ) {
34
+ $insert_setting = [
35
+ [
36
  'title' => __( 'Retain Stripe Data', 'woocommerce-gateway-stripe' ),
37
  'desc_tip' => __( 'Retains any Stripe data such as Stripe customer ID, source ID.', 'woocommerce-gateway-stripe' ),
38
  'id' => 'woocommerce_gateway_stripe_retention',
40
  'placeholder' => __( 'N/A', 'woocommerce-gateway-stripe' ),
41
  'default' => '',
42
  'autoload' => false,
43
+ ],
44
+ ];
45
 
46
  $index = null;
47
 
48
+ foreach ( $settings as $key => $value ) {
49
+ if ( 'sectionend' === $value['type'] && 'personal_data_retention' === $value['id'] ) {
50
  $index = $key;
51
  break;
52
  }
62
  /**
63
  * Returns a list of orders that are using one of Stripe's payment methods.
64
  *
65
+ * @param string $email_address
66
+ * @param int $page
67
  *
68
  * @return array WP_Post
69
  */
70
  protected function get_stripe_orders( $email_address, $page ) {
71
  $user = get_user_by( 'email', $email_address ); // Check if user has an ID in the DB to load stored personal data.
72
 
73
+ $order_query = [
74
+ 'payment_method' => [ 'stripe', 'stripe_alipay', 'stripe_bancontact', 'stripe_eps', 'stripe_giropay', 'stripe_ideal', 'stripe_multibanco', 'stripe_p24', 'stripe_sepa', 'stripe_sofort' ],
75
  'limit' => 10,
76
  'page' => $page,
77
+ ];
78
 
79
  if ( $user instanceof WP_User ) {
80
  $order_query['customer_id'] = (int) $user->ID;
87
 
88
  /**
89
  * Gets the message of the privacy to display.
 
90
  */
91
  public function get_privacy_message() {
92
  /* translators: %s URL to docs */
103
  */
104
  public function order_data_exporter( $email_address, $page = 1 ) {
105
  $done = false;
106
+ $data_to_export = [];
107
 
108
  $orders = $this->get_stripe_orders( $email_address, (int) $page );
109
 
111
 
112
  if ( 0 < count( $orders ) ) {
113
  foreach ( $orders as $order ) {
114
+ $data_to_export[] = [
115
  'group_id' => 'woocommerce_orders',
116
  'group_label' => __( 'Orders', 'woocommerce-gateway-stripe' ),
117
  'item_id' => 'order-' . $order->get_id(),
118
+ 'data' => [
119
+ [
120
  'name' => __( 'Stripe payment id', 'woocommerce-gateway-stripe' ),
121
  'value' => get_post_meta( $order->get_id(), '_stripe_source_id', true ),
122
+ ],
123
+ [
124
  'name' => __( 'Stripe customer id', 'woocommerce-gateway-stripe' ),
125
  'value' => get_post_meta( $order->get_id(), '_stripe_customer_id', true ),
126
+ ],
127
+ ],
128
+ ];
129
  }
130
 
131
  $done = 10 > count( $orders );
132
  }
133
 
134
+ return [
135
  'data' => $data_to_export,
136
  'done' => $done,
137
+ ];
138
  }
139
 
140
  /**
148
  public function subscriptions_data_exporter( $email_address, $page = 1 ) {
149
  $done = false;
150
  $page = (int) $page;
151
+ $data_to_export = [];
152
 
153
+ $meta_query = [
154
  'relation' => 'AND',
155
+ [
156
  'key' => '_payment_method',
157
+ 'value' => [ 'stripe', 'stripe_alipay', 'stripe_bancontact', 'stripe_eps', 'stripe_giropay', 'stripe_ideal', 'stripe_multibanco', 'stripe_p24', 'stripe_sepa', 'stripe_sofort' ],
158
  'compare' => 'IN',
159
+ ],
160
+ [
161
  'key' => '_billing_email',
162
  'value' => $email_address,
163
  'compare' => '=',
164
+ ],
165
+ ];
166
 
167
+ $subscription_query = [
168
  'posts_per_page' => 10,
169
  'page' => $page,
170
  'meta_query' => $meta_query,
171
+ ];
172
 
173
  $subscriptions = wcs_get_subscriptions( $subscription_query );
174
 
176
 
177
  if ( 0 < count( $subscriptions ) ) {
178
  foreach ( $subscriptions as $subscription ) {
179
+ $data_to_export[] = [
180
  'group_id' => 'woocommerce_subscriptions',
181
  'group_label' => __( 'Subscriptions', 'woocommerce-gateway-stripe' ),
182
  'item_id' => 'subscription-' . $subscription->get_id(),
183
+ 'data' => [
184
+ [
185
  'name' => __( 'Stripe payment id', 'woocommerce-gateway-stripe' ),
186
  'value' => get_post_meta( $subscription->get_id(), '_stripe_source_id', true ),
187
+ ],
188
+ [
189
  'name' => __( 'Stripe customer id', 'woocommerce-gateway-stripe' ),
190
  'value' => get_post_meta( $subscription->get_id(), '_stripe_customer_id', true ),
191
+ ],
192
+ ],
193
+ ];
194
  }
195
 
196
  $done = 10 > count( $subscriptions );
197
  }
198
 
199
+ return [
200
  'data' => $data_to_export,
201
  'done' => $done,
202
+ ];
203
  }
204
 
205
  /**
211
  */
212
  public function customer_data_exporter( $email_address, $page ) {
213
  $user = get_user_by( 'email', $email_address ); // Check if user has an ID in the DB to load stored personal data.
214
+ $data_to_export = [];
215
 
216
  if ( $user instanceof WP_User ) {
217
  $stripe_user = new WC_Stripe_Customer( $user->ID );
218
 
219
+ $data_to_export[] = [
220
  'group_id' => 'woocommerce_customer',
221
  'group_label' => __( 'Customer Data', 'woocommerce-gateway-stripe' ),
222
  'item_id' => 'user',
223
+ 'data' => [
224
+ [
225
  'name' => __( 'Stripe payment id', 'woocommerce-gateway-stripe' ),
226
  'value' => get_user_option( '_stripe_source_id', $user->ID ),
227
+ ],
228
+ [
229
  'name' => __( 'Stripe customer id', 'woocommerce-gateway-stripe' ),
230
  'value' => $stripe_user->get_id(),
231
+ ],
232
+ ],
233
+ ];
234
  }
235
 
236
+ return [
237
  'data' => $data_to_export,
238
  'done' => true,
239
+ ];
240
  }
241
 
242
  /**
258
  }
259
 
260
  $items_removed = false;
261
+ $messages = [];
262
 
263
  if ( ! empty( $stripe_customer_id ) || ! empty( $stripe_source_id ) ) {
264
  $items_removed = true;
267
  $messages[] = __( 'Stripe User Data Erased.', 'woocommerce-gateway-stripe' );
268
  }
269
 
270
+ return [
271
  'items_removed' => $items_removed,
272
  'items_retained' => false,
273
  'messages' => $messages,
274
  'done' => true,
275
+ ];
276
  }
277
 
278
  /**
287
 
288
  $items_removed = false;
289
  $items_retained = false;
290
+ $messages = [];
291
 
292
  foreach ( (array) $orders as $order ) {
293
  $order = wc_get_order( $order->get_id() );
306
  // Tell core if we have more orders to work on still
307
  $done = count( $orders ) < 10;
308
 
309
+ return [
310
  'items_removed' => $items_removed,
311
  'items_retained' => $items_retained,
312
  'messages' => $messages,
313
  'done' => $done,
314
+ ];
315
  }
316
 
317
  /**
322
  */
323
  protected function maybe_handle_subscription( $order ) {
324
  if ( ! class_exists( 'WC_Subscriptions' ) ) {
325
+ return [ false, false, [] ];
326
  }
327
 
328
  if ( ! wcs_order_contains_subscription( $order ) ) {
329
+ return [ false, false, [] ];
330
  }
331
 
332
  $subscription = current( wcs_get_subscriptions_for_order( $order->get_id() ) );
335
  $stripe_source_id = get_post_meta( $subscription_id, '_stripe_source_id', true );
336
 
337
  if ( empty( $stripe_source_id ) ) {
338
+ return [ false, false, [] ];
339
  }
340
 
341
  if ( ! $this->is_retention_expired( $order->get_date_created()->getTimestamp() ) ) {
342
  /* translators: %d Order ID */
343
+ return [ false, true, [ sprintf( __( 'Order ID %d is less than set retention days. Personal data retained. (Stripe)', 'woocommerce-gateway-stripe' ), $order->get_id() ) ] ];
344
  }
345
 
346
+ if ( $subscription->has_status( apply_filters( 'wc_stripe_privacy_eraser_subs_statuses', [ 'on-hold', 'active' ] ) ) ) {
347
  /* translators: %d Order ID */
348
+ return [ false, true, [ sprintf( __( 'Order ID %d contains an active Subscription. Personal data retained. (Stripe)', 'woocommerce-gateway-stripe' ), $order->get_id() ) ] ];
349
  }
350
 
351
  $renewal_orders = WC_Subscriptions_Renewal_Order::get_renewal_orders( $order->get_id() );
360
  delete_post_meta( $subscription_id, '_stripe_refund_id' );
361
  delete_post_meta( $subscription_id, '_stripe_customer_id' );
362
 
363
+ return [ true, false, [ __( 'Stripe Subscription Data Erased.', 'woocommerce-gateway-stripe' ) ] ];
364
  }
365
 
366
  /**
377
 
378
  if ( ! $this->is_retention_expired( $order->get_date_created()->getTimestamp() ) ) {
379
  /* translators: %d Order ID */
380
+ return [ false, true, [ sprintf( __( 'Order ID %d is less than set retention days. Personal data retained. (Stripe)', 'woocommerce-gateway-stripe' ), $order->get_id() ) ] ];
381
  }
382
 
383
  if ( empty( $stripe_source_id ) && empty( $stripe_refund_id ) && empty( $stripe_customer_id ) ) {
384
+ return [ false, false, [] ];
385
  }
386
 
387
  delete_post_meta( $order_id, '_stripe_source_id' );
388
  delete_post_meta( $order_id, '_stripe_refund_id' );
389
  delete_post_meta( $order_id, '_stripe_customer_id' );
390
 
391
+ return [ true, false, [ __( 'Stripe personal data erased.', 'woocommerce-gateway-stripe' ) ] ];
392
  }
393
 
394
  /**
395
  * Checks if create date is passed retention duration.
 
396
  */
397
  public function is_retention_expired( $created_date ) {
398
  $retention = wc_parse_relative_date_option( get_option( 'woocommerce_gateway_stripe_retention' ) );
includes/admin/stripe-alipay-settings.php CHANGED
@@ -5,45 +5,45 @@ if ( ! defined( 'ABSPATH' ) ) {
5
 
6
  return apply_filters(
7
  'wc_stripe_alipay_settings',
8
- array(
9
- 'geo_target' => array(
10
  'description' => __( 'Customer Geography: China', 'woocommerce-gateway-stripe' ),
11
  'type' => 'title',
12
- ),
13
- 'guide' => array(
14
  'description' => __( '<a href="https://stripe.com/payments/payment-methods-guide#alipay" target="_blank">Payment Method Guide</a>', 'woocommerce-gateway-stripe' ),
15
  'type' => 'title',
16
- ),
17
- 'activation' => array(
18
  'description' => __( 'Must be activated from your Stripe Dashboard Settings <a href="https://dashboard.stripe.com/account/payments/settings" target="_blank">here</a>', 'woocommerce-gateway-stripe' ),
19
  'type' => 'title',
20
- ),
21
- 'enabled' => array(
22
  'title' => __( 'Enable/Disable', 'woocommerce-gateway-stripe' ),
23
  'label' => __( 'Enable Stripe Alipay', 'woocommerce-gateway-stripe' ),
24
  'type' => 'checkbox',
25
  'description' => '',
26
  'default' => 'no',
27
- ),
28
- 'title' => array(
29
  'title' => __( 'Title', 'woocommerce-gateway-stripe' ),
30
  'type' => 'text',
31
  'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce-gateway-stripe' ),
32
  'default' => __( 'Alipay', 'woocommerce-gateway-stripe' ),
33
  'desc_tip' => true,
34
- ),
35
- 'description' => array(
36
  'title' => __( 'Description', 'woocommerce-gateway-stripe' ),
37
  'type' => 'text',
38
  'description' => __( 'This controls the description which the user sees during checkout.', 'woocommerce-gateway-stripe' ),
39
  'default' => __( 'You will be redirected to Alipay.', 'woocommerce-gateway-stripe' ),
40
  'desc_tip' => true,
41
- ),
42
- 'webhook' => array(
43
  'title' => __( 'Webhook Endpoints', 'woocommerce-gateway-stripe' ),
44
  'type' => 'title',
45
  /* translators: webhook URL */
46
  'description' => $this->display_admin_settings_webhook_description(),
47
- ),
48
- )
49
  );
5
 
6
  return apply_filters(
7
  'wc_stripe_alipay_settings',
8
+ [
9
+ 'geo_target' => [
10
  'description' => __( 'Customer Geography: China', 'woocommerce-gateway-stripe' ),
11
  'type' => 'title',
12
+ ],
13
+ 'guide' => [
14
  'description' => __( '<a href="https://stripe.com/payments/payment-methods-guide#alipay" target="_blank">Payment Method Guide</a>', 'woocommerce-gateway-stripe' ),
15
  'type' => 'title',
16
+ ],
17
+ 'activation' => [
18
  'description' => __( 'Must be activated from your Stripe Dashboard Settings <a href="https://dashboard.stripe.com/account/payments/settings" target="_blank">here</a>', 'woocommerce-gateway-stripe' ),
19
  'type' => 'title',
20
+ ],
21
+ 'enabled' => [
22
  'title' => __( 'Enable/Disable', 'woocommerce-gateway-stripe' ),
23
  'label' => __( 'Enable Stripe Alipay', 'woocommerce-gateway-stripe' ),
24
  'type' => 'checkbox',
25
  'description' => '',
26
  'default' => 'no',
27
+ ],
28
+ 'title' => [
29
  'title' => __( 'Title', 'woocommerce-gateway-stripe' ),
30
  'type' => 'text',
31
  'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce-gateway-stripe' ),
32
  'default' => __( 'Alipay', 'woocommerce-gateway-stripe' ),
33
  'desc_tip' => true,
34
+ ],
35
+ 'description' => [
36
  'title' => __( 'Description', 'woocommerce-gateway-stripe' ),
37
  'type' => 'text',
38
  'description' => __( 'This controls the description which the user sees during checkout.', 'woocommerce-gateway-stripe' ),
39
  'default' => __( 'You will be redirected to Alipay.', 'woocommerce-gateway-stripe' ),
40
  'desc_tip' => true,
41
+ ],
42
+ 'webhook' => [
43
  'title' => __( 'Webhook Endpoints', 'woocommerce-gateway-stripe' ),
44
  'type' => 'title',
45
  /* translators: webhook URL */
46
  'description' => $this->display_admin_settings_webhook_description(),
47
+ ],
48
+ ]
49
  );
includes/admin/stripe-bancontact-settings.php CHANGED
@@ -5,45 +5,45 @@ if ( ! defined( 'ABSPATH' ) ) {
5
 
6
  return apply_filters(
7
  'wc_stripe_bancontact_settings',
8
- array(
9
- 'geo_target' => array(
10
  'description' => __( 'Customer Geography: Belgium', 'woocommerce-gateway-stripe' ),
11
  'type' => 'title',
12
- ),
13
- 'guide' => array(
14
  'description' => __( '<a href="https://stripe.com/payments/payment-methods-guide#bancontact" target="_blank">Payment Method Guide</a>', 'woocommerce-gateway-stripe' ),
15
  'type' => 'title',
16
- ),
17
- 'activation' => array(
18
  'description' => __( 'Must be activated from your Stripe Dashboard Settings <a href="https://dashboard.stripe.com/account/payments/settings" target="_blank">here</a>', 'woocommerce-gateway-stripe' ),
19
  'type' => 'title',
20
- ),
21
- 'enabled' => array(
22
  'title' => __( 'Enable/Disable', 'woocommerce-gateway-stripe' ),
23
  'label' => __( 'Enable Stripe Bancontact', 'woocommerce-gateway-stripe' ),
24
  'type' => 'checkbox',
25
  'description' => '',
26
  'default' => 'no',
27
- ),
28
- 'title' => array(
29
  'title' => __( 'Title', 'woocommerce-gateway-stripe' ),
30
  'type' => 'text',
31
  'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce-gateway-stripe' ),
32
  'default' => __( 'Bancontact', 'woocommerce-gateway-stripe' ),
33
  'desc_tip' => true,
34
- ),
35
- 'description' => array(
36
  'title' => __( 'Description', 'woocommerce-gateway-stripe' ),
37
  'type' => 'text',
38
  'description' => __( 'This controls the description which the user sees during checkout.', 'woocommerce-gateway-stripe' ),
39
  'default' => __( 'You will be redirected to Bancontact.', 'woocommerce-gateway-stripe' ),
40
  'desc_tip' => true,
41
- ),
42
- 'webhook' => array(
43
  'title' => __( 'Webhook Endpoints', 'woocommerce-gateway-stripe' ),
44
  'type' => 'title',
45
  /* translators: webhook URL */
46
  'description' => $this->display_admin_settings_webhook_description(),
47
- ),
48
- )
49
  );
5
 
6
  return apply_filters(
7
  'wc_stripe_bancontact_settings',
8
+ [
9
+ 'geo_target' => [
10
  'description' => __( 'Customer Geography: Belgium', 'woocommerce-gateway-stripe' ),
11
  'type' => 'title',
12
+ ],
13
+ 'guide' => [
14
  'description' => __( '<a href="https://stripe.com/payments/payment-methods-guide#bancontact" target="_blank">Payment Method Guide</a>', 'woocommerce-gateway-stripe' ),
15
  'type' => 'title',
16
+ ],
17
+ 'activation' => [
18
  'description' => __( 'Must be activated from your Stripe Dashboard Settings <a href="https://dashboard.stripe.com/account/payments/settings" target="_blank">here</a>', 'woocommerce-gateway-stripe' ),
19
  'type' => 'title',
20
+ ],
21
+ 'enabled' => [
22
  'title' => __( 'Enable/Disable', 'woocommerce-gateway-stripe' ),
23
  'label' => __( 'Enable Stripe Bancontact', 'woocommerce-gateway-stripe' ),
24
  'type' => 'checkbox',
25
  'description' => '',
26
  'default' => 'no',
27
+ ],
28
+ 'title' => [
29
  'title' => __( 'Title', 'woocommerce-gateway-stripe' ),
30
  'type' => 'text',
31
  'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce-gateway-stripe' ),
32
  'default' => __( 'Bancontact', 'woocommerce-gateway-stripe' ),
33
  'desc_tip' => true,
34
+ ],
35
+ 'description' => [
36
  'title' => __( 'Description', 'woocommerce-gateway-stripe' ),
37
  'type' => 'text',
38
  'description' => __( 'This controls the description which the user sees during checkout.', 'woocommerce-gateway-stripe' ),
39
  'default' => __( 'You will be redirected to Bancontact.', 'woocommerce-gateway-stripe' ),
40
  'desc_tip' => true,
41
+ ],
42
+ 'webhook' => [
43
  'title' => __( 'Webhook Endpoints', 'woocommerce-gateway-stripe' ),
44
  'type' => 'title',
45
  /* translators: webhook URL */
46
  'description' => $this->display_admin_settings_webhook_description(),
47
+ ],
48
+ ]
49
  );
includes/admin/stripe-eps-settings.php CHANGED
@@ -5,41 +5,41 @@ if ( ! defined( 'ABSPATH' ) ) {
5
 
6
  return apply_filters(
7
  'wc_stripe_eps_settings',
8
- array(
9
- 'geo_target' => array(
10
  'description' => __( 'Customer Geography: Austria', 'woocommerce-gateway-stripe' ),
11
  'type' => 'title',
12
- ),
13
- 'activation' => array(
14
  'description' => __( 'Must be activated from your Stripe Dashboard Settings <a href="https://dashboard.stripe.com/account/payments/settings" target="_blank">here</a>', 'woocommerce-gateway-stripe' ),
15
  'type' => 'title',
16
- ),
17
- 'enabled' => array(
18
  'title' => __( 'Enable/Disable', 'woocommerce-gateway-stripe' ),
19
  'label' => __( 'Enable Stripe EPS', 'woocommerce-gateway-stripe' ),
20
  'type' => 'checkbox',
21
  'description' => '',
22
  'default' => 'no',
23
- ),
24
- 'title' => array(
25
  'title' => __( 'Title', 'woocommerce-gateway-stripe' ),
26
  'type' => 'text',
27
  'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce-gateway-stripe' ),
28
  'default' => __( 'EPS', 'woocommerce-gateway-stripe' ),
29
  'desc_tip' => true,
30
- ),
31
- 'description' => array(
32
  'title' => __( 'Description', 'woocommerce-gateway-stripe' ),
33
  'type' => 'text',
34
  'description' => __( 'This controls the description which the user sees during checkout.', 'woocommerce-gateway-stripe' ),
35
  'default' => __( 'You will be redirected to EPS.', 'woocommerce-gateway-stripe' ),
36
  'desc_tip' => true,
37
- ),
38
- 'webhook' => array(
39
  'title' => __( 'Webhook Endpoints', 'woocommerce-gateway-stripe' ),
40
  'type' => 'title',
41
  /* translators: webhook URL */
42
  'description' => $this->display_admin_settings_webhook_description(),
43
- ),
44
- )
45
  );
5
 
6
  return apply_filters(
7
  'wc_stripe_eps_settings',
8
+ [
9
+ 'geo_target' => [
10
  'description' => __( 'Customer Geography: Austria', 'woocommerce-gateway-stripe' ),
11
  'type' => 'title',
12
+ ],
13
+ 'activation' => [
14
  'description' => __( 'Must be activated from your Stripe Dashboard Settings <a href="https://dashboard.stripe.com/account/payments/settings" target="_blank">here</a>', 'woocommerce-gateway-stripe' ),
15
  'type' => 'title',
16
+ ],
17
+ 'enabled' => [
18
  'title' => __( 'Enable/Disable', 'woocommerce-gateway-stripe' ),
19
  'label' => __( 'Enable Stripe EPS', 'woocommerce-gateway-stripe' ),
20
  'type' => 'checkbox',
21
  'description' => '',
22
  'default' => 'no',
23
+ ],
24
+ 'title' => [
25
  'title' => __( 'Title', 'woocommerce-gateway-stripe' ),
26
  'type' => 'text',
27
  'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce-gateway-stripe' ),
28
  'default' => __( 'EPS', 'woocommerce-gateway-stripe' ),
29
  'desc_tip' => true,
30
+ ],
31
+ 'description' => [
32
  'title' => __( 'Description', 'woocommerce-gateway-stripe' ),
33
  'type' => 'text',
34
  'description' => __( 'This controls the description which the user sees during checkout.', 'woocommerce-gateway-stripe' ),
35
  'default' => __( 'You will be redirected to EPS.', 'woocommerce-gateway-stripe' ),
36
  'desc_tip' => true,
37
+ ],
38
+ 'webhook' => [
39
  'title' => __( 'Webhook Endpoints', 'woocommerce-gateway-stripe' ),
40
  'type' => 'title',
41
  /* translators: webhook URL */
42
  'description' => $this->display_admin_settings_webhook_description(),
43
+ ],
44
+ ]
45
  );
includes/admin/stripe-giropay-settings.php CHANGED
@@ -5,45 +5,45 @@ if ( ! defined( 'ABSPATH' ) ) {
5
 
6
  return apply_filters(
7
  'wc_stripe_giropay_settings',
8
- array(
9
- 'geo_target' => array(
10
  'description' => __( 'Customer Geography: Germany', 'woocommerce-gateway-stripe' ),
11
  'type' => 'title',
12
- ),
13
- 'guide' => array(
14
  'description' => __( '<a href="https://stripe.com/payments/payment-methods-guide#giropay" target="_blank">Payment Method Guide</a>', 'woocommerce-gateway-stripe' ),
15
  'type' => 'title',
16
- ),
17
- 'activation' => array(
18
  'description' => __( 'Must be activated from your Stripe Dashboard Settings <a href="https://dashboard.stripe.com/account/payments/settings" target="_blank">here</a>', 'woocommerce-gateway-stripe' ),
19
  'type' => 'title',
20
- ),
21
- 'enabled' => array(
22
  'title' => __( 'Enable/Disable', 'woocommerce-gateway-stripe' ),
23
  'label' => __( 'Enable Stripe Giropay', 'woocommerce-gateway-stripe' ),
24
  'type' => 'checkbox',
25
  'description' => '',
26
  'default' => 'no',
27
- ),
28
- 'title' => array(
29
  'title' => __( 'Title', 'woocommerce-gateway-stripe' ),
30
  'type' => 'text',
31
  'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce-gateway-stripe' ),
32
  'default' => __( 'Giropay', 'woocommerce-gateway-stripe' ),
33
  'desc_tip' => true,
34
- ),
35
- 'description' => array(
36
  'title' => __( 'Description', 'woocommerce-gateway-stripe' ),
37
  'type' => 'text',
38
  'description' => __( 'This controls the description which the user sees during checkout.', 'woocommerce-gateway-stripe' ),
39
  'default' => __( 'You will be redirected to Giropay.', 'woocommerce-gateway-stripe' ),
40
  'desc_tip' => true,
41
- ),
42
- 'webhook' => array(
43
  'title' => __( 'Webhook Endpoints', 'woocommerce-gateway-stripe' ),
44
  'type' => 'title',
45
  /* translators: webhook URL */
46
  'description' => $this->display_admin_settings_webhook_description(),
47
- ),
48
- )
49
  );
5
 
6
  return apply_filters(
7
  'wc_stripe_giropay_settings',
8
+ [
9
+ 'geo_target' => [
10
  'description' => __( 'Customer Geography: Germany', 'woocommerce-gateway-stripe' ),
11
  'type' => 'title',
12
+ ],
13
+ 'guide' => [
14
  'description' => __( '<a href="https://stripe.com/payments/payment-methods-guide#giropay" target="_blank">Payment Method Guide</a>', 'woocommerce-gateway-stripe' ),
15
  'type' => 'title',
16
+ ],
17
+ 'activation' => [
18
  'description' => __( 'Must be activated from your Stripe Dashboard Settings <a href="https://dashboard.stripe.com/account/payments/settings" target="_blank">here</a>', 'woocommerce-gateway-stripe' ),
19
  'type' => 'title',
20
+ ],
21
+ 'enabled' => [
22
  'title' => __( 'Enable/Disable', 'woocommerce-gateway-stripe' ),
23
  'label' => __( 'Enable Stripe Giropay', 'woocommerce-gateway-stripe' ),
24
  'type' => 'checkbox',
25
  'description' => '',
26
  'default' => 'no',
27
+ ],
28
+ 'title' => [
29
  'title' => __( 'Title', 'woocommerce-gateway-stripe' ),
30
  'type' => 'text',
31
  'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce-gateway-stripe' ),
32
  'default' => __( 'Giropay', 'woocommerce-gateway-stripe' ),
33
  'desc_tip' => true,
34
+ ],
35
+ 'description' => [
36
  'title' => __( 'Description', 'woocommerce-gateway-stripe' ),
37
  'type' => 'text',
38
  'description' => __( 'This controls the description which the user sees during checkout.', 'woocommerce-gateway-stripe' ),
39
  'default' => __( 'You will be redirected to Giropay.', 'woocommerce-gateway-stripe' ),
40
  'desc_tip' => true,
41
+ ],
42
+ 'webhook' => [
43
  'title' => __( 'Webhook Endpoints', 'woocommerce-gateway-stripe' ),
44
  'type' => 'title',
45
  /* translators: webhook URL */
46
  'description' => $this->display_admin_settings_webhook_description(),
47
+ ],
48
+ ]
49
  );
includes/admin/stripe-ideal-settings.php CHANGED
@@ -5,45 +5,45 @@ if ( ! defined( 'ABSPATH' ) ) {
5
 
6
  return apply_filters(
7
  'wc_stripe_ideal_settings',
8
- array(
9
- 'geo_target' => array(
10
  'description' => __( 'Customer Geography: The Netherlands', 'woocommerce-gateway-stripe' ),
11
  'type' => 'title',
12
- ),
13
- 'guide' => array(
14
  'description' => __( '<a href="https://stripe.com/payments/payment-methods-guide#ideal" target="_blank">Payment Method Guide</a>', 'woocommerce-gateway-stripe' ),
15
  'type' => 'title',
16
- ),
17
- 'activation' => array(
18
  'description' => __( 'Must be activated from your Stripe Dashboard Settings <a href="https://dashboard.stripe.com/account/payments/settings" target="_blank">here</a>', 'woocommerce-gateway-stripe' ),
19
  'type' => 'title',
20
- ),
21
- 'enabled' => array(
22
  'title' => __( 'Enable/Disable', 'woocommerce-gateway-stripe' ),
23
  'label' => __( 'Enable Stripe iDeal', 'woocommerce-gateway-stripe' ),
24
  'type' => 'checkbox',
25
  'description' => '',
26
  'default' => 'no',
27
- ),
28
- 'title' => array(
29
  'title' => __( 'Title', 'woocommerce-gateway-stripe' ),
30
  'type' => 'text',
31
  'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce-gateway-stripe' ),
32
  'default' => __( 'iDeal', 'woocommerce-gateway-stripe' ),
33
  'desc_tip' => true,
34
- ),
35
- 'description' => array(
36
  'title' => __( 'Description', 'woocommerce-gateway-stripe' ),
37
  'type' => 'text',
38
  'description' => __( 'This controls the description which the user sees during checkout.', 'woocommerce-gateway-stripe' ),
39
  'default' => __( 'You will be redirected to iDeal.', 'woocommerce-gateway-stripe' ),
40
  'desc_tip' => true,
41
- ),
42
- 'webhook' => array(
43
  'title' => __( 'Webhook Endpoints', 'woocommerce-gateway-stripe' ),
44
  'type' => 'title',
45
  /* translators: webhook URL */
46
  'description' => $this->display_admin_settings_webhook_description(),
47
- ),
48
- )
49
  );
5
 
6
  return apply_filters(
7
  'wc_stripe_ideal_settings',
8
+ [
9
+ 'geo_target' => [
10
  'description' => __( 'Customer Geography: The Netherlands', 'woocommerce-gateway-stripe' ),
11
  'type' => 'title',
12
+ ],
13
+ 'guide' => [
14
  'description' => __( '<a href="https://stripe.com/payments/payment-methods-guide#ideal" target="_blank">Payment Method Guide</a>', 'woocommerce-gateway-stripe' ),
15
  'type' => 'title',
16
+ ],
17
+ 'activation' => [
18
  'description' => __( 'Must be activated from your Stripe Dashboard Settings <a href="https://dashboard.stripe.com/account/payments/settings" target="_blank">here</a>', 'woocommerce-gateway-stripe' ),
19
  'type' => 'title',
20
+ ],
21
+ 'enabled' => [
22
  'title' => __( 'Enable/Disable', 'woocommerce-gateway-stripe' ),
23
  'label' => __( 'Enable Stripe iDeal', 'woocommerce-gateway-stripe' ),
24
  'type' => 'checkbox',
25
  'description' => '',
26
  'default' => 'no',
27
+ ],
28
+ 'title' => [
29
  'title' => __( 'Title', 'woocommerce-gateway-stripe' ),
30
  'type' => 'text',
31
  'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce-gateway-stripe' ),
32
  'default' => __( 'iDeal', 'woocommerce-gateway-stripe' ),
33
  'desc_tip' => true,
34
+ ],
35
+ 'description' => [
36
  'title' => __( 'Description', 'woocommerce-gateway-stripe' ),
37
  'type' => 'text',
38
  'description' => __( 'This controls the description which the user sees during checkout.', 'woocommerce-gateway-stripe' ),
39
  'default' => __( 'You will be redirected to iDeal.', 'woocommerce-gateway-stripe' ),
40
  'desc_tip' => true,
41
+ ],
42
+ 'webhook' => [
43
  'title' => __( 'Webhook Endpoints', 'woocommerce-gateway-stripe' ),
44
  'type' => 'title',
45
  /* translators: webhook URL */
46
  'description' => $this->display_admin_settings_webhook_description(),
47
+ ],
48
+ ]
49
  );
includes/admin/stripe-multibanco-settings.php CHANGED
@@ -5,41 +5,41 @@ if ( ! defined( 'ABSPATH' ) ) {
5
 
6
  return apply_filters(
7
  'wc_stripe_multibanco_settings',
8
- array(
9
- 'geo_target' => array(
10
  'description' => __( 'Customer Geography: Portugal', 'woocommerce-gateway-stripe' ),
11
  'type' => 'title',
12
- ),
13
- 'activation' => array(
14
  'description' => __( 'Must be activated from your Stripe Dashboard Settings <a href="https://dashboard.stripe.com/account/payments/settings" target="_blank">here</a>', 'woocommerce-gateway-stripe' ),
15
  'type' => 'title',
16
- ),
17
- 'enabled' => array(
18
  'title' => __( 'Enable/Disable', 'woocommerce-gateway-stripe' ),
19
  'label' => __( 'Enable Stripe Multibanco', 'woocommerce-gateway-stripe' ),
20
  'type' => 'checkbox',
21
  'description' => '',
22
  'default' => 'no',
23
- ),
24
- 'title' => array(
25
  'title' => __( 'Title', 'woocommerce-gateway-stripe' ),
26
  'type' => 'text',
27
  'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce-gateway-stripe' ),
28
  'default' => __( 'Multibanco', 'woocommerce-gateway-stripe' ),
29
  'desc_tip' => true,
30
- ),
31
- 'description' => array(
32
  'title' => __( 'Description', 'woocommerce-gateway-stripe' ),
33
  'type' => 'text',
34
  'description' => __( 'This controls the description which the user sees during checkout.', 'woocommerce-gateway-stripe' ),
35
  'default' => __( 'You will be redirected to Multibanco.', 'woocommerce-gateway-stripe' ),
36
  'desc_tip' => true,
37
- ),
38
- 'webhook' => array(
39
  'title' => __( 'Webhook Endpoints', 'woocommerce-gateway-stripe' ),
40
  'type' => 'title',
41
  /* translators: webhook URL */
42
  'description' => $this->display_admin_settings_webhook_description(),
43
- ),
44
- )
45
  );
5
 
6
  return apply_filters(
7
  'wc_stripe_multibanco_settings',
8
+ [
9
+ 'geo_target' => [
10
  'description' => __( 'Customer Geography: Portugal', 'woocommerce-gateway-stripe' ),
11
  'type' => 'title',
12
+ ],
13
+ 'activation' => [
14
  'description' => __( 'Must be activated from your Stripe Dashboard Settings <a href="https://dashboard.stripe.com/account/payments/settings" target="_blank">here</a>', 'woocommerce-gateway-stripe' ),
15
  'type' => 'title',
16
+ ],
17
+ 'enabled' => [
18
  'title' => __( 'Enable/Disable', 'woocommerce-gateway-stripe' ),
19
  'label' => __( 'Enable Stripe Multibanco', 'woocommerce-gateway-stripe' ),
20
  'type' => 'checkbox',
21
  'description' => '',
22
  'default' => 'no',
23
+ ],
24
+ 'title' => [
25
  'title' => __( 'Title', 'woocommerce-gateway-stripe' ),
26
  'type' => 'text',
27
  'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce-gateway-stripe' ),
28
  'default' => __( 'Multibanco', 'woocommerce-gateway-stripe' ),
29
  'desc_tip' => true,
30
+ ],
31
+ 'description' => [
32
  'title' => __( 'Description', 'woocommerce-gateway-stripe' ),
33
  'type' => 'text',
34
  'description' => __( 'This controls the description which the user sees during checkout.', 'woocommerce-gateway-stripe' ),
35
  'default' => __( 'You will be redirected to Multibanco.', 'woocommerce-gateway-stripe' ),
36
  'desc_tip' => true,
37
+ ],
38
+ 'webhook' => [
39
  'title' => __( 'Webhook Endpoints', 'woocommerce-gateway-stripe' ),
40
  'type' => 'title',
41
  /* translators: webhook URL */
42
  'description' => $this->display_admin_settings_webhook_description(),
43
+ ],
44
+ ]
45
  );
includes/admin/stripe-p24-settings.php CHANGED
@@ -5,41 +5,41 @@ if ( ! defined( 'ABSPATH' ) ) {
5
 
6
  return apply_filters(
7
  'wc_stripe_p24_settings',
8
- array(
9
- 'geo_target' => array(
10
  'description' => __( 'Customer Geography: Poland', 'woocommerce-gateway-stripe' ),
11
  'type' => 'title',
12
- ),
13
- 'activation' => array(
14
  'description' => __( 'Must be activated from your Stripe Dashboard Settings <a href="https://dashboard.stripe.com/account/payments/settings" target="_blank">here</a>', 'woocommerce-gateway-stripe' ),
15
  'type' => 'title',
16
- ),
17
- 'enabled' => array(
18
  'title' => __( 'Enable/Disable', 'woocommerce-gateway-stripe' ),
19
  'label' => __( 'Enable Stripe P24', 'woocommerce-gateway-stripe' ),
20
  'type' => 'checkbox',
21
  'description' => '',
22
  'default' => 'no',
23
- ),
24
- 'title' => array(
25
  'title' => __( 'Title', 'woocommerce-gateway-stripe' ),
26
  'type' => 'text',
27
  'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce-gateway-stripe' ),
28
  'default' => __( 'Przelewy24 (P24)', 'woocommerce-gateway-stripe' ),
29
  'desc_tip' => true,
30
- ),
31
- 'description' => array(
32
  'title' => __( 'Description', 'woocommerce-gateway-stripe' ),
33
  'type' => 'text',
34
  'description' => __( 'This controls the description which the user sees during checkout.', 'woocommerce-gateway-stripe' ),
35
  'default' => __( 'You will be redirected to P24.', 'woocommerce-gateway-stripe' ),
36
  'desc_tip' => true,
37
- ),
38
- 'webhook' => array(
39
  'title' => __( 'Webhook Endpoints', 'woocommerce-gateway-stripe' ),
40
  'type' => 'title',
41
  /* translators: webhook URL */
42
  'description' => $this->display_admin_settings_webhook_description(),
43
- ),
44
- )
45
  );
5
 
6
  return apply_filters(
7
  'wc_stripe_p24_settings',
8
+ [
9
+ 'geo_target' => [
10
  'description' => __( 'Customer Geography: Poland', 'woocommerce-gateway-stripe' ),
11
  'type' => 'title',
12
+ ],
13
+ 'activation' => [
14
  'description' => __( 'Must be activated from your Stripe Dashboard Settings <a href="https://dashboard.stripe.com/account/payments/settings" target="_blank">here</a>', 'woocommerce-gateway-stripe' ),
15
  'type' => 'title',
16
+ ],
17
+ 'enabled' => [
18
  'title' => __( 'Enable/Disable', 'woocommerce-gateway-stripe' ),
19
  'label' => __( 'Enable Stripe P24', 'woocommerce-gateway-stripe' ),
20
  'type' => 'checkbox',
21
  'description' => '',
22
  'default' => 'no',
23
+ ],
24
+ 'title' => [
25
  'title' => __( 'Title', 'woocommerce-gateway-stripe' ),
26
  'type' => 'text',
27
  'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce-gateway-stripe' ),
28
  'default' => __( 'Przelewy24 (P24)', 'woocommerce-gateway-stripe' ),
29
  'desc_tip' => true,
30
+ ],
31
+ 'description' => [
32
  'title' => __( 'Description', 'woocommerce-gateway-stripe' ),
33
  'type' => 'text',
34
  'description' => __( 'This controls the description which the user sees during checkout.', 'woocommerce-gateway-stripe' ),
35
  'default' => __( 'You will be redirected to P24.', 'woocommerce-gateway-stripe' ),
36
  'desc_tip' => true,
37
+ ],
38
+ 'webhook' => [
39
  'title' => __( 'Webhook Endpoints', 'woocommerce-gateway-stripe' ),
40
  'type' => 'title',
41
  /* translators: webhook URL */
42
  'description' => $this->display_admin_settings_webhook_description(),
43
+ ],
44
+ ]
45
  );
includes/admin/stripe-sepa-settings.php CHANGED
@@ -5,45 +5,45 @@ if ( ! defined( 'ABSPATH' ) ) {
5
 
6
  return apply_filters(
7
  'wc_stripe_sepa_settings',
8
- array(
9
- 'geo_target' => array(
10
  'description' => __( 'Customer Geography: France, Germany, Spain, Belgium, Netherlands, Luxembourg, Italy, Portugal, Austria, Ireland', 'woocommerce-gateway-stripe' ),
11
  'type' => 'title',
12
- ),
13
- 'guide' => array(
14
  'description' => __( '<a href="https://stripe.com/payments/payment-methods-guide#sepa-direct-debit" target="_blank">Payment Method Guide</a>', 'woocommerce-gateway-stripe' ),
15
  'type' => 'title',
16
- ),
17
- 'activation' => array(
18
  'description' => __( 'Must be activated from your Stripe Dashboard Settings <a href="https://dashboard.stripe.com/account/payments/settings" target="_blank">here</a>', 'woocommerce-gateway-stripe' ),
19
  'type' => 'title',
20
- ),
21
- 'enabled' => array(
22
  'title' => __( 'Enable/Disable', 'woocommerce-gateway-stripe' ),
23
  'label' => __( 'Enable Stripe SEPA Direct Debit', 'woocommerce-gateway-stripe' ),
24
  'type' => 'checkbox',
25
  'description' => '',
26
  'default' => 'no',
27
- ),
28
- 'title' => array(
29
  'title' => __( 'Title', 'woocommerce-gateway-stripe' ),
30
  'type' => 'text',
31
  'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce-gateway-stripe' ),
32
  'default' => __( 'SEPA Direct Debit', 'woocommerce-gateway-stripe' ),
33
  'desc_tip' => true,
34
- ),
35
- 'description' => array(
36
  'title' => __( 'Description', 'woocommerce-gateway-stripe' ),
37
  'type' => 'text',
38
  'description' => __( 'This controls the description which the user sees during checkout.', 'woocommerce-gateway-stripe' ),
39
  'default' => __( 'Mandate Information.', 'woocommerce-gateway-stripe' ),
40
  'desc_tip' => true,
41
- ),
42
- 'webhook' => array(
43
  'title' => __( 'Webhook Endpoints', 'woocommerce-gateway-stripe' ),
44
  'type' => 'title',
45
  /* translators: webhook URL */
46
  'description' => $this->display_admin_settings_webhook_description(),
47
- ),
48
- )
49
  );
5
 
6
  return apply_filters(
7
  'wc_stripe_sepa_settings',
8
+ [
9
+ 'geo_target' => [
10
  'description' => __( 'Customer Geography: France, Germany, Spain, Belgium, Netherlands, Luxembourg, Italy, Portugal, Austria, Ireland', 'woocommerce-gateway-stripe' ),
11
  'type' => 'title',
12
+ ],
13
+ 'guide' => [
14
  'description' => __( '<a href="https://stripe.com/payments/payment-methods-guide#sepa-direct-debit" target="_blank">Payment Method Guide</a>', 'woocommerce-gateway-stripe' ),
15
  'type' => 'title',
16
+ ],
17
+ 'activation' => [
18
  'description' => __( 'Must be activated from your Stripe Dashboard Settings <a href="https://dashboard.stripe.com/account/payments/settings" target="_blank">here</a>', 'woocommerce-gateway-stripe' ),
19
  'type' => 'title',
20
+ ],
21
+ 'enabled' => [
22
  'title' => __( 'Enable/Disable', 'woocommerce-gateway-stripe' ),
23
  'label' => __( 'Enable Stripe SEPA Direct Debit', 'woocommerce-gateway-stripe' ),
24
  'type' => 'checkbox',
25
  'description' => '',
26
  'default' => 'no',
27
+ ],
28
+ 'title' => [
29
  'title' => __( 'Title', 'woocommerce-gateway-stripe' ),
30
  'type' => 'text',
31
  'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce-gateway-stripe' ),
32
  'default' => __( 'SEPA Direct Debit', 'woocommerce-gateway-stripe' ),
33
  'desc_tip' => true,
34
+ ],
35
+ 'description' => [
36
  'title' => __( 'Description', 'woocommerce-gateway-stripe' ),
37
  'type' => 'text',
38
  'description' => __( 'This controls the description which the user sees during checkout.', 'woocommerce-gateway-stripe' ),
39
  'default' => __( 'Mandate Information.', 'woocommerce-gateway-stripe' ),
40
  'desc_tip' => true,
41
+ ],
42
+ 'webhook' => [
43
  'title' => __( 'Webhook Endpoints', 'woocommerce-gateway-stripe' ),
44
  'type' => 'title',
45
  /* translators: webhook URL */
46
  'description' => $this->display_admin_settings_webhook_description(),
47
+ ],
48
+ ]
49
  );
includes/admin/stripe-settings.php CHANGED
@@ -5,14 +5,15 @@ if ( ! defined( 'ABSPATH' ) ) {
5
 
6
  if ( woocommerce_gateway_stripe()->connect->is_connected() ) {
7
  $reset_link = add_query_arg(
8
- array(
9
  '_wpnonce' => wp_create_nonce( 'reset_stripe_api_credentials' ),
10
  'reset_stripe_api_credentials' => true,
11
- ),
12
  admin_url( 'admin.php?page=wc-settings&tab=checkout&section=stripe' )
13
  );
14
 
15
  $api_credentials_text = sprintf(
 
16
  __( '%1$sClear all Stripe account keys.%2$s %3$sThis will disable any connection to Stripe.%4$s', 'woocommerce-gateway-stripe' ),
17
  '<a id="wc_stripe_connect_button" href="' . $reset_link . '" class="button button-secondary">',