diff --git a/changelog.txt b/changelog.txt index 1e9c00cc6d..0e4104264f 100644 --- a/changelog.txt +++ b/changelog.txt @@ -13,6 +13,7 @@ * Dev - Removes the `_wcstripe_feature_upe` feature flag and the related method from the `WC_Stripe_Feature_Flags` class * Dev - Fixes some incorrect subscriptions support implementations for payment methods * Fix - Ensure correct express checkout prices in block cart and checkout with non-default decimal configuration +* Fix - Disable express checkout when Amazon Pay is disabled and the only method = 10.1.0 - 2025-11-11 = * Dev - Remove unused `shouldShowPaymentRequestButton` parameter and calculations from backend diff --git a/includes/payment-methods/class-wc-stripe-express-checkout-helper.php b/includes/payment-methods/class-wc-stripe-express-checkout-helper.php index 5de66742d2..ece656f26a 100644 --- a/includes/payment-methods/class-wc-stripe-express-checkout-helper.php +++ b/includes/payment-methods/class-wc-stripe-express-checkout-helper.php @@ -735,6 +735,15 @@ public function should_show_express_checkout_button() { } } + // Check if Amazon Pay is the only enabled method, but not available due to the tax configuration. + if ( $this->is_amazon_pay_enabled() && + ! ( $this->is_payment_request_enabled() || $this->is_link_enabled() ) && + ( wc_tax_enabled() && 'billing' === get_option( 'woocommerce_tax_based_on' ) ) + ) { + WC_Stripe_Logger::debug( 'Stripe Express Checkout is hidden due to Amazon Pay being the only enabled method, but not available due to taxes being based on billing address.' ); + return false; + } + // Hide if cart/product doesn't require shipping and tax is based on billing or shipping address. $hide_based_on_tax = $this->should_hide_ece_based_on_tax_setup(); $hide_based_on_tax_filtered = apply_filters( 'wc_stripe_should_hide_express_checkout_button_based_on_tax_setup', $hide_based_on_tax ); diff --git a/readme.txt b/readme.txt index 9db615814d..4c44db335f 100644 --- a/readme.txt +++ b/readme.txt @@ -123,5 +123,6 @@ If you get stuck, you can ask for help in the [Plugin Forum](https://wordpress.o * Dev - Removes the `_wcstripe_feature_upe` feature flag and the related method from the `WC_Stripe_Feature_Flags` class * Dev - Fixes some incorrect subscriptions support implementations for payment methods * Fix - Ensure correct express checkout prices in block cart and checkout with non-default decimal configuration +* Fix - Disable express checkout when Amazon Pay is disabled and the only method [See changelog for full details across versions](https://raw.githubusercontent.com/woocommerce/woocommerce-gateway-stripe/trunk/changelog.txt). diff --git a/tests/phpunit/PaymentMethods/WC_Stripe_Express_Checkout_Helper_Test.php b/tests/phpunit/PaymentMethods/WC_Stripe_Express_Checkout_Helper_Test.php index a8ed0fbd09..c3ada66857 100644 --- a/tests/phpunit/PaymentMethods/WC_Stripe_Express_Checkout_Helper_Test.php +++ b/tests/phpunit/PaymentMethods/WC_Stripe_Express_Checkout_Helper_Test.php @@ -44,6 +44,9 @@ public function tear_down() { $this->shipping_zone->delete(); } + delete_option( 'woocommerce_calc_taxes' ); + delete_option( 'woocommerce_tax_based_on' ); + parent::tear_down(); } @@ -100,16 +103,10 @@ function () use ( $filter_value ) { remove_filter( 'wc_stripe_should_hide_express_checkout_button_based_on_tax_setup', '__return_true' ); } - $wc_stripe_ece_helper_mock = $this->createPartialMock( - WC_Stripe_Express_Checkout_Helper::class, - [ - 'is_product', - 'allowed_items_in_cart', - 'should_show_ece_on_cart_page', - 'should_show_ece_on_checkout_page', - ], - [ $gateway ] - ); + $wc_stripe_ece_helper_mock = $this->getMockBuilder( WC_Stripe_Express_Checkout_Helper::class ) + ->onlyMethods( [ 'is_product', 'allowed_items_in_cart', 'should_show_ece_on_cart_page', 'should_show_ece_on_checkout_page' ] ) + ->setConstructorArgs( [ $gateway ] ) + ->getMock(); $wc_stripe_ece_helper_mock->method( 'is_product' )->willReturn( false ); $wc_stripe_ece_helper_mock->method( 'allowed_items_in_cart' )->willReturn( true ); @@ -271,16 +268,11 @@ public function test_hides_ece_if_stripe_gateway_unavailable() { ->disableOriginalConstructor() ->getMock(); - $wc_stripe_ece_helper_mock = $this->createPartialMock( - WC_Stripe_Express_Checkout_Helper::class, - [ - 'is_product', - 'allowed_items_in_cart', - 'should_show_ece_on_cart_page', - 'should_show_ece_on_checkout_page', - ], - [ $gateway ] - ); + $wc_stripe_ece_helper_mock = $this->getMockBuilder( WC_Stripe_Express_Checkout_Helper::class ) + ->setConstructorArgs( [ $gateway ] ) + ->onlyMethods( [ 'is_product', 'allowed_items_in_cart', 'should_show_ece_on_cart_page', 'should_show_ece_on_checkout_page' ] ) + ->getMock(); + $wc_stripe_ece_helper_mock->method( 'is_product' )->willReturn( false ); $wc_stripe_ece_helper_mock->method( 'allowed_items_in_cart' )->willReturn( true ); $wc_stripe_ece_helper_mock->method( 'should_show_ece_on_cart_page' )->willReturn( true ); @@ -325,16 +317,14 @@ public function test_hides_ece_if_stripe_gateway_unavailable() { public function test_hides_ece_if_free_trial_requires_shipping() { $this->set_up_shipping_methods(); - $wc_stripe_ece_helper_mock = $this->createPartialMock( - WC_Stripe_Express_Checkout_Helper::class, - [ - 'is_product', - 'get_product', - 'allowed_items_in_cart', - 'should_show_ece_on_cart_page', - 'should_show_ece_on_checkout_page', - ], - ); + $mock_gateway = $this->getMockBuilder( WC_Stripe_UPE_Payment_Gateway::class ) + ->disableOriginalConstructor() + ->getMock(); + + $wc_stripe_ece_helper_mock = $this->getMockBuilder( WC_Stripe_Express_Checkout_Helper::class ) + ->setConstructorArgs( [ $mock_gateway ] ) + ->onlyMethods( [ 'is_product', 'get_product', 'allowed_items_in_cart', 'should_show_ece_on_cart_page', 'should_show_ece_on_checkout_page' ] ) + ->getMock(); $wc_stripe_ece_helper_mock->method( 'is_product' )->willReturn( true ); $wc_stripe_ece_helper_mock->method( 'allowed_items_in_cart' )->willReturn( true ); @@ -1105,17 +1095,10 @@ public function test_opc_detection_logic( $is_opc, $button_locations, $expected ->disableOriginalConstructor() ->getMock(); - $wc_stripe_ece_helper_mock = $this->createPartialMock( - WC_Stripe_Express_Checkout_Helper::class, - [ - 'is_one_page_checkout', - 'is_product', - 'is_checkout', - 'allowed_items_in_cart', - 'get_product', - ], - [ $gateway ] - ); + $wc_stripe_ece_helper_mock = $this->getMockBuilder( WC_Stripe_Express_Checkout_Helper::class ) + ->setConstructorArgs( [ $gateway ] ) + ->onlyMethods( [ 'is_one_page_checkout', 'is_product', 'is_checkout', 'allowed_items_in_cart', 'get_product' ] ) + ->getMock(); // Create a mock product. $product = WC_Helper_Product::create_simple_product(); @@ -1160,4 +1143,53 @@ public function provide_opc_detection_scenarios() { 'OPC with both enabled' => [ true, [ 'checkout', 'product' ], true ], ]; } + + /** + * Test that the express checkout button is shown or hidden when Amazon Pay is the only enabled method. + * + * @param bool $taxes_enabled Whether taxes are enabled. + * @param string $tax_based_on The tax based on option. + * @param bool $expected Expected result. + * @return void + * @dataProvider provide_test_should_show_express_checkout_button_with_amazon_pay_only + */ + public function test_should_show_express_checkout_button_with_amazon_pay_only( bool $taxes_enabled, string $tax_based_on, bool $expected ): void { + update_option( 'woocommerce_calc_taxes', $taxes_enabled ? 'yes' : 'no' ); + update_option( 'woocommerce_tax_based_on', $tax_based_on ); + + $helper = $this->getMockBuilder( WC_Stripe_Express_Checkout_Helper::class ) + ->onlyMethods( [ 'is_amazon_pay_enabled', 'is_payment_request_enabled', 'is_link_enabled' ] ) + ->getMock(); + + $helper->method( 'is_amazon_pay_enabled' )->willReturn( true ); + $helper->method( 'is_payment_request_enabled' )->willReturn( false ); + $helper->method( 'is_link_enabled' )->willReturn( false ); + $helper->testmode = true; + + $original_gateways = WC()->payment_gateways()->payment_gateways; + WC()->payment_gateways()->payment_gateways = [ + 'stripe' => new WC_Stripe_UPE_Payment_Gateway(), + ]; + + $result = $helper->should_show_express_checkout_button(); + + // Restore original gateways. + WC()->payment_gateways()->payment_gateways = $original_gateways; + + $this->assertEquals( $expected, $result ); + } + + /** + * Data provider for {@see test_should_show_express_checkout_button_with_amazon_pay_only()}. + * + * @return array + */ + public function provide_test_should_show_express_checkout_button_with_amazon_pay_only(): array { + return [ + 'taxes enabled, billing address' => [ true, 'billing', false ], + 'taxes disabled, billing address' => [ false, 'billing', true ], + 'taxes enabled, shipping address' => [ true, 'shipping', true ], + 'taxes disabled, shipping address' => [ false, 'shipping', true ], + ]; + } }