Skip to content
Merged
Show file tree
Hide file tree
Changes from 81 commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
9109f75
Removing card requirement for OC
wjrosa Aug 11, 2025
27848e1
Merge branch 'develop' into fix/removing-card-requirement-for-oc
wjrosa Aug 11, 2025
6dd474b
Backend changes
wjrosa Aug 11, 2025
fc32555
Merge branch 'fix/removing-card-requirement-for-oc' of https://github…
wjrosa Aug 11, 2025
bfa1738
Backend changes
wjrosa Aug 11, 2025
074f9fb
Changelog and readme entries
wjrosa Aug 11, 2025
73d97f4
Fix tests
wjrosa Aug 11, 2025
a93ecb0
Fix tests
wjrosa Aug 11, 2025
172e0ed
unit test
wjrosa Aug 11, 2025
896e3d0
Merge branch 'develop' into fix/removing-card-requirement-for-oc
wjrosa Aug 11, 2025
e29852a
Fix tests
wjrosa Aug 11, 2025
12c5bba
Fix shortcode checkout methods display
wjrosa Aug 12, 2025
bd021ae
Moving OC card method logic to the new single method class
wjrosa Aug 12, 2025
52464b8
Removing unnecessary condition
wjrosa Aug 12, 2025
4c5faaa
Condition is actually necessary
wjrosa Aug 12, 2025
bb83e47
Merge branch 'fix/removing-card-requirement-for-oc' into dev/moving-o…
wjrosa Aug 12, 2025
0fd565e
Fix shortcode container label
wjrosa Aug 12, 2025
d51e259
Moving some methods
wjrosa Aug 12, 2025
d515862
Additional fixes
wjrosa Aug 12, 2025
bbf9f22
Fix add payment method title
wjrosa Aug 12, 2025
db7a424
Adding specific frontend constant to avoid confusion
wjrosa Aug 12, 2025
cc480ce
Renaming class to OC
wjrosa Aug 12, 2025
35c4062
Improving docs
wjrosa Aug 12, 2025
799c5d6
Merge branch 'develop' into fix/removing-card-requirement-for-oc
wjrosa Aug 13, 2025
d87a919
Removing disabledButChecked prop and related code
wjrosa Aug 13, 2025
51c8994
Removing the required for OC pill and related files
wjrosa Aug 13, 2025
683e94e
Renaming Single to OC
wjrosa Aug 13, 2025
f4ddf11
Fix tests
wjrosa Aug 13, 2025
ba19a5e
Unit test
wjrosa Aug 13, 2025
1e7c5c0
Changelog and readme entries
wjrosa Aug 13, 2025
b3665a8
Merge branch 'develop' into fix/removing-card-requirement-for-oc
wjrosa Aug 14, 2025
55c5fc3
Merge branch 'dev/removing-required-for-oc-pill' into fix/removing-ca…
wjrosa Aug 14, 2025
467aef1
Hide OC container when there are no methods available
wjrosa Aug 14, 2025
f86bdea
Merge branch 'develop' into fix/removing-card-requirement-for-oc
wjrosa Aug 14, 2025
a494227
Merge branch 'fix/removing-card-requirement-for-oc' into dev/moving-o…
wjrosa Aug 14, 2025
954eff8
Merge branch 'develop' into fix/removing-card-requirement-for-oc
wjrosa Aug 14, 2025
79716e2
Merge branch 'develop' into fix/removing-card-requirement-for-oc
wjrosa Aug 14, 2025
44973f1
Fix merge
wjrosa Aug 14, 2025
a1062e9
Fix tests
wjrosa Aug 14, 2025
aecd42a
Merge branch 'develop' into fix/removing-card-requirement-for-oc
wjrosa Aug 14, 2025
e7e19b4
Merge branch 'fix/removing-card-requirement-for-oc' into dev/moving-o…
wjrosa Aug 14, 2025
fb4c602
Merge branch 'develop' into fix/removing-card-requirement-for-oc
wjrosa Aug 18, 2025
4cdbfac
Fix express methods not available
wjrosa Aug 18, 2025
ac88378
Merge branch 'fix/removing-card-requirement-for-oc' into dev/moving-o…
wjrosa Aug 18, 2025
e1b568d
Removing unnecessary import
wjrosa Aug 18, 2025
b8dcaca
Fix payment method unavailable
wjrosa Aug 18, 2025
eb23e83
Fix payment method unavailable
wjrosa Aug 18, 2025
c0b0db3
Fix method ID
wjrosa Aug 18, 2025
738b9e0
Removing unnecessary changes
wjrosa Aug 18, 2025
8167222
Revert unnecessary changes
wjrosa Aug 18, 2025
a492833
Simplifying logic
wjrosa Aug 18, 2025
d725830
Simplifying logic
wjrosa Aug 18, 2025
792cc4a
Fix payment method title
wjrosa Aug 19, 2025
87c3d2c
Revert unnecessary change
wjrosa Aug 19, 2025
0955ec9
Flagging infinity loop line
wjrosa Aug 19, 2025
b78fd40
Fix infinity loop
wjrosa Aug 19, 2025
099b665
Removing unnecessary constant
wjrosa Aug 19, 2025
712d0ff
Simplifying logic
wjrosa Aug 19, 2025
e61cfeb
Fix instructions
wjrosa Aug 19, 2025
33f4486
Improving readability
wjrosa Aug 19, 2025
d63de45
Improving readability
wjrosa Aug 19, 2025
bd6e5c9
Improving readability
wjrosa Aug 19, 2025
65eb3f1
Merge branch 'develop' into dev/moving-oc-card-method-logic-to-single…
wjrosa Aug 20, 2025
ec23a93
Update changelog.txt
wjrosa Aug 20, 2025
805d633
Changelog and readme entries
wjrosa Aug 20, 2025
26c2911
Merge branch 'develop' into dev/moving-oc-card-method-logic-to-single…
wjrosa Aug 20, 2025
046375f
Merge branch 'develop' into dev/moving-oc-card-method-logic-to-single…
wjrosa Aug 21, 2025
94e164a
Merge branch 'dev/moving-oc-card-method-logic-to-single-method-class'…
wjrosa Aug 21, 2025
ae1cb67
Fix invalid intent log when intent data is missing
wjrosa Aug 21, 2025
ce4817a
Fix selected payment method type
wjrosa Aug 21, 2025
65ba94f
Revert order lock changes
wjrosa Aug 21, 2025
c28b903
Fix methods availability
wjrosa Aug 21, 2025
a1281a0
Merge branch 'develop' into dev/moving-oc-card-method-logic-to-single…
wjrosa Aug 22, 2025
be6a48c
Update includes/class-wc-stripe-helper.php
wjrosa Aug 25, 2025
f95015e
Removing unnecessary LPM_GATEWAY_CLASS constnat
wjrosa Aug 25, 2025
bf66fb1
Update doc blocks
wjrosa Aug 25, 2025
0b78567
Merge branch 'develop' into dev/moving-oc-card-method-logic-to-single…
wjrosa Aug 25, 2025
7feb8d9
Fix methods availability at the shortcode checkout
wjrosa Aug 25, 2025
2624188
Merge branch 'dev/moving-oc-card-method-logic-to-single-method-class'…
wjrosa Aug 25, 2025
4d60f51
Fix ECE methods title
wjrosa Aug 25, 2025
11c628a
Fix payment intent amount comparison
wjrosa Aug 25, 2025
fa4bee1
Fix Link availability in the block checkout
wjrosa Aug 26, 2025
3c5f37d
UI update
wjrosa Aug 26, 2025
f58a3fe
Adding call to parent is_available method
wjrosa Aug 26, 2025
6b129cc
Fix tests
wjrosa Aug 26, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
*** Changelog ***

