diff --git a/changelog.txt b/changelog.txt index 364a4cc015..5572c8ea94 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,6 +1,7 @@ *** Changelog *** = 9.9.0 - xxxx-xx-xx = +* Add - Allow the purchase of free trials using the Express Payment methods when the product does not require shipping * 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 * Update - Increases the default font size for the Optimized Checkout payment element to match the rest of the checkout form diff --git a/client/blocks/express-checkout/index.js b/client/blocks/express-checkout/index.js index a297842cfb..c40a4feba1 100644 --- a/client/blocks/express-checkout/index.js +++ b/client/blocks/express-checkout/index.js @@ -83,9 +83,7 @@ const expressCheckoutElement = ( expressPaymentMethod, api ) => { ); const edit = getEditorElement( expressPaymentMethod ); const canMakePayment = ( { cart } ) => { - if ( parseFloat( cart.cartTotals.total_price ) === 0.0 ) { - return false; - } + return true; if ( ! getBlocksConfiguration()?.shouldShowExpressCheckoutButton ) { return false; diff --git a/client/express-checkout/utils/index.js b/client/express-checkout/utils/index.js index 7dab154c39..f701b35a50 100644 --- a/client/express-checkout/utils/index.js +++ b/client/express-checkout/utils/index.js @@ -105,7 +105,6 @@ export const getExpressCheckoutButtonAppearance = () => { return { variables: { borderRadius: `${ - getExpressCheckoutData( 'button' )?.radius || getDefaultBorderRadius() }px`, spacingUnit: '6px', 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 33138ab40b..e03a4a8912 100644 --- a/includes/payment-methods/class-wc-stripe-express-checkout-helper.php +++ b/includes/payment-methods/class-wc-stripe-express-checkout-helper.php @@ -622,6 +622,8 @@ public function is_page_supported() { * @return boolean True if express checkout elements are supported on current page, false otherwise */ public function should_show_express_checkout_button() { + return true; + // Bail if account is not connected. if ( ! WC_Stripe::get_instance()->connect->is_connected() ) { WC_Stripe_Logger::log( 'Account is not connected.' ); @@ -685,10 +687,9 @@ public function should_show_express_checkout_button() { return false; } - // Don't show in the product page if the product price is 0. - // ToDo: support free trials. Free trials should be supported if the product does not require shipping. - if ( $is_product && $product && 0.0 === (float) $product->get_price() ) { - WC_Stripe_Logger::log( 'Stripe Express Checkout does not support free products.' ); + // Don't show in the product page if the product price is 0 and the product requires shipping. + if ( $is_product && $product && 0.0 === (float) $product->get_price() && $this->product_or_cart_needs_shipping() ) { + WC_Stripe_Logger::log( 'Stripe Express Checkout does not support free products that requires shipping.' ); return false; } diff --git a/readme.txt b/readme.txt index 1aaca7d45d..28eb5b3ed3 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 = +* Add - Allow the purchase of free trials using the Express Payment methods when the product does not require shipping * 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 * Update - Increases the default font size for the Optimized Checkout payment element to match the rest of the checkout form 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 26a149df3e..1af2098861 100644 --- a/tests/phpunit/PaymentMethods/WC_Stripe_Express_Checkout_Helper_Test.php +++ b/tests/phpunit/PaymentMethods/WC_Stripe_Express_Checkout_Helper_Test.php @@ -315,6 +315,86 @@ public function test_hides_ece_if_stripe_gateway_unavailable() { WC()->payment_gateways()->payment_gateways = $original_gateways; } + /** + * Test should_show_express_checkout_button, free trial logic. + * + * @return void + */ + 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', + ], + ); + + $wc_stripe_ece_helper_mock->expects( $this->any() )->method( 'is_product' )->willReturn( true ); + $wc_stripe_ece_helper_mock->expects( $this->any() )->method( 'allowed_items_in_cart' )->willReturn( true ); + $wc_stripe_ece_helper_mock->expects( $this->any() )->method( 'should_show_ece_on_cart_page' )->willReturn( true ); + $wc_stripe_ece_helper_mock->expects( $this->any() )->method( 'should_show_ece_on_checkout_page' )->willReturn( true ); + $wc_stripe_ece_helper_mock->testmode = true; + + if ( ! defined( 'WOOCOMMERCE_CHECKOUT' ) ) { + define( 'WOOCOMMERCE_CHECKOUT', true ); + } + + // Ensure that the 'stripe' gateway is available. + $original_gateways = WC()->payment_gateways()->payment_gateways; + WC()->payment_gateways()->payment_gateways = [ + 'stripe' => new WC_Gateway_Stripe(), + ]; + + update_option( 'woocommerce_calc_taxes', 'no' ); + + // Should show, as free virtual products does not require shipping. + $virtual_product = WC_Helper_Product::create_simple_product(); + $virtual_product->set_virtual( true ); + $virtual_product->set_tax_status( 'none' ); + $virtual_product->set_price( 0 ); + $virtual_product->save(); + + WC()->session->init(); + WC()->cart->empty_cart(); + + WC()->cart->add_to_cart( $virtual_product->get_id(), 1 ); + $wc_stripe_ece_helper_mock + ->expects( $this->any() ) + ->method( 'get_product' ) + ->willReturn( $virtual_product ); + + $this->assertTrue( $wc_stripe_ece_helper_mock->should_show_express_checkout_button() ); + + // Should hide if the free product requires shipping. + $shippable_product = WC_Helper_Product::create_simple_product(); + $shippable_product->set_virtual( false ); + $shippable_product->set_tax_status( 'none' ); + $shippable_product->save(); + + WC()->session->init(); + WC()->cart->empty_cart(); + + WC()->cart->add_to_cart( $shippable_product->get_id(), 1 ); + $wc_stripe_ece_helper_mock + ->expects( $this->any() ) + ->method( 'get_product' ) + ->willReturn( $shippable_product ); + + $this->assertFalse( $wc_stripe_ece_helper_mock->should_show_express_checkout_button() ); + + // Restore original settings. + WC()->cart->empty_cart(); + WC()->session->cleanup_sessions(); + WC()->payment_gateways()->payment_gateways = $original_gateways; + + update_option( 'woocommerce_calc_taxes', 'yes' ); + } + /** * Test for get_checkout_data(). */