From 587e9a832dd14f767ecbc96c4df58a86278f8393 Mon Sep 17 00:00:00 2001 From: Timur Karimov Date: Tue, 3 Oct 2023 12:09:52 +0200 Subject: [PATCH 1/6] Enables deferred intent UPE for existing legacy UPE stores (#7306) Co-authored-by: Timur Karimov --- changelog/feat-handle-server-side-dupe-flag | 4 ++ client/payment-methods/index.js | 66 ++++++++---------- client/payment-methods/test/index.js | 65 +++++++++++++++++- includes/class-wc-payment-gateway-wcpay.php | 6 +- includes/class-wc-payments-features.php | 68 ++++++++++++++++--- .../test-class-upe-payment-gateway.php | 9 ++- .../test-class-upe-split-payment-gateway.php | 8 ++- .../test-class-wc-payment-gateway-wcpay.php | 2 +- .../test-class-wc-payments-token-service.php | 7 +- tests/unit/test-class-wc-payments.php | 4 +- 10 files changed, 175 insertions(+), 64 deletions(-) create mode 100644 changelog/feat-handle-server-side-dupe-flag diff --git a/changelog/feat-handle-server-side-dupe-flag b/changelog/feat-handle-server-side-dupe-flag new file mode 100644 index 00000000000..cdf484a3b1d --- /dev/null +++ b/changelog/feat-handle-server-side-dupe-flag @@ -0,0 +1,4 @@ +Significance: minor +Type: add + +Handle server-side feature flag for new UPE type enablement. diff --git a/client/payment-methods/index.js b/client/payment-methods/index.js index d47b2ddb9e1..a03ca98204a 100644 --- a/client/payment-methods/index.js +++ b/client/payment-methods/index.js @@ -39,7 +39,6 @@ import DisableUPEModal from '../settings/disable-upe-modal'; import PaymentMethodsList from 'components/payment-methods-list'; import PaymentMethod from 'components/payment-methods-list/payment-method'; import WCPaySettingsContext from '../settings/wcpay-settings-context'; -import Pill from '../components/pill'; import methodsConfiguration from '../payment-methods-map'; import CardBody from '../settings/card-body'; import { upeCapabilityStatuses } from 'wcpay/additional-methods-setup/constants'; @@ -48,23 +47,34 @@ import ConfirmPaymentMethodDeleteModal from './delete-modal'; import { getAdminUrl } from 'wcpay/utils'; import { getPaymentMethodDescription } from 'wcpay/utils/payment-methods'; import InlineNotice from 'wcpay/components/inline-notice'; -import interpolateComponents from '@automattic/interpolate-components'; const PaymentMethodsDropdownMenu = ( { setOpenModal } ) => { + const { isUpeEnabled, upeType } = useContext( WcPayUpeContext ); + const isDisablePossible = + isUpeEnabled && upeType !== 'deferred_intent_upe_without_fallback'; + const label = isDisablePossible + ? __( 'Add feedback or disable', 'woocommerce-payments' ) + : __( 'Add feedback', 'woocommerce-payments' ); + + const buttons = [ + { + title: __( 'Provide feedback', 'woocommerce-payments' ), + onClick: () => setOpenModal( 'survey' ), + }, + ]; + + if ( isDisablePossible ) { + buttons.push( { + title: 'Disable', + onClick: () => setOpenModal( 'disable' ), + } ); + } + return ( setOpenModal( 'survey' ), - }, - { - title: 'Disable', - onClick: () => setOpenModal( 'disable' ), - }, - ] } + label={ label } + controls={ buttons } /> ); }; @@ -225,6 +235,11 @@ const PaymentMethods = () => { const { isUpeEnabled, status, upeType } = useContext( WcPayUpeContext ); const [ openModalIdentifier, setOpenModalIdentifier ] = useState( '' ); + const rollbackNoticeForLegacyUPE = __( + // eslint-disable-next-line max-len + 'You have been switched from the new checkout to your previous checkout experience. We will keep you posted on the new checkout availability.', + 'woocommerce-payments' + ); return ( <> @@ -260,17 +275,6 @@ const PaymentMethods = () => { 'woocommerce-payments' ) } - { upeType !== 'split' && ( - <> - { ' ' } - - { __( - 'Early access', - 'woocommerce-payments' - ) } - - - ) } { status="warning" isDismissible={ false } > - { interpolateComponents( { - mixedString: __( - 'The new WooPayments checkout experience will become the default on October 11, 2023.' + - ' {{learnMoreLink}}Learn more{{/learnMoreLink}}', - 'woocommerce-payments' - ), - components: { - learnMoreLink: ( - // eslint-disable-next-line max-len - - ), - }, - } ) } + { rollbackNoticeForLegacyUPE } ) } diff --git a/client/payment-methods/test/index.js b/client/payment-methods/test/index.js index 5d2ebf69ff9..834dd51e1f0 100644 --- a/client/payment-methods/test/index.js +++ b/client/payment-methods/test/index.js @@ -424,7 +424,7 @@ describe( 'PaymentMethods', () => { expect( disableUPEButton ).toBeInTheDocument(); expect( screen.queryByText( 'Payment methods' ).parentElement - ).toHaveTextContent( 'Payment methods Early access' ); + ).toHaveTextContent( 'Payment methods' ); } ); test( 'Does not render the feedback elements when UPE is disabled', () => { @@ -484,6 +484,69 @@ describe( 'PaymentMethods', () => { ); } ); + it( 'should only be able to leave feedback when deferred upe after migration is enabled', () => { + render( + + + + ); + const kebabMenuWithFeedbackOnly = screen.queryByRole( 'button', { + name: 'Add feedback', + } ); + + const kebabMenuWithFeedbackAndDisable = screen.queryByRole( 'button', { + name: 'Add feedback or disable', + } ); + + expect( kebabMenuWithFeedbackOnly ).toBeInTheDocument(); + expect( kebabMenuWithFeedbackAndDisable ).not.toBeInTheDocument(); + } ); + + it( 'should only be able to leave feedback and disable when deferred upe was enabled manually for legacy card stores', () => { + render( + + + + ); + const kebabMenuWithFeedbackOnly = screen.queryByRole( 'button', { + name: 'Add feedback', + } ); + + const kebabMenuWithFeedbackAndDisable = screen.queryByRole( 'button', { + name: 'Add feedback or disable', + } ); + + expect( kebabMenuWithFeedbackAndDisable ).toBeInTheDocument(); + expect( kebabMenuWithFeedbackOnly ).not.toBeInTheDocument(); + } ); + + it( 'should be able to leave feedback and disable for non-deferred-upe', () => { + render( + + + + ); + const kebabMenuWithFeedbackOnly = screen.queryByRole( 'button', { + name: 'Add feedback', + } ); + + const kebabMenuWithFeedbackAndDisable = screen.queryByRole( 'button', { + name: 'Add feedback or disable', + } ); + + expect( kebabMenuWithFeedbackAndDisable ).toBeInTheDocument(); + expect( kebabMenuWithFeedbackOnly ).not.toBeInTheDocument(); + } ); + it( 'should render the activation modal when requirements exist for the payment method', () => { useEnabledPaymentMethodIds.mockReturnValue( [ [], jest.fn() ] ); useGetAvailablePaymentMethodIds.mockReturnValue( [ 'bancontact' ] ); diff --git a/includes/class-wc-payment-gateway-wcpay.php b/includes/class-wc-payment-gateway-wcpay.php index 4711a697a7b..b2a1ffba8c9 100644 --- a/includes/class-wc-payment-gateway-wcpay.php +++ b/includes/class-wc-payment-gateway-wcpay.php @@ -1603,11 +1603,11 @@ public function set_payment_method_title_for_order( $order, $payment_method_type */ protected function get_metadata_from_order( $order, $payment_type ) { if ( $this instanceof UPE_Split_Payment_Gateway ) { - $gateway_type = 'split_upe'; + $gateway_type = 'split_upe_with_deferred_intent_creation'; } elseif ( $this instanceof UPE_Payment_Gateway ) { - $gateway_type = 'upe'; + $gateway_type = 'legacy_upe'; } else { - $gateway_type = 'classic'; + $gateway_type = 'legacy_card'; } $name = sanitize_text_field( $order->get_billing_first_name() ) . ' ' . sanitize_text_field( $order->get_billing_last_name() ); $email = sanitize_email( $order->get_billing_email() ); diff --git a/includes/class-wc-payments-features.php b/includes/class-wc-payments-features.php index 6d61b0966c6..fb4d8333231 100644 --- a/includes/class-wc-payments-features.php +++ b/includes/class-wc-payments-features.php @@ -24,6 +24,7 @@ class WC_Payments_Features { const PROGRESSIVE_ONBOARDING_FLAG_NAME = '_wcpay_feature_progressive_onboarding'; const DISPUTE_ON_TRANSACTION_PAGE = '_wcpay_feature_dispute_on_transaction_page'; const PAY_FOR_ORDER_FLOW = '_wcpay_feature_pay_for_order_flow'; + const DEFERRED_UPE_SERVER_FLAG_NAME = 'is_deferred_intent_creation_upe_enabled'; /** * Checks whether any UPE gateway is enabled. @@ -40,7 +41,26 @@ public static function is_upe_enabled() { * @return string */ public static function get_enabled_upe_type() { - if ( self::is_upe_split_enabled() || self::is_upe_deferred_intent_enabled() ) { + // New stores created in 6.4.0 or 6.5.0, and legacy card stores that self-migrated to dUPE in 6.4.0 or 6.5.0. + $has_store_enabled_dupe_from_previous_plugin_version = self::has_store_enabled_dupe_from_previous_plugin_version(); + $has_store_enabled_upe_and_dupe_server_flag = self::has_store_enabled_upe_and_dupe_server_flag(); + + // Stores which first self-migrated and then had deferred intent creation UPE enabled by default. + if ( $has_store_enabled_dupe_from_previous_plugin_version && $has_store_enabled_upe_and_dupe_server_flag ) { + return 'deferred_intent_upe_without_fallback'; + } + + // Stores which have deferred intent creation UPE enabled by default. + if ( $has_store_enabled_upe_and_dupe_server_flag ) { + return 'deferred_intent_upe_without_fallback'; + } + + // Stores which self-migrated to dUPE (e.g. legacy card stores from 6.4.0 or 6.5.0). + if ( $has_store_enabled_dupe_from_previous_plugin_version ) { + return 'deferred_intent_upe_with_fallback'; + } + + if ( self::is_upe_split_enabled() ) { return 'split'; } @@ -57,25 +77,55 @@ public static function get_enabled_upe_type() { * @return bool */ public static function is_upe_legacy_enabled() { - $upe_flag_value = '1' === get_option( self::UPE_FLAG_NAME, '0' ); - if ( $upe_flag_value ) { - return true; - } - return false; + return '1' === get_option( self::UPE_FLAG_NAME, '0' ); } /** * Checks whether the Split-UPE gateway is enabled */ public static function is_upe_split_enabled() { - return '1' === get_option( self::UPE_SPLIT_FLAG_NAME, '0' ) && self::is_upe_split_eligible(); + return '1' === get_option( self::UPE_SPLIT_FLAG_NAME, '0' ); } /** - * Checks whether the Split UPE with deferred intent is enabled + * Checks whether the Split UPE with deferred intent creation is enabled */ public static function is_upe_deferred_intent_enabled() { - return ( '1' === get_option( self::UPE_DEFERRED_INTENT_FLAG_NAME, '0' ) ) || self::is_upe_split_enabled(); + // Support new stores created in 6.4.0 or 6.5.0, and legacy card stores that migrated to deferred UPE in 6.4.0 or 6.5.0. + $has_store_enabled_dupe_from_previous_plugin_version = self::has_store_enabled_dupe_from_previous_plugin_version(); + $has_store_enabled_upe_and_dupe_server_flag = self::has_store_enabled_upe_and_dupe_server_flag(); + + return $has_store_enabled_dupe_from_previous_plugin_version || $has_store_enabled_upe_and_dupe_server_flag; + } + + /** + * Checks if the store has deferred intent creation UPE enabled from a previous version. + * This is applicable to: + * * legacy card stores that self-migrated to deferred UPE in 6.4.0 or 6.5.0 + * * new stores starting 6.4.0 + */ + private static function has_store_enabled_dupe_from_previous_plugin_version() { + return '1' === get_option( self::UPE_DEFERRED_INTENT_FLAG_NAME, '0' ); + } + + /** + * Checks if the store has UPE enabled and the server-side feature flag is enabled. + * This is applicable to: + * * Split UPE stores starting 6.4.0 + * * Legacy UPE stores starting 6.6.0 + */ + private static function has_store_enabled_upe_and_dupe_server_flag() { + return ( self::is_upe_split_enabled() || self::is_upe_legacy_enabled() ) && self::is_deferred_upe_server_flag_enabled(); + } + + + /** + * Checks if the Deferred UPE server-side feature flag is enabled. + * The flag should be always returned, and if it's not present, server assumes it's enabled. + */ + private static function is_deferred_upe_server_flag_enabled() { + $account = WC_Payments::get_database_cache()->get( WCPay\Database_Cache::ACCOUNT_KEY, true ); + return is_array( $account ) && ( $account[ self::DEFERRED_UPE_SERVER_FLAG_NAME ] ?? false ); } /** diff --git a/tests/unit/payment-methods/test-class-upe-payment-gateway.php b/tests/unit/payment-methods/test-class-upe-payment-gateway.php index e52cac12c1d..631cd87cef9 100644 --- a/tests/unit/payment-methods/test-class-upe-payment-gateway.php +++ b/tests/unit/payment-methods/test-class-upe-payment-gateway.php @@ -381,7 +381,7 @@ public function test_update_payment_intent_adds_customer_save_payment_and_level3 'order_number' => $order_number, 'order_key' => $order->get_order_key(), 'payment_type' => Payment_Type::SINGLE(), - 'gateway_type' => 'upe', + 'gateway_type' => 'legacy_upe', 'checkout_type' => '', 'client_version' => WCPAY_VERSION_NUMBER, 'subscription_payment' => 'no', @@ -483,7 +483,7 @@ public function test_update_payment_intent_with_selected_upe_payment_method() { 'order_number' => $order_number, 'order_key' => $order->get_order_key(), 'payment_type' => Payment_Type::SINGLE(), - 'gateway_type' => 'upe', + 'gateway_type' => 'legacy_upe', 'checkout_type' => '', 'client_version' => WCPAY_VERSION_NUMBER, 'subscription_payment' => 'no', @@ -581,7 +581,7 @@ public function test_update_payment_intent_with_payment_country() { 'order_number' => $order_number, 'order_key' => $order->get_order_key(), 'payment_type' => Payment_Type::SINGLE(), - 'gateway_type' => 'upe', + 'gateway_type' => 'legacy_upe', 'checkout_type' => '', 'client_version' => WCPAY_VERSION_NUMBER, 'subscription_payment' => 'no', @@ -1904,8 +1904,7 @@ public function test_maybe_filter_gateway_title_with_no_additional_feature_flags } public function test_maybe_filter_gateway_title_skips_update_due_to_enabled_split_upe() { - update_option( '_wcpay_feature_upe_split', '1' ); - update_option( '_wcpay_feature_upe_deferred_intent', '0' ); + update_option( '_wcpay_feature_upe_deferred_intent', '1' ); $data = [ 'methods' => [ diff --git a/tests/unit/payment-methods/test-class-upe-split-payment-gateway.php b/tests/unit/payment-methods/test-class-upe-split-payment-gateway.php index d092632f1d3..629699827ed 100644 --- a/tests/unit/payment-methods/test-class-upe-split-payment-gateway.php +++ b/tests/unit/payment-methods/test-class-upe-split-payment-gateway.php @@ -439,7 +439,7 @@ public function test_update_payment_intent_adds_customer_save_payment_and_level3 'order_number' => $order_number, 'order_key' => $order->get_order_key(), 'payment_type' => Payment_Type::SINGLE(), - 'gateway_type' => 'split_upe', + 'gateway_type' => 'split_upe_with_deferred_intent_creation', 'checkout_type' => '', 'client_version' => WCPAY_VERSION_NUMBER, 'subscription_payment' => 'no', @@ -514,7 +514,7 @@ public function test_update_payment_intent_with_selected_upe_payment_method() { 'order_number' => $order_number, 'order_key' => $order->get_order_key(), 'payment_type' => Payment_Type::SINGLE(), - 'gateway_type' => 'split_upe', + 'gateway_type' => 'split_upe_with_deferred_intent_creation', 'checkout_type' => '', 'client_version' => WCPAY_VERSION_NUMBER, 'subscription_payment' => 'no', @@ -593,7 +593,7 @@ public function test_update_payment_intent_with_payment_country() { 'order_number' => $order_number, 'order_key' => $order->get_order_key(), 'payment_type' => Payment_Type::SINGLE(), - 'gateway_type' => 'split_upe', + 'gateway_type' => 'split_upe_with_deferred_intent_creation', 'checkout_type' => '', 'client_version' => WCPAY_VERSION_NUMBER, 'subscription_payment' => 'no', @@ -2125,6 +2125,7 @@ public function test_remove_link_payment_method_if_card_disabled() { } public function test_link_payment_method_if_card_enabled() { + update_option( '_wcpay_feature_upe_deferred_intent', '1' ); WC_Helper_Site_Currency::$mock_site_currency = 'USD'; $mock_upe_gateway = $this->getMockBuilder( UPE_Split_Payment_Gateway::class ) @@ -2426,6 +2427,7 @@ public function test_get_payment_methods_without_request_context_or_token() { * @return void */ public function test_get_payment_methods_from_gateway_id() { + update_option( '_wcpay_feature_upe_deferred_intent', '1' ); $order = WC_Helper_Order::create_order(); $mock_upe_gateway = $this->getMockBuilder( UPE_Split_Payment_Gateway::class ) ->setConstructorArgs( diff --git a/tests/unit/test-class-wc-payment-gateway-wcpay.php b/tests/unit/test-class-wc-payment-gateway-wcpay.php index 464f5e90959..ac119699600 100644 --- a/tests/unit/test-class-wc-payment-gateway-wcpay.php +++ b/tests/unit/test-class-wc-payment-gateway-wcpay.php @@ -1292,7 +1292,7 @@ public function test_capture_charge_metadata() { 'order_number' => $order->get_order_number(), 'order_key' => $order->get_order_key(), 'payment_type' => Payment_Type::SINGLE(), - 'gateway_type' => 'classic', + 'gateway_type' => 'legacy_card', 'checkout_type' => '', 'client_version' => WCPAY_VERSION_NUMBER, 'subscription_payment' => 'no', diff --git a/tests/unit/test-class-wc-payments-token-service.php b/tests/unit/test-class-wc-payments-token-service.php index fe37bc5ef53..e1e489608dd 100644 --- a/tests/unit/test-class-wc-payments-token-service.php +++ b/tests/unit/test-class-wc-payments-token-service.php @@ -111,9 +111,10 @@ public function test_add_token_to_user_for_sepa() { } /** - * Test add SEPA token to user with split UPE. + * Test add SEPA token to user with deferred intent creation UPE. */ - public function test_add_token_to_user_for_sepa_split_upe() { + public function test_add_token_to_user_for_sepa_deferred_intent_creation_upe() { + update_option( '_wcpay_feature_upe_deferred_intent', '1' ); update_option( WC_Payments_Features::UPE_SPLIT_FLAG_NAME, '1' ); $mock_payment_method = [ 'id' => 'pm_mock', @@ -542,7 +543,7 @@ public function test_woocommerce_get_customer_payment_tokens_not_added_twice_for } public function test_woocommerce_get_customer_payment_tokens_not_added_from_different_gateway() { - update_option( '_wcpay_feature_upe_split', '1' ); + update_option( '_wcpay_feature_upe_deferred_intent', '1' ); $gateway_id = WC_Payment_Gateway_WCPay::GATEWAY_ID; $tokens = []; $payment_methods = [ Payment_Method::CARD, Payment_Method::SEPA ]; diff --git a/tests/unit/test-class-wc-payments.php b/tests/unit/test-class-wc-payments.php index beee6c8652e..c0f50592560 100644 --- a/tests/unit/test-class-wc-payments.php +++ b/tests/unit/test-class-wc-payments.php @@ -79,7 +79,7 @@ public function test_it_does_not_register_woopay_hooks_if_feature_flag_is_disabl } public function test_it_skips_stripe_link_gateway_registration() { - update_option( WC_Payments_Features::UPE_SPLIT_FLAG_NAME, '1' ); + update_option( WC_Payments_Features::UPE_DEFERRED_INTENT_FLAG_NAME, '1' ); $card_gateway_mock = $this->createMock( UPE_Split_Payment_Gateway::class ); $card_gateway_mock @@ -103,7 +103,7 @@ public function test_it_skips_stripe_link_gateway_registration() { $this->assertInstanceOf( UPE_Split_Payment_Gateway::class, $registered_gateways[0] ); $this->assertEquals( $registered_gateways[0]->get_stripe_id(), 'card' ); - update_option( WC_Payments_Features::UPE_SPLIT_FLAG_NAME, '0' ); + update_option( WC_Payments_Features::UPE_DEFERRED_INTENT_FLAG_NAME, '0' ); } public function test_rest_endpoints_validate_nonce() { From 8d4d61491080304984f7c98f477bb31321edb9b4 Mon Sep 17 00:00:00 2001 From: Cvetan Cvetanov Date: Tue, 3 Oct 2023 14:52:38 +0300 Subject: [PATCH 2/6] Fix variable virtual products require a shipping address for Apple Pay and Google Pay (#7317) --- .../fix-6714-request-button-virtual-variable | 4 ++ client/payment-request/index.js | 37 +++++++++++++++---- 2 files changed, 34 insertions(+), 7 deletions(-) create mode 100644 changelog/fix-6714-request-button-virtual-variable diff --git a/changelog/fix-6714-request-button-virtual-variable b/changelog/fix-6714-request-button-virtual-variable new file mode 100644 index 00000000000..cb7b26a6be6 --- /dev/null +++ b/changelog/fix-6714-request-button-virtual-variable @@ -0,0 +1,4 @@ +Significance: patch +Type: fix + +Virtual variable products no longer require shipping details when checking out with Apple Pay and Google Pay diff --git a/client/payment-request/index.js b/client/payment-request/index.js index 8596874a4eb..e9c77679c61 100644 --- a/client/payment-request/index.js +++ b/client/payment-request/index.js @@ -381,14 +381,37 @@ jQuery( ( $ ) => { $.when( wcpayPaymentRequest.getSelectedProductData() ) .then( ( response ) => { - $.when( - paymentRequest.update( { - total: response.total, - displayItems: response.displayItems, - } ) - ).then( () => { + // If a variation doesn't need shipping, re-init the `wcpayPaymentRequest` with response params. + if ( + wcpayPaymentRequestParams.product.needs_shipping !== + response.needs_shipping + ) { + wcpayPaymentRequestParams.product.needs_shipping = + response.needs_shipping; + wcpayPaymentRequestParams.product.total = + response.total; + wcpayPaymentRequestParams.product.displayItems = + response.displayItems; + wcpayPaymentRequest.init(); wcpayPaymentRequest.unblockPaymentRequestButton(); - } ); + } else { + const responseTotal = response.total; + + // If a variation `needs_shipping` is `false`, the `pending` param needs to be set to `false`. + // Because the additional shipping address call is not executed to set the pending to `false`. + if ( response.needs_shipping === false ) { + responseTotal.pending = false; + } + + $.when( + paymentRequest.update( { + total: responseTotal, + displayItems: response.displayItems, + } ) + ).then( () => { + wcpayPaymentRequest.unblockPaymentRequestButton(); + } ); + } } ) .catch( () => { wcpayPaymentRequest.hide(); From 666d8c16bc2d792416aaba4629ad61ab5d81ce2f Mon Sep 17 00:00:00 2001 From: Jesse Pearson Date: Tue, 3 Oct 2023 10:43:43 -0300 Subject: [PATCH 3/6] Move hooks out of MultiCurrency class constructors into own init_hooks methods (#7330) Co-authored-by: Marcin Bot Co-authored-by: Marcin Bot Co-authored-by: Allie Mims <60988591+allie500@users.noreply.github.com> --- ...move-hooks-from-multi-currency-constructor | 4 +++ dev/phpcs/ruleset.xml | 3 -- includes/multi-currency/AdminNotices.php | 6 ++-- includes/multi-currency/BackendCurrencies.php | 8 ++++- .../multi-currency/CurrencySwitcherBlock.php | 7 ++++ .../multi-currency/FrontendCurrencies.php | 7 ++++ includes/multi-currency/FrontendPrices.php | 7 ++++ .../Helpers/OrderMetaHelper.php | 25 +++++++------ includes/multi-currency/MultiCurrency.php | 36 ++++++++++++++++--- .../PaymentMethodsCompatibility.php | 7 ++++ includes/multi-currency/Settings.php | 11 ++++-- .../multi-currency/SettingsOnboardCta.php | 11 ++++-- includes/multi-currency/Tracking.php | 7 ++++ includes/multi-currency/UserSettings.php | 7 ++++ .../test-class-admin-notices.php | 1 + .../test-class-backend-currencies.php | 3 ++ .../test-class-currency-switcher-block.php | 1 + .../test-class-frontend-currencies.php | 1 + .../test-class-frontend-prices.php | 1 + ...st-class-payment-methods-compatibility.php | 1 + .../multi-currency/test-class-settings.php | 4 +-- .../multi-currency/test-class-tracking.php | 1 + .../test-class-user-settings.php | 1 + 23 files changed, 129 insertions(+), 31 deletions(-) create mode 100644 changelog/dev-7258-remove-hooks-from-multi-currency-constructor diff --git a/changelog/dev-7258-remove-hooks-from-multi-currency-constructor b/changelog/dev-7258-remove-hooks-from-multi-currency-constructor new file mode 100644 index 00000000000..caba16f39ee --- /dev/null +++ b/changelog/dev-7258-remove-hooks-from-multi-currency-constructor @@ -0,0 +1,4 @@ +Significance: patch +Type: dev + +Move hooks out of MultiCurrency constructor into own init_hooks method. diff --git a/dev/phpcs/ruleset.xml b/dev/phpcs/ruleset.xml index 3072f03bf4a..980e13b37cd 100644 --- a/dev/phpcs/ruleset.xml +++ b/dev/phpcs/ruleset.xml @@ -2,9 +2,6 @@ WCPay custom coding standards. - - */includes/multi-currency/* - */includes/subscriptions/* */includes/compat/subscriptions/* diff --git a/includes/multi-currency/AdminNotices.php b/includes/multi-currency/AdminNotices.php index 49612a450f4..cd9055fa2fe 100644 --- a/includes/multi-currency/AdminNotices.php +++ b/includes/multi-currency/AdminNotices.php @@ -21,9 +21,11 @@ class AdminNotices { private $notices = []; /** - * Constructor + * Initializes this class' WP hooks. + * + * @return void */ - public function __construct() { + public function init_hooks() { add_action( 'admin_notices', [ $this, 'admin_notices' ] ); add_action( 'wp_loaded', [ $this, 'hide_notices' ] ); } diff --git a/includes/multi-currency/BackendCurrencies.php b/includes/multi-currency/BackendCurrencies.php index ccdf1636841..9ea009ac4c4 100644 --- a/includes/multi-currency/BackendCurrencies.php +++ b/includes/multi-currency/BackendCurrencies.php @@ -45,7 +45,14 @@ class BackendCurrencies { public function __construct( MultiCurrency $multi_currency, WC_Payments_Localization_Service $localization_service ) { $this->multi_currency = $multi_currency; $this->localization_service = $localization_service; + } + /** + * Initializes this class' WP hooks. + * + * @return void + */ + public function init_hooks() { // Skip if no additional currencies are enabled. if ( ! $this->multi_currency->has_additional_currencies_enabled() ) { return; @@ -60,7 +67,6 @@ public function __construct( MultiCurrency $multi_currency, WC_Payments_Localiza // Currency hooks. Be aware that this should not run after Explicit Price hook, its priority should be less // than explicit price hooks to run before them. add_filter( 'wc_price_args', [ $this, 'build_wc_price_args' ], 50 ); - } } diff --git a/includes/multi-currency/CurrencySwitcherBlock.php b/includes/multi-currency/CurrencySwitcherBlock.php index 3b498fe7e58..2dd7029386f 100644 --- a/includes/multi-currency/CurrencySwitcherBlock.php +++ b/includes/multi-currency/CurrencySwitcherBlock.php @@ -42,7 +42,14 @@ class CurrencySwitcherBlock { public function __construct( MultiCurrency $multi_currency, Compatibility $compatibility ) { $this->multi_currency = $multi_currency; $this->compatibility = $compatibility; + } + /** + * Initializes this class' WP hooks. + * + * @return void + */ + public function init_hooks() { add_action( 'init', [ $this, 'init_block_widget' ] ); } diff --git a/includes/multi-currency/FrontendCurrencies.php b/includes/multi-currency/FrontendCurrencies.php index 13b86f22b7f..7a75254d854 100644 --- a/includes/multi-currency/FrontendCurrencies.php +++ b/includes/multi-currency/FrontendCurrencies.php @@ -99,7 +99,14 @@ public function __construct( MultiCurrency $multi_currency, WC_Payments_Localiza $this->localization_service = $localization_service; $this->utils = $utils; $this->compatibility = $compatibility; + } + /** + * Initializes this class' WP hooks. + * + * @return void + */ + public function init_hooks() { if ( ! is_admin() && ! defined( 'DOING_CRON' ) && ! Utils::is_admin_api_request() ) { // Currency hooks. add_filter( 'woocommerce_currency', [ $this, 'get_woocommerce_currency' ], 900 ); diff --git a/includes/multi-currency/FrontendPrices.php b/includes/multi-currency/FrontendPrices.php index 0c9dbefa950..f1975387d42 100644 --- a/includes/multi-currency/FrontendPrices.php +++ b/includes/multi-currency/FrontendPrices.php @@ -38,7 +38,14 @@ class FrontendPrices { public function __construct( MultiCurrency $multi_currency, Compatibility $compatibility ) { $this->multi_currency = $multi_currency; $this->compatibility = $compatibility; + } + /** + * Initializes this class' WP hooks. + * + * @return void + */ + public function init_hooks() { if ( ! is_admin() && ! defined( 'DOING_CRON' ) && ! Utils::is_admin_api_request() ) { // Simple product price hooks. add_filter( 'woocommerce_product_get_price', [ $this, 'get_product_price_string' ], 99, 2 ); diff --git a/includes/multi-currency/Helpers/OrderMetaHelper.php b/includes/multi-currency/Helpers/OrderMetaHelper.php index 02ecc812e00..64e53e3c80a 100644 --- a/includes/multi-currency/Helpers/OrderMetaHelper.php +++ b/includes/multi-currency/Helpers/OrderMetaHelper.php @@ -39,7 +39,18 @@ class OrderMetaHelper { */ public function __construct( WC_Payments_API_Client $payments_api_client ) { $this->payments_api_client = $payments_api_client; - $this->add_actions(); + } + + /** + * Initializes this class' WP hooks. + * + * @return void + */ + public function init_hooks() { + add_action( 'add_meta_boxes', [ $this, 'maybe_add_meta_box' ], 10, 2 ); + add_action( 'save_post', [ $this, 'maybe_update_exchange_rate' ] ); + add_action( 'admin_notices', [ $this, 'maybe_output_errors' ] ); + add_filter( 'get_edit_post_link', [ $this, 'maybe_update_edit_post_link' ] ); } /** @@ -325,18 +336,6 @@ public function maybe_update_edit_post_link( $url ): string { return $url; } - /** - * Adds our actions and hooks. - * - * @return void - */ - private function add_actions() { - add_action( 'add_meta_boxes', [ $this, 'maybe_add_meta_box' ], 10, 2 ); - add_action( 'save_post', [ $this, 'maybe_update_exchange_rate' ] ); - add_action( 'admin_notices', [ $this, 'maybe_output_errors' ] ); - add_filter( 'get_edit_post_link', [ $this, 'maybe_update_edit_post_link' ] ); - } - /** * Checks to see if the feature is enabled by the request parameter. * diff --git a/includes/multi-currency/MultiCurrency.php b/includes/multi-currency/MultiCurrency.php index ac0d8c49c18..c758170e92d 100644 --- a/includes/multi-currency/MultiCurrency.php +++ b/includes/multi-currency/MultiCurrency.php @@ -197,6 +197,7 @@ class MultiCurrency { public static function instance() { if ( is_null( self::$instance ) ) { self::$instance = new self( WC_Payments::get_payments_api_client(), WC_Payments::get_account_service(), WC_Payments::get_localization_service(), WC_Payments::get_database_cache() ); + self::$instance->init_hooks(); } return self::$instance; } @@ -220,7 +221,14 @@ public function __construct( WC_Payments_API_Client $payments_api_client, WC_Pay $this->geolocation = new Geolocation( $this->localization_service ); $this->compatibility = new Compatibility( $this, $this->utils ); $this->currency_switcher_block = new CurrencySwitcherBlock( $this, $this->compatibility ); + } + /** + * Initializes this class' WP hooks. + * + * @return void + */ + public function init_hooks() { if ( is_admin() && current_user_can( 'manage_woocommerce' ) ) { add_filter( 'woocommerce_get_settings_pages', [ $this, 'init_settings_pages' ] ); // Enqueue the scripts after the main WC_Payments_Admin does. @@ -241,6 +249,8 @@ public function __construct( WC_Payments_API_Client $payments_api_client, WC_Pay add_action( 'init', [ $this, 'possible_simulation_activation' ], 13 ); add_action( 'woocommerce_created_customer', [ $this, 'set_new_customer_currency_meta' ] ); } + + $this->currency_switcher_block->init_hooks(); } /** @@ -266,9 +276,9 @@ public function init() { $this->update_manual_rate_currencies_notice_option(); } - new PaymentMethodsCompatibility( $this, WC_Payments::get_gateway() ); - new AdminNotices(); - new UserSettings( $this ); + $payment_method_compat = new PaymentMethodsCompatibility( $this, WC_Payments::get_gateway() ); + $admin_notices = new AdminNotices(); + $user_settings = new UserSettings( $this ); new Analytics( $this ); $this->frontend_prices = new FrontendPrices( $this, $this->compatibility ); @@ -277,6 +287,16 @@ public function init() { $this->tracking = new Tracking( $this ); $this->order_meta_helper = new OrderMetaHelper( $this->payments_api_client ); + // Init all of the hooks. + $payment_method_compat->init_hooks(); + $admin_notices->init_hooks(); + $user_settings->init_hooks(); + $this->frontend_prices->init_hooks(); + $this->frontend_currencies->init_hooks(); + $this->backend_currencies->init_hooks(); + $this->tracking->init_hooks(); + $this->order_meta_helper->init_hooks(); + add_action( 'woocommerce_order_refunded', [ $this, 'add_order_meta_on_refund' ], 50, 2 ); // Check to make sure there are enabled currencies, then for Storefront being active, and then load the integration. @@ -331,9 +351,15 @@ public function init_settings_pages( $settings_pages ): array { } if ( $this->payments_account->is_stripe_connected() ) { - $settings_pages[] = new Settings( $this ); + $settings = new Settings( $this ); + $settings->init_hooks(); + + $settings_pages[] = $settings; } else { - $settings_pages[] = new SettingsOnboardCta( $this ); + $settings_onboard_cta = new SettingsOnboardCta( $this ); + $settings_onboard_cta->init_hooks(); + + $settings_pages[] = $settings_onboard_cta; } return $settings_pages; diff --git a/includes/multi-currency/PaymentMethodsCompatibility.php b/includes/multi-currency/PaymentMethodsCompatibility.php index 864e533c600..7b75d81c4c7 100644 --- a/includes/multi-currency/PaymentMethodsCompatibility.php +++ b/includes/multi-currency/PaymentMethodsCompatibility.php @@ -40,7 +40,14 @@ class PaymentMethodsCompatibility { public function __construct( MultiCurrency $multi_currency, WC_Payment_Gateway_WCPay $gateway ) { $this->multi_currency = $multi_currency; $this->gateway = $gateway; + } + /** + * Initializes this class' WP hooks. + * + * @return void + */ + public function init_hooks() { add_action( 'update_option_woocommerce_woocommerce_payments_settings', [ $this, 'add_missing_currencies' ] diff --git a/includes/multi-currency/Settings.php b/includes/multi-currency/Settings.php index e4309c8690e..11c74d56619 100644 --- a/includes/multi-currency/Settings.php +++ b/includes/multi-currency/Settings.php @@ -45,11 +45,18 @@ public function __construct( MultiCurrency $multi_currency ) { $this->id = $this->multi_currency->id; $this->label = _x( 'Multi-currency', 'Settings tab label', 'woocommerce-payments' ); + parent::__construct(); + } + + /** + * Initializes this class' WP hooks. + * + * @return void + */ + public function init_hooks() { // TODO: Only register emoji script in settings page. Until WC Admin decide if they will enable it too: https://github.com/woocommerce/woocommerce-admin/issues/6388. add_action( 'admin_print_scripts', [ $this, 'maybe_add_print_emoji_detection_script' ] ); add_action( 'woocommerce_admin_field_wcpay_multi_currency_settings_page', [ $this, 'wcpay_multi_currency_settings_page' ] ); - - parent::__construct(); } /** diff --git a/includes/multi-currency/SettingsOnboardCta.php b/includes/multi-currency/SettingsOnboardCta.php index dbe7fa15fb7..835bcdc7f01 100644 --- a/includes/multi-currency/SettingsOnboardCta.php +++ b/includes/multi-currency/SettingsOnboardCta.php @@ -37,11 +37,18 @@ public function __construct( MultiCurrency $multi_currency ) { $this->id = $this->multi_currency->id; $this->label = _x( 'Multi-currency', 'Settings tab label', 'woocommerce-payments' ); - add_action( 'woocommerce_admin_field_wcpay_currencies_settings_onboarding_cta', [ $this, 'currencies_settings_onboarding_cta' ] ); - parent::__construct(); } + /** + * Initializes this class' WP hooks. + * + * @return void + */ + public function init_hooks() { + add_action( 'woocommerce_admin_field_wcpay_currencies_settings_onboarding_cta', [ $this, 'currencies_settings_onboarding_cta' ] ); + } + /** * Output the call to action button if needing to onboard. */ diff --git a/includes/multi-currency/Tracking.php b/includes/multi-currency/Tracking.php index d90f64ca913..c34d3ffc47e 100644 --- a/includes/multi-currency/Tracking.php +++ b/includes/multi-currency/Tracking.php @@ -27,7 +27,14 @@ class Tracking { */ public function __construct( MultiCurrency $multi_currency ) { $this->multi_currency = $multi_currency; + } + /** + * Initializes this class' WP hooks. + * + * @return void + */ + public function init_hooks() { add_filter( 'woocommerce_tracker_data', [ $this, 'add_tracker_data' ], 50 ); } diff --git a/includes/multi-currency/UserSettings.php b/includes/multi-currency/UserSettings.php index be33c2d3b71..185c715e5b3 100644 --- a/includes/multi-currency/UserSettings.php +++ b/includes/multi-currency/UserSettings.php @@ -28,7 +28,14 @@ class UserSettings { */ public function __construct( MultiCurrency $multi_currency ) { $this->multi_currency = $multi_currency; + } + /** + * Initializes this class' WP hooks. + * + * @return void + */ + public function init_hooks() { // Only show currency selector if more than one currency is enabled. if ( 1 < count( $this->multi_currency->get_enabled_currencies() ) ) { add_action( 'woocommerce_edit_account_form', [ $this, 'add_presentment_currency_switch' ] ); diff --git a/tests/unit/multi-currency/test-class-admin-notices.php b/tests/unit/multi-currency/test-class-admin-notices.php index 10b4d055a32..31e5b3504b6 100644 --- a/tests/unit/multi-currency/test-class-admin-notices.php +++ b/tests/unit/multi-currency/test-class-admin-notices.php @@ -23,6 +23,7 @@ public function set_up() { parent::set_up(); $this->admin_notices = new WCPay\MultiCurrency\AdminNotices(); + $this->admin_notices->init_hooks(); } public function test_admin_notices_displays_currency_changed_notice() { diff --git a/tests/unit/multi-currency/test-class-backend-currencies.php b/tests/unit/multi-currency/test-class-backend-currencies.php index 9601dec5afb..530efc71b7d 100644 --- a/tests/unit/multi-currency/test-class-backend-currencies.php +++ b/tests/unit/multi-currency/test-class-backend-currencies.php @@ -43,6 +43,7 @@ public function set_up() { set_current_screen( 'edit-post' ); $this->backend_currencies = new BackendCurrencies( $this->mock_multi_currency, $this->mock_localization_service ); + $this->backend_currencies->init_hooks(); } public function tear_down() { @@ -74,6 +75,7 @@ public function test_registers_woocommerce_filter_with_multiple_enabled_currenci ->method( 'has_additional_currencies_enabled' ) ->willReturn( true ); $this->backend_currencies = new BackendCurrencies( $this->mock_multi_currency, $this->mock_localization_service ); + $this->backend_currencies->init_hooks(); $this->assertGreaterThan( 10, @@ -89,6 +91,7 @@ public function test_doesnt_register_woocommerce_filter_on_frontend( $filter, $f $this->tear_down(); $this->backend_currencies = new BackendCurrencies( $this->mock_multi_currency, $this->mock_localization_service ); + $this->backend_currencies->init_hooks(); $this->assertFalse( has_filter( $filter, [ $this->backend_currencies, $function_name ] ), diff --git a/tests/unit/multi-currency/test-class-currency-switcher-block.php b/tests/unit/multi-currency/test-class-currency-switcher-block.php index 843662ab39a..5e42e7e6659 100644 --- a/tests/unit/multi-currency/test-class-currency-switcher-block.php +++ b/tests/unit/multi-currency/test-class-currency-switcher-block.php @@ -52,6 +52,7 @@ public function set_up() { $this->mock_multi_currency, $this->mock_compatibility ); + $this->currency_switcher_block->init_hooks(); } /** diff --git a/tests/unit/multi-currency/test-class-frontend-currencies.php b/tests/unit/multi-currency/test-class-frontend-currencies.php index fbf24d404a2..ea7302e7c29 100644 --- a/tests/unit/multi-currency/test-class-frontend-currencies.php +++ b/tests/unit/multi-currency/test-class-frontend-currencies.php @@ -66,6 +66,7 @@ public function set_up() { ->willReturn( new Currency( 'USD' ) ); $this->frontend_currencies = new FrontendCurrencies( $this->mock_multi_currency, $this->mock_localization_service, $this->mock_utils, $this->mock_compatibility ); + $this->frontend_currencies->init_hooks(); } public function tear_down() { diff --git a/tests/unit/multi-currency/test-class-frontend-prices.php b/tests/unit/multi-currency/test-class-frontend-prices.php index 2a1e8cac6b7..db34cc1b40d 100644 --- a/tests/unit/multi-currency/test-class-frontend-prices.php +++ b/tests/unit/multi-currency/test-class-frontend-prices.php @@ -40,6 +40,7 @@ public function set_up() { $this->mock_multi_currency = $this->createMock( WCPay\MultiCurrency\MultiCurrency::class ); $this->frontend_prices = new WCPay\MultiCurrency\FrontendPrices( $this->mock_multi_currency, $this->mock_compatibility ); + $this->frontend_prices->init_hooks(); } public function tear_down() { diff --git a/tests/unit/multi-currency/test-class-payment-methods-compatibility.php b/tests/unit/multi-currency/test-class-payment-methods-compatibility.php index 2dfa1db645b..b71c305ef2d 100644 --- a/tests/unit/multi-currency/test-class-payment-methods-compatibility.php +++ b/tests/unit/multi-currency/test-class-payment-methods-compatibility.php @@ -59,6 +59,7 @@ public function set_up() { ->getMock(); $this->payment_methods_compatibility = new \WCPay\MultiCurrency\PaymentMethodsCompatibility( $this->multi_currency_mock, $this->gateway_mock ); + $this->payment_methods_compatibility->init_hooks(); add_filter( 'pre_option__wcpay_feature_upe', [ $this, 'mock_upe_flag' ], 50, 3 ); } diff --git a/tests/unit/multi-currency/test-class-settings.php b/tests/unit/multi-currency/test-class-settings.php index 7c49ec8e14c..1320ae9f0de 100644 --- a/tests/unit/multi-currency/test-class-settings.php +++ b/tests/unit/multi-currency/test-class-settings.php @@ -36,15 +36,13 @@ public function set_up() { // The settings pages file is only included in woocommerce_get_settings_pages, so we need to manually include it here. $this->settings = new WCPay\MultiCurrency\Settings( $this->mock_multi_currency ); + $this->settings->init_hooks(); } /** * @dataProvider woocommerce_action_provider */ public function test_registers_internal_actions_with_account( $action, $function_name ) { - // Init Settings again to get proper registration of hooks/filters. - $this->settings = new WCPay\MultiCurrency\Settings( $this->mock_multi_currency ); - $this->assertNotFalse( has_action( $action, [ $this->settings, $function_name ] ), "Action '$action' was not registered with '$function_name'" diff --git a/tests/unit/multi-currency/test-class-tracking.php b/tests/unit/multi-currency/test-class-tracking.php index 754d64399f4..af8fcccc41f 100644 --- a/tests/unit/multi-currency/test-class-tracking.php +++ b/tests/unit/multi-currency/test-class-tracking.php @@ -113,6 +113,7 @@ public function set_up() { ->willReturn( $this->mock_default_currency ); $this->tracking = new WCPay\MultiCurrency\Tracking( $this->mock_multi_currency ); + $this->tracking->init_hooks(); } public function tear_down() { diff --git a/tests/unit/multi-currency/test-class-user-settings.php b/tests/unit/multi-currency/test-class-user-settings.php index 97f3dacb10d..24026b71b94 100644 --- a/tests/unit/multi-currency/test-class-user-settings.php +++ b/tests/unit/multi-currency/test-class-user-settings.php @@ -43,6 +43,7 @@ public function set_up() { ); $this->user_settings = new WCPay\MultiCurrency\UserSettings( $this->mock_multi_currency ); + $this->user_settings->init_hooks(); } public function test_add_presentment_currency_switch_renders_markup() { From a10f4c05386e95438eb335ada92d6b577917eced Mon Sep 17 00:00:00 2001 From: Mike Moore Date: Tue, 3 Oct 2023 11:10:56 -0400 Subject: [PATCH 4/6] Add tests for set_payment_method_title_for_email function (#7331) Co-authored-by: Timur Karimov --- changelog/dev-7285-test-payment-method-title | 5 + .../test-class-upe-payment-gateway.php | 108 ++++++++++++++++-- 2 files changed, 106 insertions(+), 7 deletions(-) create mode 100644 changelog/dev-7285-test-payment-method-title diff --git a/changelog/dev-7285-test-payment-method-title b/changelog/dev-7285-test-payment-method-title new file mode 100644 index 00000000000..a825d60b99e --- /dev/null +++ b/changelog/dev-7285-test-payment-method-title @@ -0,0 +1,5 @@ +Significance: patch +Type: dev +Comment: Adding a few unit tests + + diff --git a/tests/unit/payment-methods/test-class-upe-payment-gateway.php b/tests/unit/payment-methods/test-class-upe-payment-gateway.php index 631cd87cef9..07c1e1214d3 100644 --- a/tests/unit/payment-methods/test-class-upe-payment-gateway.php +++ b/tests/unit/payment-methods/test-class-upe-payment-gateway.php @@ -93,11 +93,11 @@ class UPE_Payment_Gateway_Test extends WCPAY_UnitTestCase { private $mock_rate_limiter; /** - * WC_Payments_Order_Service. + * Mock WC_Payments_Order_Service. * - * @var WC_Payments_Order_Service + * @var WC_Payments_Order_Service|PHPUnit_Framework_MockObject_MockObject */ - private $order_service; + private $mock_order_service; /** * Array of mock UPE payment methods. @@ -240,7 +240,18 @@ public function set_up() { $this->mock_payment_methods[ $mock_payment_method->get_id() ] = $mock_payment_method; } - $this->order_service = new WC_Payments_Order_Service( $this->mock_api_client ); + $this->mock_order_service = $this->getMockBuilder( WC_Payments_Order_Service::class ) + ->setConstructorArgs( + [ + $this->mock_api_client, + ] + ) + ->setMethods( + [ + 'get_payment_method_id_for_order', + ] + ) + ->getMock(); // Arrange: Mock UPE_Payment_Gateway so that some of its methods can be // mocked, and their return values can be used for testing. @@ -254,7 +265,7 @@ public function set_up() { $this->mock_action_scheduler_service, $this->mock_payment_methods, $this->mock_rate_limiter, - $this->order_service, + $this->mock_order_service, $this->mock_dpps, $this->mock_localization_service, ] @@ -1444,6 +1455,89 @@ public function test_correct_payment_method_title_for_order() { } } + public function test_set_payment_method_title_for_email_updates_title() { + $mock_visa_details = [ + 'type' => 'card', + 'card' => [ + 'network' => 'visa', + 'funding' => 'debit', + ], + ]; + + $this->mock_order_service + ->expects( $this->once() ) + ->method( 'get_payment_method_id_for_order' ) + ->will( + $this->returnValue( 'pm_XXXXXXX' ) + ); + + $this->mock_api_client + ->expects( $this->once() ) + ->method( 'get_payment_method' ) + ->will( + $this->returnValue( $mock_visa_details ) + ); + + $order = WC_Helper_Order::create_order(); + $order->set_payment_method( 'woocommerce_payments' ); + $order->set_payment_method_title( 'Popular Payment Methods' ); + + $this->mock_upe_gateway->set_payment_method_title_for_email( $order ); + $this->assertEquals( 'Visa debit card', $order->get_payment_method_title() ); + } + + public function test_correct_payment_method_title_for_order_when_set_for_email() { + $payment_methods = [ + 'cheque' => 'Check payments', + 'cod' => 'Cash on delivery', + 'bacs' => 'Direct bank transfer', + ]; + + // Emulates order creation which sets the payment method and title. + $order = WC_Helper_Order::create_order(); + + foreach ( $payment_methods as $method => $title ) { + $order->set_payment_method( $method ); + $order->set_payment_method_title( $title ); + + $this->mock_upe_gateway->set_payment_method_title_for_email( $order ); + $this->assertEquals( $title, $order->get_payment_method_title() ); + } + } + + public function test_set_payment_method_title_for_email_fallback() { + $this->mock_order_service + ->expects( $this->once() ) + ->method( 'get_payment_method_id_for_order' ) + ->will( + $this->returnValue( '' ) + ); + + $order = WC_Helper_Order::create_order(); + $order->set_payment_method( 'woocommerce_payments' ); + $order->set_payment_method_title( 'Popular Payment Methods' ); + + $this->mock_upe_gateway->set_payment_method_title_for_email( $order ); + $this->assertEquals( 'WooPayments', $order->get_payment_method_title() ); + } + + public function test_set_payment_method_title_for_email_only_runs_for_legacy_upe() { + update_option( '_wcpay_feature_upe', '0' ); + update_option( '_wcpay_feature_upe_split', '1' ); + + // set_payment_method_title_for_email should return before this functions runs. + $this->mock_order_service + ->expects( $this->never() ) + ->method( 'get_payment_method_id_for_order' ); + + $order = WC_Helper_Order::create_order(); + $order->set_payment_method( 'woocommerce_payments' ); + $order->set_payment_method_title( 'Credit / Debit Card' ); + + $this->mock_upe_gateway->set_payment_method_title_for_email( $order ); + $this->assertEquals( 'Credit / Debit Card', $order->get_payment_method_title() ); + } + public function test_payment_methods_show_correct_default_outputs() { $mock_token = WC_Helper_Token::create_token( 'pm_mock' ); $this->mock_token_service->expects( $this->any() ) @@ -1977,7 +2071,7 @@ public function test_remove_link_payment_method_if_card_disabled() { $this->mock_action_scheduler_service, $this->mock_payment_methods, $this->mock_rate_limiter, - $this->order_service, + $this->mock_order_service, $this->mock_dpps, $this->mock_localization_service, ] @@ -2026,7 +2120,7 @@ public function test_link_payment_method_if_card_enabled() { $this->mock_action_scheduler_service, $this->mock_payment_methods, $this->mock_rate_limiter, - $this->order_service, + $this->mock_order_service, $this->mock_dpps, $this->mock_localization_service, ] From 1e696f8fc6e6c3bc016d094e8c556d2a4b9260d2 Mon Sep 17 00:00:00 2001 From: Rua Haszard Date: Wed, 4 Oct 2023 11:53:08 +1300 Subject: [PATCH 5/6] add a new page component for redirecting disputes => details: (#7310) Co-authored-by: Rua Haszard Co-authored-by: Eric Jinks <3147296+Jinksi@users.noreply.github.com> --- ...891-redirect-dispute-detail-to-transaction | 4 + client/data/disputes/action-types.js | 1 + client/data/disputes/actions.js | 9 +++ client/data/disputes/hooks.ts | 15 ++-- client/data/disputes/reducer.js | 8 +- client/data/disputes/resolvers.js | 2 + client/data/disputes/selectors.js | 5 ++ client/data/disputes/test/resolvers.js | 4 + client/disputes/details/index.tsx | 4 +- .../redirect-to-transaction-details/index.tsx | 76 +++++++++++++++++++ .../style.scss | 9 +++ client/index.js | 17 ++++- includes/admin/class-wc-payments-admin.php | 7 +- 13 files changed, 149 insertions(+), 12 deletions(-) create mode 100644 changelog/fix-6891-redirect-dispute-detail-to-transaction create mode 100644 client/disputes/redirect-to-transaction-details/index.tsx create mode 100644 client/disputes/redirect-to-transaction-details/style.scss diff --git a/changelog/fix-6891-redirect-dispute-detail-to-transaction b/changelog/fix-6891-redirect-dispute-detail-to-transaction new file mode 100644 index 00000000000..1a7a59f3d4e --- /dev/null +++ b/changelog/fix-6891-redirect-dispute-detail-to-transaction @@ -0,0 +1,4 @@ +Significance: patch +Type: dev + +This work is part of a UI improvements to increase disputes response that is behind a feature flag. A changelog entry will be added to represent the work as a whole. diff --git a/client/data/disputes/action-types.js b/client/data/disputes/action-types.js index a88cdbdc02c..318d331c84c 100644 --- a/client/data/disputes/action-types.js +++ b/client/data/disputes/action-types.js @@ -2,6 +2,7 @@ export default { SET_DISPUTE: 'SET_DISPUTE', + SET_ERROR_FOR_DISPUTE: 'SET_ERROR_FOR_DISPUTE', SET_DISPUTES: 'SET_DISPUTES', SET_DISPUTES_SUMMARY: 'SET_DISPUTES_SUMMARY', }; diff --git a/client/data/disputes/actions.js b/client/data/disputes/actions.js index 7e099b440f3..4a0f82197e1 100644 --- a/client/data/disputes/actions.js +++ b/client/data/disputes/actions.js @@ -23,6 +23,15 @@ export function updateDispute( data ) { }; } +export function updateErrorForDispute( id, data, error ) { + return { + type: TYPES.SET_ERROR_FOR_DISPUTE, + id, + data, + error, + }; +} + export function updateDisputes( query, data ) { return { type: TYPES.SET_DISPUTES, diff --git a/client/data/disputes/hooks.ts b/client/data/disputes/hooks.ts index 256faf30152..e3797499537 100644 --- a/client/data/disputes/hooks.ts +++ b/client/data/disputes/hooks.ts @@ -15,6 +15,7 @@ import type { CachedDisputes, DisputesSummary, } from 'wcpay/types/disputes'; +import type { ApiError } from 'wcpay/types/errors'; import { STORE_NAME } from '../constants'; import { disputeAwaitingResponseStatuses } from 'wcpay/disputes/filters/config'; @@ -25,16 +26,20 @@ import { disputeAwaitingResponseStatuses } from 'wcpay/disputes/filters/config'; export const useDispute = ( id: string ): { - dispute: Dispute; + dispute?: Dispute; + error?: ApiError; isLoading: boolean; doAccept: () => void; } => { - const { dispute, isLoading } = useSelect( + const { dispute, error, isLoading } = useSelect( ( select ) => { - const { getDispute, isResolving } = select( STORE_NAME ); + const { getDispute, getDisputeError, isResolving } = select( + STORE_NAME + ); return { - dispute: getDispute( id ), + dispute: getDispute( id ), + error: getDisputeError( id ), isLoading: isResolving( 'getDispute', [ id ] ), }; }, @@ -44,7 +49,7 @@ export const useDispute = ( const { acceptDispute } = useDispatch( STORE_NAME ); const doAccept = () => acceptDispute( id ); - return { dispute, isLoading, doAccept }; + return { dispute, isLoading, error, doAccept }; }; /** diff --git a/client/data/disputes/reducer.js b/client/data/disputes/reducer.js index 3312bb2b9f9..f6b88f90452 100644 --- a/client/data/disputes/reducer.js +++ b/client/data/disputes/reducer.js @@ -15,7 +15,7 @@ const defaultState = { byId: {}, queries: {}, summary: {}, cached: {} }; const receiveDisputes = ( state = defaultState, - { type, query = {}, data = [] } + { type, query = {}, data = [], id, error } ) => { const index = getResourceId( query ); @@ -25,6 +25,12 @@ const receiveDisputes = ( ...state, byId: { ...state.byId, [ data.id ]: data }, }; + case TYPES.SET_ERROR_FOR_DISPUTE: + state = { + ...state, + byId: { ...state.byId, [ id ]: { error } }, + }; + break; case TYPES.SET_DISPUTES: return { ...state, diff --git a/client/data/disputes/resolvers.js b/client/data/disputes/resolvers.js index 3676df92d60..ee82f790c51 100644 --- a/client/data/disputes/resolvers.js +++ b/client/data/disputes/resolvers.js @@ -18,6 +18,7 @@ import { updateDispute, updateDisputes, updateDisputesSummary, + updateErrorForDispute, } from './actions'; const formatQueryFilters = ( query ) => ( { @@ -61,6 +62,7 @@ export function* getDispute( id ) { 'createErrorNotice', __( 'Error retrieving dispute.', 'woocommerce-payments' ) ); + yield updateErrorForDispute( id, undefined, e ); } } diff --git a/client/data/disputes/selectors.js b/client/data/disputes/selectors.js index 4bd5347c82a..b592e518298 100644 --- a/client/data/disputes/selectors.js +++ b/client/data/disputes/selectors.js @@ -26,6 +26,11 @@ export const getDispute = ( state, id ) => { return disputeById[ id ]; }; +export const getDisputeError = ( state, id ) => { + const disputeById = getDisputesState( state ).byId || {}; + return disputeById[ id ]?.error; +}; + export const getCachedDispute = ( state, id ) => { const disputeById = getDisputesState( state ).cached || {}; return disputeById[ id ]; diff --git a/client/data/disputes/test/resolvers.js b/client/data/disputes/test/resolvers.js index 5b576a65cf7..cd5538de148 100644 --- a/client/data/disputes/test/resolvers.js +++ b/client/data/disputes/test/resolvers.js @@ -13,6 +13,7 @@ import { updateDispute, updateDisputes, updateDisputesSummary, + updateErrorForDispute, } from '../actions'; import { getDispute, getDisputes, getDisputesSummary } from '../resolvers'; @@ -68,6 +69,9 @@ describe( 'getDispute resolver', () => { expect.any( String ) ) ); + expect( generator.next().value ).toEqual( + updateErrorForDispute( 'dp_mock1', undefined, errorResponse ) + ); } ); } ); } ); diff --git a/client/disputes/details/index.tsx b/client/disputes/details/index.tsx index e8e43312fcc..e8af4bbcf97 100644 --- a/client/disputes/details/index.tsx +++ b/client/disputes/details/index.tsx @@ -23,7 +23,7 @@ import { TestModeNotice, topics } from 'components/test-mode-notice'; import '../style.scss'; import { Dispute } from 'wcpay/types/disputes'; -const DisputeDetails = ( { +const LegacyDisputeDetails = ( { query: { id: disputeId }, }: { query: { id: string }; @@ -156,4 +156,4 @@ const DisputeDetails = ( { ); }; -export default DisputeDetails; +export default LegacyDisputeDetails; diff --git a/client/disputes/redirect-to-transaction-details/index.tsx b/client/disputes/redirect-to-transaction-details/index.tsx new file mode 100644 index 00000000000..87c7e7954a4 --- /dev/null +++ b/client/disputes/redirect-to-transaction-details/index.tsx @@ -0,0 +1,76 @@ +/** + * External dependencies + */ +import React, { useEffect } from 'react'; +import { getHistory } from '@woocommerce/navigation'; +import { Spinner, Icon, Flex, FlexItem } from '@wordpress/components'; + +/** + * Internal dependencies. + */ +import Page from 'components/page'; +import { useDispute } from 'data/index'; +import { Charge } from 'wcpay/types/charges'; +import { getAdminUrl } from 'wcpay/utils'; + +import './style.scss'; +import warning from 'wcpay/components/icons/warning'; + +const RedirectToTransactionDetails: React.FC< { query: { id: string } } > = ( { + query: { id: disputeId }, +} ) => { + const { dispute, error, isLoading } = useDispute( disputeId ); + + useEffect( () => { + if ( ! isLoading && dispute?.charge ) { + // Dispute type allows charge as nested object or string ID, + // so we have to hint we expect a Charge object here. + const chargeObject = dispute.charge as Charge; + const transactionDetailsUrl = getAdminUrl( { + page: 'wc-admin', + path: '/payments/transactions/details', + id: chargeObject.payment_intent, + transaction_id: chargeObject.balance_transaction, + type: 'dispute', + } ); + getHistory().replace( transactionDetailsUrl ); + } + }, [ dispute, isLoading ] ); + + return ( + + + { error ? ( + <> + + + + +
+ Error retrieving dispute +
+
Please check your network and try again.
+
+ + ) : ( + <> + + + + +
+ One moment please +
+
Redirecting to payment details…
+
+ + ) } +
+
+ ); +}; + +export default RedirectToTransactionDetails; diff --git a/client/disputes/redirect-to-transaction-details/style.scss b/client/disputes/redirect-to-transaction-details/style.scss new file mode 100644 index 00000000000..ca8fc49c8f5 --- /dev/null +++ b/client/disputes/redirect-to-transaction-details/style.scss @@ -0,0 +1,9 @@ +.wcpay-dispute-detail-legacy-redirect { + // Shift the redirect spinner to approx center of viewport. + top: 10vh; + position: relative; + + .components-flex-item { + text-align: center; + } +} diff --git a/client/index.js b/client/index.js index acb980c353e..681ff13479b 100644 --- a/client/index.js +++ b/client/index.js @@ -20,7 +20,8 @@ import DepositDetailsPage from 'deposits/details'; import TransactionsPage from 'transactions'; import PaymentDetailsPage from 'payment-details'; import DisputesPage from 'disputes'; -import DisputeDetailsPage from 'disputes/details'; +import LegacyDisputeDetailsPage from 'disputes/details'; +import RedirectToTransactionDetails from 'disputes/redirect-to-transaction-details'; import DisputeEvidencePage from 'disputes/evidence'; import AdditionalMethodsPage from 'wcpay/additional-methods-setup'; import MultiCurrencySetupPage from 'wcpay/multi-currency-setup'; @@ -150,8 +151,15 @@ addFilter( }, capability: 'manage_woocommerce', } ); + + // If disputes on transaction page feature is enabled, set up a soft + // redirect component; otherwise register the (legacy) dispute details page. + const isDisputeOnTransactionPageEnabled = + window.wcpaySettings.featureFlags.isDisputeOnTransactionPageEnabled; pages.push( { - container: DisputeDetailsPage, + container: isDisputeOnTransactionPageEnabled + ? RedirectToTransactionDetails + : LegacyDisputeDetailsPage, path: '/payments/disputes/details', wpOpenMenu: menuID, breadcrumbs: [ @@ -163,11 +171,14 @@ addFilter( __( 'Dispute details', 'woocommerce-payments' ), ], navArgs: { - id: 'wc-payments-disputes-details', + id: isDisputeOnTransactionPageEnabled + ? 'wc-payments-disputes-details-legacy-redirect' + : 'wc-payments-disputes-details', parentPath: '/payments/disputes', }, capability: 'manage_woocommerce', } ); + pages.push( { container: DisputeEvidencePage, path: '/payments/disputes/challenge', diff --git a/includes/admin/class-wc-payments-admin.php b/includes/admin/class-wc-payments-admin.php index d76a2dae6c8..25b0a0fdc40 100644 --- a/includes/admin/class-wc-payments-admin.php +++ b/includes/admin/class-wc-payments-admin.php @@ -472,14 +472,19 @@ public function add_payments_menu() { 'path' => '/payments/transactions/details', ] ); + + $is_dispute_on_transaction_page_enabled = WC_Payments_Features::is_dispute_on_transaction_page_enabled(); wc_admin_register_page( [ - 'id' => 'wc-payments-disputes-details', + 'id' => $is_dispute_on_transaction_page_enabled + ? 'wc-payments-disputes-details-legacy-redirect' + : 'wc-payments-disputes-details', 'title' => __( 'Dispute details', 'woocommerce-payments' ), 'parent' => 'wc-payments-disputes', 'path' => '/payments/disputes/details', ] ); + wc_admin_register_page( [ 'id' => 'wc-payments-disputes-challenge', From e8da91878bac29fa9da7a0b4c51e5f3fac456ce3 Mon Sep 17 00:00:00 2001 From: James Allan Date: Wed, 4 Oct 2023 12:23:58 +1000 Subject: [PATCH 6/6] Update the WooPayments and Woo Subscriptions deactivate plugin warning modals (#7323) --- ...-billing-deactivate-plugin-warning-updates | 4 ++ .../subscriptions/assets/css/plugin-page.css | 37 +++++----- .../subscriptions/assets/js/plugin-page.js | 30 ++++---- ...ts-subscriptions-plugin-notice-manager.php | 20 +++--- .../html-subscriptions-plugin-notice.php | 43 +++++++---- .../html-wcpay-deactivate-warning.php | 10 +-- .../html-woo-payments-deactivate-warning.php | 72 +++++++++++++++++++ 7 files changed, 156 insertions(+), 60 deletions(-) create mode 100644 changelog/stripe-billing-deactivate-plugin-warning-updates create mode 100644 includes/subscriptions/templates/html-woo-payments-deactivate-warning.php diff --git a/changelog/stripe-billing-deactivate-plugin-warning-updates b/changelog/stripe-billing-deactivate-plugin-warning-updates new file mode 100644 index 00000000000..fb52189cd61 --- /dev/null +++ b/changelog/stripe-billing-deactivate-plugin-warning-updates @@ -0,0 +1,4 @@ +Significance: minor +Type: update + +Update the content of modals that are displayed when deactivating the WooPayments or Woo Subscriptions plugins when the store has active Stripe Billing subscriptions. diff --git a/includes/subscriptions/assets/css/plugin-page.css b/includes/subscriptions/assets/css/plugin-page.css index 05add31edb6..b7d109e036c 100644 --- a/includes/subscriptions/assets/css/plugin-page.css +++ b/includes/subscriptions/assets/css/plugin-page.css @@ -1,4 +1,4 @@ -#wcpay-subscriptions-plugin-warning-notice .button { +.woopayments-plugin-warning-modal .button { height: 36px; align-items: center; box-sizing: border-box; @@ -7,10 +7,10 @@ line-height: normal; cursor: pointer; } -#wcpay-subscriptions-plugin-warning-notice .button-secondary { +.woopayments-plugin-warning-modal .button-secondary { background: transparent; } -#wcpay-subscriptions-plugin-warning-notice .button.busy { +.woopayments-plugin-warning-modal .button.busy { animation: wcpay-plugin-notice-submit-button-busy 3000ms infinite linear; background-image: linear-gradient( -45deg, @@ -21,59 +21,56 @@ ); background-size: 100px 100%; } -#wcpay-subscriptions-plugin-warning-notice - footer - .inner - > *:not( :first-child ) { +.woopayments-plugin-warning-modal footer .inner > *:not( :first-child ) { margin-left: 16px; } -#wcpay-subscriptions-plugin-warning-notice h1 { +.woopayments-plugin-warning-modal h1 { font-size: 1rem; font-weight: 600; line-height: 1; } -#wcpay-subscriptions-plugin-warning-notice header, -#wcpay-subscriptions-plugin-warning-notice footer { +.woopayments-plugin-warning-modal header, +.woopayments-plugin-warning-modal footer { background: initial; box-shadow: initial; } -#wcpay-subscriptions-plugin-warning-notice header { +.woopayments-plugin-warning-modal header { margin: 0 -24px; padding-top: 24px; padding-left: 24px; height: 60px; border-bottom: 1px solid #dcdcde; } -#wcpay-subscriptions-plugin-warning-notice footer { +.woopayments-plugin-warning-modal footer { padding: 24px; border-top: 1px solid #dcdcde; } -#wcpay-subscriptions-plugin-warning-notice .wc-backbone-modal-content { +.woopayments-plugin-warning-modal .wc-backbone-modal-content { border-radius: 2px; padding: 0 24px 24px; } -#wcpay-subscriptions-plugin-warning-notice .modal-close-link { +.woopayments-plugin-warning-modal .modal-close-link { height: 100%; width: 60px; border-left: none; } -#wcpay-subscriptions-plugin-warning-notice .modal-close-link:hover { +.woopayments-plugin-warning-modal .modal-close-link:hover { background: transparent; } -#wcpay-subscriptions-plugin-warning-notice article { +.woopayments-plugin-warning-modal article { padding: 1.5em 0; } -#wcpay-subscriptions-plugin-warning-notice .wc-backbone-modal-main { +.woopayments-plugin-warning-modal .wc-backbone-modal-main { padding-bottom: 60px; } -#wcpay-subscriptions-plugin-warning-notice .modal-close-link:hover::before { +.woopayments-plugin-warning-modal .modal-close-link:hover::before { color: initial; } -#wcpay-subscriptions-plugin-warning-notice ul { +.woopayments-plugin-warning-modal ul { padding-left: 24px; list-style: disc; } -#wcpay-subscriptions-plugin-warning-notice ul > li > ul { +.woopayments-plugin-warning-modal ul > li > ul { margin-top: 6px; list-style: circle; } diff --git a/includes/subscriptions/assets/js/plugin-page.js b/includes/subscriptions/assets/js/plugin-page.js index df980ddf166..5123ba5671f 100644 --- a/includes/subscriptions/assets/js/plugin-page.js +++ b/includes/subscriptions/assets/js/plugin-page.js @@ -9,13 +9,6 @@ jQuery( function ( $ ) { // Initialise handlers for WC Pay deactivate warning. init_deactivate_wcpay_warning() { - // If the store doesn't have active WCPay (Stripe Billing) subscriptions, no warning needed. - if ( - ! wcpay_subscriptions_plugin_screen_data.store_has_active_wcpay_subscriptions - ) { - return; - } - // Intercept click on WCPay deactivate link to show modal. $( '#deactivate-woocommerce-payments' ).on( 'click', @@ -47,10 +40,10 @@ jQuery( function ( $ ) { ); }, - // Initialise handlers for WC Subscriptions deactivate warning. + // Initialise handlers for Woo Subscriptions deactivate warning. init_deactivate_wc_subscriptions_warning() { - // Intercept click on WCS deactivate link to show modal. - $( '#deactivate-woocommerce-subscriptions' ).on( + // Intercept click on Woo Subscriptions deactivate link to show modal. + $( '#deactivate-' + this.get_woo_subscriptions_plugin_slug() ).on( 'click', this.display_wcs_warning ); @@ -77,9 +70,22 @@ jQuery( function ( $ ) { 'busy' ); - window.location = $( '#deactivate-woocommerce-subscriptions' ).attr( - 'href' + window.location = $( + '#deactivate-' + + wc_payments_plugin.get_woo_subscriptions_plugin_slug() + ).attr( 'href' ); + }, + // Gets the Woo Subscriptions plugin slug. When the ite is connected to WooCommerce.com, the slug is different and includes a woocommerce-com- prefix. + get_woo_subscriptions_plugin_slug() { + const element = document.querySelector( + '[data-slug="woocommerce-com-woocommerce-subscriptions"]' ); + + if ( element ) { + return 'woocommerce-com-woocommerce-subscriptions'; + } else { + return 'woocommerce-subscriptions'; + } }, }; diff --git a/includes/subscriptions/class-wc-payments-subscriptions-plugin-notice-manager.php b/includes/subscriptions/class-wc-payments-subscriptions-plugin-notice-manager.php index 1fb6dd7b523..76ce78eeaaf 100644 --- a/includes/subscriptions/class-wc-payments-subscriptions-plugin-notice-manager.php +++ b/includes/subscriptions/class-wc-payments-subscriptions-plugin-notice-manager.php @@ -41,7 +41,7 @@ private function is_admin_plugins_screen() { * Enqueues the admin scripts needed on the plugins screen. */ public function enqueue_scripts_and_styles() { - if ( ! $this->is_admin_plugins_screen() ) { + if ( ! $this->is_admin_plugins_screen() || ! WC_Payments_Subscription_Service::store_has_active_wcpay_subscriptions() ) { return; } @@ -58,12 +58,6 @@ public function enqueue_scripts_and_styles() { wp_enqueue_script( 'wcpay-subscriptions-plugin' ); - // Enqueue script data - does this store have active WCPay subscriptions? - $script_data = [ - 'store_has_active_wcpay_subscriptions' => WC_Payments_Subscription_Service::store_has_active_wcpay_subscriptions(), - ]; - wp_localize_script( 'wcpay-subscriptions-plugin', 'wcpay_subscriptions_plugin_screen_data', $script_data ); - WC_Payments_Utils::enqueue_style( 'wcpay-subscriptions-plugin-styles', plugins_url( 'includes/subscriptions/assets/css/plugin-page.css', WCPAY_PLUGIN_FILE ), @@ -77,8 +71,16 @@ public function enqueue_scripts_and_styles() { * Enqueues templates for plugin deactivation warnings on the admin plugin screen. */ public function output_notice_template() { - if ( $this->is_admin_plugins_screen() ) { - wc_get_template( 'html-subscriptions-plugin-notice.php', [], '', dirname( __DIR__ ) . '/subscriptions/templates/' ); + if ( ! $this->is_admin_plugins_screen() ) { + return; + } + + wc_get_template( 'html-subscriptions-plugin-notice.php', [], '', dirname( __DIR__ ) . '/subscriptions/templates/' ); + + // Load a slightly different notice for folks still using the legacy WCPay Subscriptions functionality. + if ( WC_Payments::get_gateway()->is_subscriptions_plugin_active() ) { + wc_get_template( 'html-woo-payments-deactivate-warning.php', [], '', dirname( __DIR__ ) . '/subscriptions/templates/' ); + } else { wc_get_template( 'html-wcpay-deactivate-warning.php', [], '', dirname( __DIR__ ) . '/subscriptions/templates/' ); } } diff --git a/includes/subscriptions/templates/html-subscriptions-plugin-notice.php b/includes/subscriptions/templates/html-subscriptions-plugin-notice.php index 0a2e8f6fa79..1d4941e5b90 100644 --- a/includes/subscriptions/templates/html-subscriptions-plugin-notice.php +++ b/includes/subscriptions/templates/html-subscriptions-plugin-notice.php @@ -7,7 +7,7 @@ ?>