diff --git a/changelog.txt b/changelog.txt index d823660e82..a295b65729 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,6 +1,7 @@ *** Changelog *** = 9.9.0 - xxxx-xx-xx = +* Dev - Moves all the Optimized Checkout feature code of the card payment method class to a new, specific class * Fix - Removes the credit card payment method requirement for the Optimized Checkout feature * Fix - Payment method test instructions not showing up for the Optimized Checkout payment element * Add - Includes a new notice to highlight the Optimized Checkout feature above the payment methods list in the Stripe settings page diff --git a/client/stripe-utils/constants.js b/client/stripe-utils/constants.js index 1b19e75670..e32e3da801 100644 --- a/client/stripe-utils/constants.js +++ b/client/stripe-utils/constants.js @@ -54,6 +54,7 @@ export const PAYMENT_METHOD_STRIPE_CASHAPP = 'stripe_cashapp'; export const PAYMENT_METHOD_STRIPE_ACSS = 'stripe_acss_debit'; export const PAYMENT_METHOD_STRIPE_BACS_DEBIT = 'stripe_bacs_debit'; export const PAYMENT_METHOD_STRIPE_BECS = 'stripe_au_becs_debit'; +export const PAYMENT_METHOD_STRIPE_OC = 'stripe'; export function getPaymentMethodsConstants() { return { @@ -79,6 +80,7 @@ export function getPaymentMethodsConstants() { cashapp: PAYMENT_METHOD_STRIPE_CASHAPP, acss_debit: PAYMENT_METHOD_STRIPE_ACSS, bacs_debit: PAYMENT_METHOD_STRIPE_BACS_DEBIT, + oc: PAYMENT_METHOD_STRIPE_OC, // Default payment method for Optimized Checkout }; } diff --git a/includes/class-wc-stripe.php b/includes/class-wc-stripe.php index 1e2037d0d4..83d78da484 100644 --- a/includes/class-wc-stripe.php +++ b/includes/class-wc-stripe.php @@ -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'; diff --git a/includes/constants/class-wc-stripe-payment-methods.php b/includes/constants/class-wc-stripe-payment-methods.php index f2b38e83ad..a42936405a 100644 --- a/includes/constants/class-wc-stripe-payment-methods.php +++ b/includes/constants/class-wc-stripe-payment-methods.php @@ -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 // Express method constants const AMAZON_PAY = 'amazon_pay'; diff --git a/includes/payment-methods/class-wc-stripe-upe-payment-gateway.php b/includes/payment-methods/class-wc-stripe-upe-payment-gateway.php index 672e7f933c..ed9b737d78 100644 --- a/includes/payment-methods/class-wc-stripe-upe-payment-gateway.php +++ b/includes/payment-methods/class-wc-stripe-upe-payment-gateway.php @@ -607,14 +607,14 @@ private function get_enabled_payment_method_config() { $enabled_payment_methods = $this->get_upe_enabled_at_checkout_payment_method_ids(); - // 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 the Optimized Checkout is enabled, we need to return just the OC payment method + express methods. + // All payment methods are rendered inside the OC container. if ( $this->oc_enabled ) { $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( [ WC_Stripe_UPE_Payment_Method_OC::STRIPE_ID ], $enabled_express_methods ); } foreach ( $enabled_payment_methods as $payment_method_id ) { @@ -2040,6 +2040,8 @@ public function set_payment_method_title_for_order( $order, $payment_method_type if ( $is_stripe_link && isset( $this->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 ); + } elseif ( $this->oc_enabled ) { + $payment_method_title = ( new WC_Stripe_UPE_Payment_Method_OC() )->get_title( $stripe_payment_method ); } else { $payment_method_title = $payment_method->get_title( $stripe_payment_method ); } diff --git a/includes/payment-methods/class-wc-stripe-upe-payment-method-cc.php b/includes/payment-methods/class-wc-stripe-upe-payment-method-cc.php index f1fd13df72..8cf68c925a 100644 --- a/includes/payment-methods/class-wc-stripe-upe-payment-method-cc.php +++ b/includes/payment-methods/class-wc-stripe-upe-payment-method-cc.php @@ -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(); } @@ -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' ), @@ -149,26 +140,4 @@ private function get_card_wallet_type_title( $express_payment_type ) { 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(); - } } diff --git a/includes/payment-methods/class-wc-stripe-upe-payment-method-oc.php b/includes/payment-methods/class-wc-stripe-upe-payment-method-oc.php new file mode 100644 index 0000000000..5f2a3bc52d --- /dev/null +++ b/includes/payment-methods/class-wc-stripe-upe-payment-method-oc.php @@ -0,0 +1,115 @@ +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 ) { + 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; + } + + /** + * 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 Credit Card 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' ), + '', + '', + '', + '' + ); + } +} diff --git a/includes/payment-methods/class-wc-stripe-upe-payment-method.php b/includes/payment-methods/class-wc-stripe-upe-payment-method.php index fa650dfd09..d29859b915 100644 --- a/includes/payment-methods/class-wc-stripe-upe-payment-method.php +++ b/includes/payment-methods/class-wc-stripe-upe-payment-method.php @@ -176,8 +176,8 @@ public function get_id() { */ public function is_enabled() { return 'yes' === $this->enabled - // When OC is enabled, we use the card payment container to render all the methods. - || ( $this->oc_enabled && WC_Stripe_Payment_Methods::CARD === $this->stripe_id ); + // When OC is enabled, we use the OC payment container to render all the methods. + || ( $this->oc_enabled && WC_Stripe_Payment_Methods::OC === $this->stripe_id ); } /** @@ -186,9 +186,9 @@ public function is_enabled() { * @return bool */ public function is_available() { - // When OC is enabled, we use the card payment container to render all the methods. + // When OC is enabled, we use the OC payment container to render all the methods. if ( $this->oc_enabled ) { - return WC_Stripe_Payment_Methods::CARD === $this->stripe_id; + return WC_Stripe_Payment_Methods::OC === $this->stripe_id; } if ( is_add_payment_method_page() && ! $this->is_reusable() ) { diff --git a/readme.txt b/readme.txt index b621c8b9c0..1a2694d4aa 100644 --- a/readme.txt +++ b/readme.txt @@ -111,6 +111,7 @@ If you get stuck, you can ask for help in the [Plugin Forum](https://wordpress.o == Changelog == = 9.9.0 - xxxx-xx-xx = +* Dev - Moves all the Optimized Checkout feature code of the card payment method class to a new, specific class * Fix - Removes the credit card payment method requirement for the Optimized Checkout feature * Fix - Payment method test instructions not showing up for the Optimized Checkout payment element * Add - Includes a new notice to highlight the Optimized Checkout feature above the payment methods list in the Stripe settings page diff --git a/tests/phpunit/PaymentMethods/WC_Stripe_UPE_Payment_Gateway_Test.php b/tests/phpunit/PaymentMethods/WC_Stripe_UPE_Payment_Gateway_Test.php index 7501b9a9de..0b80295acd 100644 --- a/tests/phpunit/PaymentMethods/WC_Stripe_UPE_Payment_Gateway_Test.php +++ b/tests/phpunit/PaymentMethods/WC_Stripe_UPE_Payment_Gateway_Test.php @@ -6,7 +6,6 @@ use Exception; use WooCommerce\Stripe\Tests\Helpers\OC_Test_Helper; use WC_Stripe_Database_Cache; -use WC_Stripe_Payment_Method_Configurations; use WooCommerce\Stripe\Tests\Helpers\PMC_Test_Helper; use WooCommerce\Stripe\Tests\Helpers\UPE_Test_Helper; use WC_Data_Exception; diff --git a/tests/phpunit/PaymentMethods/WC_Stripe_UPE_Payment_Method_CC_Test.php b/tests/phpunit/PaymentMethods/WC_Stripe_UPE_Payment_Method_CC_Test.php index 1e3b0e1464..33680afe11 100644 --- a/tests/phpunit/PaymentMethods/WC_Stripe_UPE_Payment_Method_CC_Test.php +++ b/tests/phpunit/PaymentMethods/WC_Stripe_UPE_Payment_Method_CC_Test.php @@ -17,18 +17,13 @@ class WC_Stripe_UPE_Payment_Method_CC_Test extends WP_UnitTestCase { * Tests for `get_title`. * * @param array|bool $payment_details Payment details. - * @param bool $optimized_checkout_setting Optimized Checkout flag. * @param array $query_params Query parameters. * @param string $expected Expected title. * @return void * * @dataProvider provide_test_get_title */ - public function test_get_title( $payment_details, $optimized_checkout_setting, $query_params, $expected ) { - if ( $optimized_checkout_setting ) { - OC_Test_Helper::enable_oc(); - } - + public function test_get_title( $payment_details, $query_params, $expected ) { if ( is_array( $payment_details ) ) { $payment_details = json_decode( wp_json_encode( $payment_details ) ); } @@ -39,9 +34,6 @@ public function test_get_title( $payment_details, $optimized_checkout_setting, $ $payment_method = new WC_Stripe_UPE_Payment_Method_CC(); $actual = $payment_method->get_title( $payment_details ); - // Clean up. - OC_Test_Helper::disable_oc(); - $this->assertEquals( $expected, $actual ); } @@ -52,22 +44,6 @@ public function test_get_title( $payment_details, $optimized_checkout_setting, $ */ public function provide_test_get_title() { return [ - 'optimized checkout, with payment details' => [ - 'payment details' => [ - 'type' => WC_Stripe_Payment_Methods::ALIPAY, - ], - 'optimized checkout flag' => true, - 'query params' => [], - 'expected' => 'Alipay', - ], - 'optimized checkout, block checkout page / pay for order' => [ - 'payment details' => false, - 'optimized checkout flag' => true, - 'query params' => [ - 'pay_for_order' => 'true', - ], - 'expected' => 'Stripe', - ], 'Google Pay' => [ 'payment details' => [ 'card' => [ @@ -76,13 +52,11 @@ public function provide_test_get_title() { ], ], ], - 'optimized checkout flag' => false, 'query params' => [], 'expected' => 'Google Pay (Stripe)', ], 'default, hardcoded' => [ 'payment details' => false, - 'optimized checkout flag' => false, 'query params' => [], 'expected' => 'Credit / Debit Card', ], @@ -92,41 +66,14 @@ public function provide_test_get_title() { /** * Test for `get_testing_instructions`. * - * @param bool $optimized_checkout_setting Optimized Checkout setting. - * @param string $expected Expected instructions. * @return void - * - * @dataProvider provide_test_get_testing_instructions */ - public function test_get_testing_instructions( $optimized_checkout_setting, $expected ) { - if ( $optimized_checkout_setting ) { - OC_Test_Helper::enable_oc(); - } + public function test_get_testing_instructions() { + $expected = 'Test mode: 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 here.'; $payment_method = new WC_Stripe_UPE_Payment_Method_CC(); $actual = $payment_method->get_testing_instructions(); - // Clean up - OC_Test_Helper::disable_oc(); - $this->assertEquals( $expected, $actual ); } - - /** - * Provider for `get_testing_instructions`. - * - * @return array - */ - public function provide_test_get_testing_instructions() { - return [ - 'Optimized Checkout enabled' => [ - 'optimized checkout setting' => true, - 'expected' => '
', - ], - 'Optimized Checkout disabled' => [ - 'optimized checkout setting' => false, - 'expected' => 'Test mode: 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 here.', - ], - ]; - } } diff --git a/tests/phpunit/PaymentMethods/WC_Stripe_UPE_Payment_Method_OC_Test.php b/tests/phpunit/PaymentMethods/WC_Stripe_UPE_Payment_Method_OC_Test.php new file mode 100644 index 0000000000..052b4c822c --- /dev/null +++ b/tests/phpunit/PaymentMethods/WC_Stripe_UPE_Payment_Method_OC_Test.php @@ -0,0 +1,103 @@ +assertSame( 'Stripe', $payment_method->title ); + $this->assertContains( 'subscriptions', $payment_method->supports ); + $this->assertContains( 'tokenization', $payment_method->supports ); + } + + /** + * Tests for `get_title` method. + * + * @return void + * + * @dataProvider provide_test_get_title + */ + public function test_get_title( $payment_details, $query_params, $expected ) { + if ( is_array( $payment_details ) ) { + $payment_details = json_decode( wp_json_encode( $payment_details ) ); + } + if ( ! empty( $query_params ) ) { + $_GET = array_merge( $_GET, $query_params ); + } + + $payment_method = new WC_Stripe_UPE_Payment_Method_OC(); + $actual = $payment_method->get_title( $payment_details ); + + $this->assertEquals( $expected, $actual ); + } + + /** + * Data provider for `test_get_title`. + * + * @return array + */ + public function provide_test_get_title() { + return [ + 'with payment details' => [ + 'payment details' => [ + 'type' => WC_Stripe_Payment_Methods::ALIPAY, + ], + 'query params' => [], + 'expected' => 'Alipay', + ], + 'block checkout page / pay for order' => [ + 'payment details' => false, + 'query params' => [ + 'pay_for_order' => 'true', + ], + 'expected' => 'Stripe', + ], + 'default, hardcoded' => [ + 'payment details' => false, + 'query params' => [], + 'expected' => 'Stripe', + ], + ]; + } + + /** + * Tests for `is_available`, `get_retrievable_type`, `is_capability_active`, and `requires_automatic_capture` methods. + * @return void + */ + public function test_feature_methods() { + $payment_method = new WC_Stripe_UPE_Payment_Method_OC(); + + $this->assertTrue( $payment_method->is_available() ); + $this->assertEquals( WC_Stripe_Payment_Methods::CARD, $payment_method->get_retrievable_type() ); + $this->assertTrue( $payment_method->is_capability_active() ); + $this->assertFalse( $payment_method->requires_automatic_capture() ); + } + + /** + * Test for `get_testing_instructions`. + * + * @return void + */ + public function test_get_testing_instructions() { + $expected = ' '; + + $payment_method = new WC_Stripe_UPE_Payment_Method_OC(); + $actual = $payment_method->get_testing_instructions(); + + $this->assertEquals( $expected, $actual ); + } +}