diff --git a/changelog.txt b/changelog.txt index 25614d13d0..ded408c04f 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,6 +1,7 @@ *** Changelog *** = 10.1.0 - xxxx-xx-xx = +* Fix - Fixes Amazon Pay display inside the Apple Pay/Google Pay container. And location settings for those methods affecting each other * Dev - Upgrades the `nock` NPM package to version `^13.5.6` to remove the lodash.set dependency * Add - Add a new filter allowing third-party plugins to hook captcha solutions when creating and confirming setup intents * Dev - Add track events when clicking the "Reconnect to Stripe" button (both in the settings page and the admin notice) diff --git a/client/entrypoints/amazon-pay-settings/express-checkout-preview-component.js b/client/entrypoints/amazon-pay-settings/express-checkout-preview-component.js index 9dff9546a9..6b05b3cdc2 100644 --- a/client/entrypoints/amazon-pay-settings/express-checkout-preview-component.js +++ b/client/entrypoints/amazon-pay-settings/express-checkout-preview-component.js @@ -44,6 +44,10 @@ const ExpressCheckoutPreviewComponent = ( { size } ) => { buttonHeight: Math.min( Math.max( height, 40 ), 55 ), paymentMethods: { amazonPay: 'auto', + link: 'never', + googlePay: 'never', + applePay: 'never', + klarna: 'never', }, layout: { overflow: 'never' }, }; diff --git a/client/entrypoints/express-checkout-settings/express-checkout-preview-component.js b/client/entrypoints/express-checkout-settings/express-checkout-preview-component.js index d657e25099..a5aaf8cd56 100644 --- a/client/entrypoints/express-checkout-settings/express-checkout-preview-component.js +++ b/client/entrypoints/express-checkout-settings/express-checkout-preview-component.js @@ -84,6 +84,8 @@ const ExpressCheckoutPreviewComponent = ( { buttonType, theme, size } ) => { link: 'never', googlePay: 'always', applePay: 'always', + amazonPay: 'never', + klarna: 'never', }, layout: { overflow: 'never' }, }; diff --git a/includes/class-wc-stripe-blocks-support.php b/includes/class-wc-stripe-blocks-support.php index f350eca32d..c08cf346d9 100644 --- a/includes/class-wc-stripe-blocks-support.php +++ b/includes/class-wc-stripe-blocks-support.php @@ -46,8 +46,8 @@ public function __construct( $payment_request_configuration = null, $express_che $this->payment_request_configuration = null !== $payment_request_configuration ? $payment_request_configuration : new WC_Stripe_Payment_Request(); if ( null === $express_checkout_configuration ) { - $helper = new WC_Stripe_Express_Checkout_Helper(); - $ajax_handler = new WC_Stripe_Express_Checkout_Ajax_Handler( $helper ); + $helper = new WC_Stripe_Express_Checkout_Helper(); + $ajax_handler = new WC_Stripe_Express_Checkout_Ajax_Handler( $helper ); $express_checkout_configuration = new WC_Stripe_Express_Checkout_Element( $ajax_handler, $helper ); } $this->express_checkout_configuration = $express_checkout_configuration; @@ -278,35 +278,6 @@ private function get_style() { * @return boolean True if ECEs should be displayed, false otherwise. */ private function should_show_express_checkout_button() { - // Don't show if ECEs are turned off in settings. - if ( ! $this->express_checkout_configuration->express_checkout_helper->is_express_checkout_enabled() ) { - return false; - } - - // Don't show if ECEs are supposed to be hidden on the cart page. - if ( - has_block( 'woocommerce/cart' ) - && ! $this->express_checkout_configuration->express_checkout_helper->should_show_ece_on_cart_page() - ) { - return false; - } - - // Don't show if ECEs are supposed to be hidden on the checkout page. - if ( - has_block( 'woocommerce/checkout' ) - && ! $this->express_checkout_configuration->express_checkout_helper->should_show_ece_on_checkout_page() - ) { - return false; - } - - // Don't show ECEs if there are unsupported products in the cart. - if ( - ( has_block( 'woocommerce/checkout' ) || has_block( 'woocommerce/cart' ) ) - && ! $this->express_checkout_configuration->express_checkout_helper->allowed_items_in_cart() - ) { - return false; - } - return $this->express_checkout_configuration->express_checkout_helper->should_show_express_checkout_button(); } diff --git a/includes/payment-methods/class-wc-stripe-express-checkout-element.php b/includes/payment-methods/class-wc-stripe-express-checkout-element.php index 886d87ad55..4c9abde178 100644 --- a/includes/payment-methods/class-wc-stripe-express-checkout-element.php +++ b/includes/payment-methods/class-wc-stripe-express-checkout-element.php @@ -548,7 +548,7 @@ public function display_express_checkout_button_separator_html() { return; } - if ( is_checkout() && ! in_array( 'checkout', $this->express_checkout_helper->get_button_locations(), true ) ) { + if ( is_checkout() && ! $this->express_checkout_helper->should_show_ece_on_checkout_page() ) { return; } 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 b6f826bd9e..9d0fa5c87a 100644 --- a/includes/payment-methods/class-wc-stripe-express-checkout-helper.php +++ b/includes/payment-methods/class-wc-stripe-express-checkout-helper.php @@ -677,13 +677,13 @@ public function should_show_express_checkout_button() { } // Don't show on cart if disabled. - if ( is_cart() && ! $this->should_show_ece_on_cart_page() ) { + if ( $this->is_cart() && ! $this->should_show_ece_on_cart_page() ) { WC_Stripe_Logger::log( 'Stripe Express Checkout buttons display on cart is disabled. ' ); return false; } // Don't show on checkout if disabled. - if ( is_checkout() && ! $this->should_show_ece_on_checkout_page() ) { + if ( $this->is_checkout() && ! $this->should_show_ece_on_checkout_page() ) { WC_Stripe_Logger::log( 'Stripe Express Checkout buttons display on checkout is disabled. ' ); return false; } @@ -842,13 +842,13 @@ private function product_or_cart_needs_shipping() { } /** - * Returns true if express checkout buttons are enabled on the cart page, false + * Returns true if any express checkout buttons are enabled on the cart page, false * otherwise. * - * @return boolean True if express checkout buttons are enabled on the cart page, false otherwise + * @return boolean True if any express checkout buttons are enabled on the cart page, false otherwise. */ public function should_show_ece_on_cart_page() { - $should_show_on_cart_page = in_array( 'cart', $this->get_button_locations(), true ); + $should_show_on_cart_page = $this->should_show_ece_on_page( 'cart' ); return apply_filters( 'wc_stripe_show_payment_request_on_cart', @@ -865,7 +865,7 @@ public function should_show_ece_on_cart_page() { public function should_show_ece_on_checkout_page() { global $post; - $should_show_on_checkout_page = in_array( 'checkout', $this->get_button_locations(), true ); + $should_show_on_checkout_page = $this->should_show_ece_on_page( 'checkout' ); return apply_filters( 'wc_stripe_show_payment_request_on_checkout', @@ -875,15 +875,15 @@ public function should_show_ece_on_checkout_page() { } /** - * Returns true if express checkout buttons are enabled on product pages, false + * Returns true if any express checkout buttons are enabled on product pages, false * otherwise. * - * @return boolean True if express checkout buttons are enabled on product pages, false otherwise + * @return boolean True if any express checkout buttons are enabled on product pages, false otherwise */ public function should_show_ece_on_product_pages() { global $post; - $should_show_on_product_page = in_array( 'product', $this->get_button_locations(), true ); + $should_show_on_product_page = $this->should_show_ece_on_page( 'product' ); // Note the negation because if the filter returns `true` that means we should hide the PRB. return ! apply_filters( @@ -893,6 +893,18 @@ public function should_show_ece_on_product_pages() { ); } + /** + * Returns true if any express checkout buttons are enabled on the given page, false + * otherwise. + * + * @param string $page The page to check. + * @return boolean True if any express checkout buttons are enabled on the given page, false otherwise. + */ + private function should_show_ece_on_page( $page ) { + return $this->is_enabled_for_location( 'payment_request', $page ) || + $this->is_enabled_for_location( 'amazon_pay', $page ); + } + /** * Returns true if the provided product is supported, false otherwise. * @@ -1378,6 +1390,15 @@ public function is_checkout() { return is_checkout() || has_block( 'woocommerce/checkout' ); } + /** + * Checks if this is the cart page or content contains a cart block. + * + * @return boolean + */ + public function is_cart() { + return is_cart() || has_block( 'woocommerce/cart' ); + } + /** * Builds the shippings methods to pass to express checkout elements. */ @@ -1549,22 +1570,46 @@ public function get_login_confirmation_settings() { /** * Pages where the express checkout buttons should be displayed. * + * @param string|null $express_checkout_type The type of express checkout. * @return array */ - public function get_button_locations() { - // If the locations have not been set return the default setting. - if ( ! isset( $this->stripe_settings['payment_request_button_locations'] ) ) { - return [ 'product', 'cart' ]; + public function get_button_locations( ?string $express_checkout_type = null ) { + switch ( $express_checkout_type ) { + case 'amazon_pay': + $key = 'amazon_pay_button_locations'; + break; + case 'payment_request': + case 'link': // Link does not yet have its own Customize page. It shares the same location settings as Apple Pay and Google Pay. + default: + $key = 'payment_request_button_locations'; + break; } - // If all locations are removed through the settings UI the location config will be set to - // an empty string "". If that's the case (and if the settings are not an array for any - // other reason) we should return an empty array. - if ( ! is_array( $this->stripe_settings['payment_request_button_locations'] ) ) { - return []; + if ( ! isset( $this->stripe_settings[ $key ] ) ) { + // If the locations have not been set/modified, return the default setting. + $enabled_locations = [ 'product', 'cart' ]; + } elseif ( ! is_array( $this->stripe_settings[ $key ] ) ) { + // If all locations are removed through the settings UI the location config will be set to + // an empty string "". If that's the case (and if the settings are not an array for any + // other reason) we should return an empty array. + $enabled_locations = []; + } else { + $enabled_locations = $this->stripe_settings[ $key ]; } - return $this->stripe_settings['payment_request_button_locations']; + return $enabled_locations; + } + + /** + * Check if the express checkout type is enabled for the given location. + * + * @param string $express_checkout_type The type of express checkout. + * @param string $location The location to check. + * @return boolean + */ + public function is_enabled_for_location( $express_checkout_type = 'payment_request', $location = '' ) { + $enabled_locations = $this->get_button_locations( $express_checkout_type ); + return in_array( $location, $enabled_locations, true ); } /** @@ -1584,7 +1629,14 @@ public function is_express_checkout_enabled() { * @return boolean */ public function is_payment_request_enabled() { - return $this->gateway->is_payment_request_enabled(); + $is_enabled = $this->gateway->is_payment_request_enabled(); + if ( is_product() ) { + return $is_enabled && $this->is_enabled_for_location( 'payment_request', 'product' ); + } elseif ( is_cart() ) { + return $is_enabled && $this->is_enabled_for_location( 'payment_request', 'cart' ); + } + + return $is_enabled; } /** @@ -1593,7 +1645,14 @@ public function is_payment_request_enabled() { * @return boolean */ public function is_amazon_pay_enabled() { - return WC_Stripe_UPE_Payment_Method_Amazon_Pay::is_amazon_pay_enabled( $this->gateway ); + $is_enabled = WC_Stripe_UPE_Payment_Method_Amazon_Pay::is_amazon_pay_enabled( $this->gateway ); + if ( is_product() ) { + return $is_enabled && $this->is_enabled_for_location( 'amazon_pay', 'product' ); + } elseif ( is_cart() ) { + return $is_enabled && $this->is_enabled_for_location( 'amazon_pay', 'cart' ); + } + + return $is_enabled; } /** @@ -1602,7 +1661,14 @@ public function is_amazon_pay_enabled() { * @return boolean */ public function is_link_enabled() { - return WC_Stripe_UPE_Payment_Method_Link::is_link_enabled( $this->gateway ); + $is_enabled = WC_Stripe_UPE_Payment_Method_Link::is_link_enabled( $this->gateway ); + if ( is_product() ) { + return $is_enabled && $this->is_enabled_for_location( 'link', 'product' ); + } elseif ( is_cart() ) { + return $is_enabled && $this->is_enabled_for_location( 'link', 'cart' ); + } + + return $is_enabled; } /** diff --git a/readme.txt b/readme.txt index e9825ae052..f6b5235fbe 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 == = 10.1.0 - xxxx-xx-xx = +* Fix - Fixes Amazon Pay display inside the Apple Pay/Google Pay container. And location settings for those methods affecting each other * Dev - Upgrades the `nock` NPM package to version `^13.5.6` to remove the lodash.set dependency * Add - Add a new filter allowing third-party plugins to hook captcha solutions when creating and confirming setup intents * Dev - Add track events when clicking the "Reconnect to Stripe" button (both in the settings page and the admin notice) 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 d568e1d812..b1104d4847 100644 --- a/tests/phpunit/PaymentMethods/WC_Stripe_Express_Checkout_Helper_Test.php +++ b/tests/phpunit/PaymentMethods/WC_Stripe_Express_Checkout_Helper_Test.php @@ -984,4 +984,110 @@ public function provide_test_has_free_trial() { ], ]; } + + /** + * Tests for `is_cart`. + * + * @return void + */ + public function test_is_cart(): void { + add_filter( 'woocommerce_is_cart', '__return_true' ); + + $helper = new WC_Stripe_Express_Checkout_Helper(); + + $actual = $helper->is_cart(); + + // Clean up. + remove_filter( 'woocommerce_is_cart', '__return_true' ); + + $this->assertTrue( $actual ); + + $actual = $helper->is_cart(); + + $this->assertFalse( $actual ); + } + + /** + * Teats for `get_button_locations`. + * + * @param string $express_checkout_type Express checkout type. + * @param array $settings Settings array. + * @param array $expected Expected locations. + * @return void + * + * @dataProvider provide_test_get_button_locations + */ + public function test_get_button_locations( string $express_checkout_type, array $settings = [], $expected = [] ): void { + $helper = new WC_Stripe_Express_Checkout_Helper(); + $helper->stripe_settings = $settings; + + $actual = $helper->get_button_locations( $express_checkout_type ); + + $this->assertSame( $expected, $actual ); + } + + public function provide_test_get_button_locations(): array { + return [ + 'payment request, settings exists' => [ + 'express checkout type' => 'payment_request', + 'settings' => [ 'payment_request_button_locations' => [ 'checkout', 'cart' ] ], + 'expected' => [ 'checkout', 'cart' ], + ], + 'payment request, settings exists, but not a valid array' => [ + 'express checkout type' => 'payment_request', + 'settings' => [ 'payment_request_button_locations' => 'invalid_value' ], + 'expected' => [], + ], + 'payment request, settings do not exist' => [ + 'express checkout type' => 'payment_request', + 'settings' => [], + 'expected' => [ 'product', 'cart' ], + ], + 'link, settings exists' => [ + 'express checkout type' => 'link', + 'settings' => [ 'payment_request_button_locations' => [ 'cart' ] ], + 'expected' => [ 'cart' ], + ], + 'link, settings exists, but not a valid array' => [ + 'express checkout type' => 'link', + 'settings' => [ 'payment_request_button_locations' => 'invalid_value' ], + 'expected' => [], + ], + 'link, settings do not exist' => [ + 'express checkout type' => 'link', + 'settings' => [], + 'expected' => [ 'product', 'cart' ], + ], + 'amazon pay, settings exists' => [ + 'express checkout type' => 'amazon_pay', + 'settings' => [ 'amazon_pay_button_locations' => [ 'checkout' ] ], + 'expected' => [ 'checkout' ], + ], + 'amazon pay, settings exists, but not a valid array' => [ + 'express checkout type' => 'amazon_pay', + 'settings' => [ 'amazon_pay_button_locations' => 'invalid_value' ], + 'expected' => [], + ], + 'amazon pay, settings do not exist' => [ + 'express checkout type' => 'amazon_pay', + 'settings' => [], + 'expected' => [ 'product', 'cart' ], + ], + 'default, settings exists' => [ + 'express checkout type' => 'default', + 'settings' => [ 'payment_request_button_locations' => [ 'checkout', 'cart' ] ], + 'expected' => [ 'checkout', 'cart' ], + ], + 'default, settings exists, but not a valid array' => [ + 'express checkout type' => 'default', + 'settings' => [ 'payment_request_button_locations' => 'invalid_value' ], + 'expected' => [], + ], + 'default, settings do not exist' => [ + 'express checkout type' => 'default', + 'settings' => [], + 'expected' => [ 'product', 'cart' ], + ], + ]; + } }