= 9.9.0 - xxxx-xx-xx =
* Dev - Extracts Optimized Checkout logic from card payment method into new WC_Stripe_UPE_Payment_Method_OC class
* Fix - The availability of the Link payment method when the Optimized Checkout is enabled
* Dev - Update Javascript unit tests for compatibility with Node 20
* Dev - Replaces some payment method instantiation logic for the Optimized Checkout with calls to the `get_payment_method_instance` method
Expand Down
12 changes: 7 additions & 5 deletions includes/class-wc-stripe-helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -1949,11 +1949,13 @@ public static function validate_intent_for_order( $order, $intent, ?string $sele
$order_currency = strtolower( $order->get_currency() );
$order_amount = WC_Stripe_Helper::get_stripe_amount( $order->get_total(), $order->get_currency() );
$order_intent_id = self::get_intent_id_from_order( $order );
$intent_currency = isset( $intent->currency ) ? strtolower( $intent->currency ) : null;
$intent_amount = isset( $intent->amount ) ? (int) $intent->amount : null;

if ( 'payment_intent' === $intent->object ) {
$is_valid = $order_currency === $intent->currency
$is_valid = $order_currency === $intent_currency
&& $is_valid_payment_type
&& $order_amount === $intent->amount
&& $order_amount === $intent_amount
&& ( ! $order_intent_id || $order_intent_id === $intent->id );
} else {
// Setup intents don't have an amount or currency.
Expand All @@ -1968,12 +1970,12 @@ public static function validate_intent_for_order( $order, $intent, ?string $sele

$permitted_payment_types = implode( '/', $intent->payment_method_types );
WC_Stripe_Logger::critical(
"Error: Invalid payment intent for order. Intent: {$intent->currency} {$intent->amount} via {$permitted_payment_types}, Order: {$order_currency} {$order_amount} {$selected_payment_type}",
"Error: Invalid payment intent for order. Intent: {$intent_currency} {$intent_amount} via {$permitted_payment_types}, Order: {$order_currency} {$order_amount} {$selected_payment_type}",
[
'order_id' => $order->get_id(),
'intent_id' => $intent->id,
'intent_currency' => $intent->currency,
'intent_amount' => $intent->amount,
'intent_currency' => $intent_currency,
'intent_amount' => $intent_amount,
'intent_payment_method_types' => $intent->payment_method_types,
'selected_payment_type' => $selected_payment_type,
'order_currency' => $order->get_currency(),
Expand Down
1 change: 1 addition & 0 deletions includes/class-wc-stripe.php
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ public function init() {
require_once WC_STRIPE_PLUGIN_PATH . '/includes/payment-methods/class-wc-stripe-upe-payment-method-wechat-pay.php';
require_once WC_STRIPE_PLUGIN_PATH . '/includes/payment-methods/class-wc-stripe-upe-payment-method-acss.php';
require_once WC_STRIPE_PLUGIN_PATH . '/includes/payment-methods/class-wc-stripe-upe-payment-method-amazon-pay.php';
require_once WC_STRIPE_PLUGIN_PATH . '/includes/payment-methods/class-wc-stripe-upe-payment-method-oc.php';
require_once WC_STRIPE_PLUGIN_PATH . '/includes/payment-methods/class-wc-gateway-stripe-bancontact.php';
require_once WC_STRIPE_PLUGIN_PATH . '/includes/payment-methods/class-wc-gateway-stripe-sofort.php';
require_once WC_STRIPE_PLUGIN_PATH . '/includes/payment-methods/class-wc-gateway-stripe-giropay.php';
Expand Down
1 change: 1 addition & 0 deletions includes/constants/class-wc-stripe-payment-methods.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class WC_Stripe_Payment_Methods {
const SEPA_DEBIT = 'sepa_debit';
const SOFORT = 'sofort';
const WECHAT_PAY = 'wechat_pay';
const OC = 'card'; // This is a special case for the Optimized Checkout
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: To avoid any ambiguity, should we set this to its own ID (eg: oc_container) and then map it to card where frontend/Stripe expects it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried that, but it caused a lot of bugs (tried it again now and still couldn't do it). We still need some stuff from the card payment method class (even when inactive). That was the way I could make it as independent as possible. We can revisit this later


// Express method constants
const AMAZON_PAY = 'amazon_pay';
Expand Down
50 changes: 30 additions & 20 deletions includes/payment-methods/class-wc-stripe-upe-payment-gateway.php
Original file line number Diff line number Diff line change
Expand Up @@ -614,19 +614,23 @@ private function get_enabled_payment_method_config() {
$settings = [];

$enabled_payment_methods = $this->get_upe_enabled_at_checkout_payment_method_ids();
$original_method_ids = $enabled_payment_methods; // For OC, keep the original methods to control availability
$payment_methods = $this->payment_methods;

// If the Optimized Checkout is enabled, we need to return just the card payment method + express methods.
// All payment methods are rendered inside the card container.
if ( $this->oc_enabled ) {
$oc_method_id = WC_Stripe_UPE_Payment_Method_OC::STRIPE_ID;
$enabled_express_methods = array_intersect(
$enabled_payment_methods,
WC_Stripe_Payment_Methods::EXPRESS_PAYMENT_METHODS
);
$enabled_payment_methods = array_merge( [ WC_Stripe_UPE_Payment_Method_CC::STRIPE_ID ], $enabled_express_methods );
$enabled_payment_methods = array_merge( [ $oc_method_id ], $enabled_express_methods );
$payment_methods[ $oc_method_id ] = new WC_Stripe_UPE_Payment_Method_OC();
}

foreach ( $enabled_payment_methods as $payment_method_id ) {
$payment_method = $this->payment_methods[ $payment_method_id ];
$payment_method = $payment_methods[ $payment_method_id ];

$settings[ $payment_method_id ] = [
'isReusable' => $payment_method->is_reusable(),
Expand All @@ -636,7 +640,7 @@ private function get_enabled_payment_method_config() {
'showSaveOption' => $this->should_upe_payment_method_show_save_option( $payment_method ),
'supportsDeferredIntent' => $payment_method->supports_deferred_intent(),
'countries' => $payment_method->get_available_billing_countries(),
'enabledPaymentMethods' => $this->get_upe_enabled_payment_method_ids(), // For the Optimized Checkout.
'enabledPaymentMethods' => $original_method_ids,
];
}

Expand Down Expand Up @@ -2030,19 +2034,26 @@ public function is_oc_enabled() {
* @version 5.5.0
*/
public function set_payment_method_title_for_order( $order, $payment_method_type, $stripe_payment_method = false ) {
if ( ! isset( $this->payment_methods[ $payment_method_type ] ) ) {
$payment_methods = $this->payment_methods;

// Override the payment method type if the Optimized Checkout is enabled.
if ( $this->oc_enabled && WC_Stripe_Payment_Methods::OC === $payment_method_type ) {
$payment_methods[ WC_Stripe_Payment_Methods::OC ] = new WC_Stripe_UPE_Payment_Method_OC();
}

if ( ! isset( $payment_methods[ $payment_method_type ] ) ) {
return;
}

$payment_method = $this->payment_methods[ $payment_method_type ];
$payment_method = $payment_methods[ $payment_method_type ];
$payment_method_id = $payment_method instanceof WC_Stripe_UPE_Payment_Method_CC ? $this->id : $payment_method->id;
$is_stripe_link = WC_Stripe_Payment_Methods::LINK === $payment_method_type ||
( isset( $stripe_payment_method->type ) && WC_Stripe_Payment_Methods::LINK === $stripe_payment_method->type );

// Stripe Link uses the main gateway to process payments, however Link payments should use the title of the Link payment method.
if ( $is_stripe_link && isset( $this->payment_methods[ WC_Stripe_Payment_Methods::LINK ] ) ) {
if ( $is_stripe_link && isset( $payment_methods[ WC_Stripe_Payment_Methods::LINK ] ) ) {
$payment_method_id = $this->id;
$payment_method_title = $this->payment_methods[ WC_Stripe_Payment_Methods::LINK ]->get_title( $stripe_payment_method );
$payment_method_title = $payment_methods[ WC_Stripe_Payment_Methods::LINK ]->get_title( $stripe_payment_method );
} else {
$payment_method_title = $payment_method->get_title( $stripe_payment_method );
}
Expand Down Expand Up @@ -2485,12 +2496,17 @@ protected function prepare_payment_information_from_request( WC_Order $order ) {

$payment_method_details = ! empty( $payment_method_id ) ? WC_Stripe_API::get_payment_method( $payment_method_id ) : (object) [];

$payment_method_types = $this->get_payment_method_types_for_intent_creation(
$selected_payment_type,
$order->get_id(),
$this->get_express_payment_type_from_request(),
( $payment_method_details->type ?? null )
);
// Override the payment method type with the API value when OC is enabled
if ( $this->oc_enabled ) {
$selected_payment_type = $payment_method_details->type ?? null;
$payment_method_types = [ $selected_payment_type ];
} else {
$payment_method_types = $this->get_payment_method_types_for_intent_creation(
$selected_payment_type,
$order->get_id(),
$this->get_express_payment_type_from_request()
);
}

$payment_information = [
'amount' => $amount,
Expand Down Expand Up @@ -3085,14 +3101,8 @@ private function get_existing_compatible_payment_intent( $order, $payment_method
private function get_payment_method_types_for_intent_creation(
string $selected_payment_type,
int $order_id,
?string $express_payment_type = null,
?string $payment_method_type = null
?string $express_payment_type = null
): array {
// If Single Payment Element is enabled, return only the payment method type.
if ( $this->oc_enabled && ! empty( $payment_method_type ) ) {
return [ $payment_method_type ];
}

// If the shopper didn't select a payment type, return all the enabled ones.
if ( '' === $selected_payment_type ) {
return $this->get_upe_enabled_at_checkout_payment_method_ids( $order_id );
Expand Down
50 changes: 0 additions & 50 deletions includes/payment-methods/class-wc-stripe-upe-payment-method-cc.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,6 @@ public function get_title( $payment_details = false ) {
return $this->get_card_wallet_type_title( $wallet_type );
}

// Optimized checkout
if ( $this->oc_enabled ) {
return $this->get_optimized_checkout_title( $payment_details );
}

// Default
return parent::get_title();
}
Expand Down Expand Up @@ -117,10 +112,6 @@ public function requires_automatic_capture() {
* @return string
*/
public function get_testing_instructions( $show_optimized_checkout_instruction = false ) {
if ( $this->oc_enabled && ! $show_optimized_checkout_instruction ) {
return WC_Stripe_UPE_Payment_Gateway::get_testing_instructions_for_optimized_checkout();
}

return sprintf(
/* translators: 1) HTML strong open tag 2) HTML strong closing tag 3) HTML anchor open tag 2) HTML anchor closing tag */
esc_html__( '%1$sTest mode:%2$s use the test VISA card 4242424242424242 with any expiry date and CVC. Other payment methods may redirect to a Stripe test page to authorize payment. More test card numbers are listed %3$shere%4$s.', 'woocommerce-gateway-stripe' ),
Expand All @@ -130,45 +121,4 @@ public function get_testing_instructions( $show_optimized_checkout_instruction =
'</a>'
);
}

/**
* Returns the title for the card wallet type.
* This is used to display the title for Apple Pay and Google Pay.
*
* @param $express_payment_type string The type of express payment method.
*
* @return string The title for the card wallet type.
*/
private function get_card_wallet_type_title( $express_payment_type ) {
$express_payment_titles = WC_Stripe_Payment_Methods::EXPRESS_METHODS_LABELS;
$payment_method_title = $express_payment_titles[ $express_payment_type ] ?? false;

if ( ! $payment_method_title ) {
return parent::get_title();
}

return $payment_method_title . WC_Stripe_Express_Checkout_Helper::get_payment_method_title_suffix();
}

/**
* Returns the title for the optimized checkout.
*
* @param stdClass|array|bool $payment_details Optional payment details from charge object.
* @return string
*/
private function get_optimized_checkout_title( $payment_details = false ) {
if ( $payment_details ) { // Setting title for the order details page / thank you page.
$payment_method = WC_Stripe_UPE_Payment_Gateway::get_payment_method_instance( $payment_details->type );

// Avoid potential recursion by checking instance type. This fixes the title on pay for order confirmation page.
return $payment_method instanceof self ? parent::get_title() : $payment_method->get_title();
}

// Block checkout and pay for order (checkout) page.
if ( ( has_block( 'woocommerce/checkout' ) || ! empty( $_GET['pay_for_order'] ) ) && ! is_wc_endpoint_url( 'order-received' ) ) { // phpcs:ignore WordPress.Security.NonceVerification
return 'Stripe';
}

return parent::get_title();
}
}
119 changes: 119 additions & 0 deletions includes/payment-methods/class-wc-stripe-upe-payment-method-oc.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}

/**
* Class WC_Stripe_UPE_Payment_Method_OC
*
* This class represents the Stripe UPE payment method for the Optimized Checkout (OC) flow.
*/
class WC_Stripe_UPE_Payment_Method_OC extends WC_Stripe_UPE_Payment_Method {

const STRIPE_ID = WC_Stripe_Payment_Methods::OC;

/**
* Constructor for the Optimized Checkout payment method (which renders all methods).
*/
public function __construct() {
parent::__construct();
$main_settings = WC_Stripe_Helper::get_stripe_settings();
$is_stripe_enabled = ! empty( $main_settings['enabled'] ) && 'yes' === $main_settings['enabled'];

$this->enabled = $is_stripe_enabled && $this->oc_enabled ? 'yes' : 'no';
$this->id = WC_Gateway_Stripe::ID; // Force the ID to be the same as the main payment gateway.
$this->stripe_id = self::STRIPE_ID;
$this->title = 'Stripe';
$this->is_reusable = true;
$this->supports[] = 'subscriptions';
$this->supports[] = 'tokenization';
}

/**
* Returns payment method title
*
* @param stdClass|array|bool $payment_details Optional payment details from charge object.
*
* @return string
*/
public function get_title( $payment_details = false ) {
// Wallet type
$wallet_type = $payment_details->card->wallet->type ?? null;
if ( $wallet_type ) {
return $this->get_card_wallet_type_title( $wallet_type );
}

if ( $payment_details ) { // Setting title for the order details page / thank you page.
$payment_method = WC_Stripe_UPE_Payment_Gateway::get_payment_method_instance( $payment_details->type );

// Avoid potential recursion by checking instance type. This fixes the title on pay for order confirmation page.
return $payment_method instanceof self ? parent::get_title() : $payment_method->get_title();
}

// Block checkout and pay for order (checkout) page.
if ( ( has_block( 'woocommerce/checkout' ) || ! empty( $_GET['pay_for_order'] ) ) && ! is_wc_endpoint_url( 'order-received' ) ) { // phpcs:ignore WordPress.Security.NonceVerification
return 'Stripe';
}

return parent::get_title();
}

/**
* Returns true if the UPE method is available.
*
* @inheritDoc
*/
public function is_available() {
return true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we do something like

Suggested change
return true;
if ( ! parent::is_available() ) return false;
return true;

I see the is_available method in WC_Payment_Gateway (which was in the previous inheritance chain) has some additional checks that might be useful.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. Added it in f58a3fe. I didn't apply your suggestion directly due to linting.

}

/**
* Returns string representing payment method type
* to query to retrieve saved payment methods from Stripe.
*
* @inheritDoc
*/
public function get_retrievable_type() {
return WC_Stripe_UPE_Payment_Method_CC::STRIPE_ID;
}

/**
* Returns boolean dependent on whether capability
* for site account is enabled for payment method.
*
* @inheritDoc
*/
public function is_capability_active() {
return true;
}

/**
* The Optimized Checkout method allows automatic capture.
*
* @inheritDoc
*/
public function requires_automatic_capture() {
return false;
}

/**
* Returns testing credentials to be printed at checkout in test mode.
*
* @param bool $show_optimized_checkout_instruction Whether this is being called through the Optimized Checkout instructions method. Used to avoid an infinite loop call.
* @return string
*/
public function get_testing_instructions( $show_optimized_checkout_instruction = false ) {
if ( ! $show_optimized_checkout_instruction ) {
return WC_Stripe_UPE_Payment_Gateway::get_testing_instructions_for_optimized_checkout();
}

return sprintf(
/* translators: 1) HTML strong open tag 2) HTML strong closing tag 3) HTML anchor open tag 2) HTML anchor closing tag */
esc_html__( '%1$sTest mode:%2$s use the test VISA card 4242424242424242 with any expiry date and CVC. Other payment methods may redirect to a Stripe test page to authorize payment. More test card numbers are listed %3$shere%4$s.', 'woocommerce-gateway-stripe' ),
'<strong>',
'</strong>',
'<a href="https://docs.stripe.com/testing" target="_blank">',
'</a>'
);
}
}
Loading
Loading