From 224288c42c4b056c15436598583e2dfe4106984b Mon Sep 17 00:00:00 2001 From: James Allan Date: Mon, 18 Sep 2023 09:39:59 +1000 Subject: [PATCH 01/98] Fix issues when the Stripe Billing `is_migrating()` function would return false if the one of the actions was actively running (#7227) --- changelog/fix-subscription-migration-in-progress-check | 5 +++++ .../class-wc-payments-subscriptions-migrator.php | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 changelog/fix-subscription-migration-in-progress-check diff --git a/changelog/fix-subscription-migration-in-progress-check b/changelog/fix-subscription-migration-in-progress-check new file mode 100644 index 00000000000..650e1b1d627 --- /dev/null +++ b/changelog/fix-subscription-migration-in-progress-check @@ -0,0 +1,5 @@ +Significance: patch +Type: dev +Comment: This change fixes a bug in unreleased code. No changelog entry needed. + + diff --git a/includes/subscriptions/class-wc-payments-subscriptions-migrator.php b/includes/subscriptions/class-wc-payments-subscriptions-migrator.php index 5165653bd39..d8fa2b7738a 100644 --- a/includes/subscriptions/class-wc-payments-subscriptions-migrator.php +++ b/includes/subscriptions/class-wc-payments-subscriptions-migrator.php @@ -764,13 +764,13 @@ public function get_stripe_billing_subscription_count() { /** * Determines if a migration is currently in progress. * - * A migration is considered to be in progress if either the initial migration action or an individual subscription - * actions are scheduled. + * A migration is considered to be in progress if the initial migration action or an individual subscription + * action (or retry) is scheduled. * * @return bool True if a migration is in progress, false otherwise. */ public function is_migrating() { - return is_numeric( as_next_scheduled_action( $this->scheduled_hook ) ) || is_numeric( as_next_scheduled_action( $this->migrate_hook ) ) || is_numeric( as_next_scheduled_action( $this->migrate_hook . '_retry' ) ); + return (bool) as_next_scheduled_action( $this->scheduled_hook ) || (bool) as_next_scheduled_action( $this->migrate_hook ) || (bool) as_next_scheduled_action( $this->migrate_hook . '_retry' ); } /** From 1664440bbbcc5b65e017116ddddc06976f6e3646 Mon Sep 17 00:00:00 2001 From: Jesse Pearson Date: Mon, 18 Sep 2023 11:52:13 -0300 Subject: [PATCH 02/98] Disable automatic currency switching and switcher widgets on pay_for_order page (#7152) Co-authored-by: Taha Paksu <3295+tpaksu@users.noreply.github.com> --- ...disable-currency-switcher-on-pay-for-order | 4 ++ includes/multi-currency/Compatibility.php | 33 ++++++++++++++++- .../WooCommerceSubscriptions.php | 6 +-- .../multi-currency/CurrencySwitcherBlock.php | 10 ++++- .../multi-currency/CurrencySwitcherWidget.php | 2 +- includes/multi-currency/MultiCurrency.php | 4 +- .../test-class-woocommerce-subscriptions.php | 22 +++++------ .../test-class-compatibility.php | 27 ++++++++++++++ .../test-class-currency-switcher-block.php | 37 ++++++++++++++++++- .../test-class-currency-switcher-widget.php | 16 ++++---- .../test-class-multi-currency.php | 37 +++++++++++++++++++ 11 files changed, 167 insertions(+), 31 deletions(-) create mode 100644 changelog/fix-5031-disable-currency-switcher-on-pay-for-order diff --git a/changelog/fix-5031-disable-currency-switcher-on-pay-for-order b/changelog/fix-5031-disable-currency-switcher-on-pay-for-order new file mode 100644 index 00000000000..1a8faa30591 --- /dev/null +++ b/changelog/fix-5031-disable-currency-switcher-on-pay-for-order @@ -0,0 +1,4 @@ +Significance: minor +Type: fix + +Disable automatic currency switching and switcher widgets on pay_for_order page. diff --git a/includes/multi-currency/Compatibility.php b/includes/multi-currency/Compatibility.php index 31ecbfcb0f9..c88fc94cdcd 100644 --- a/includes/multi-currency/Compatibility.php +++ b/includes/multi-currency/Compatibility.php @@ -87,12 +87,41 @@ public function override_selected_currency() { } /** - * Checks to see if the widgets should be hidden. + * Deprecated method, please use should_disable_currency_switching. * * @return bool False if it shouldn't be hidden, true if it should. */ public function should_hide_widgets(): bool { - return apply_filters( MultiCurrency::FILTER_PREFIX . 'should_hide_widgets', false ); + wc_deprecated_function( __FUNCTION__, '6.5.0', 'Compatibility::should_disable_currency_switching' ); + return $this->should_disable_currency_switching(); + } + + /** + * Checks to see if currency switching should be disabled, such as the widgets and the automatic geolocation switching. + * + * @return bool False if no, true if yes. + */ + public function should_disable_currency_switching(): bool { + $return = false; + + /** + * If the pay_for_order parameter is set, we disable currency switching. + * + * WooCommerce itself handles all the heavy lifting and verification on the Order Pay page, we just need to + * make sure the currency switchers are not displayed. This is due to once the order is created, the currency + * itself should remain static. + */ + if ( isset( $_GET['pay_for_order'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended + $return = true; + } + + // If someone has hooked into the deprecated filter, throw a notice and then apply the filtering. + if ( has_action( MultiCurrency::FILTER_PREFIX . 'should_hide_widgets' ) ) { + wc_deprecated_hook( MultiCurrency::FILTER_PREFIX . 'should_hide_widgets', '6.5.0', MultiCurrency::FILTER_PREFIX . 'should_disable_currency_switching' ); + $return = apply_filters( MultiCurrency::FILTER_PREFIX . 'should_hide_widgets', $return ); + } + + return apply_filters( MultiCurrency::FILTER_PREFIX . 'should_disable_currency_switching', $return ); } /** diff --git a/includes/multi-currency/Compatibility/WooCommerceSubscriptions.php b/includes/multi-currency/Compatibility/WooCommerceSubscriptions.php index e63c7ea54c3..74cc36ecc15 100644 --- a/includes/multi-currency/Compatibility/WooCommerceSubscriptions.php +++ b/includes/multi-currency/Compatibility/WooCommerceSubscriptions.php @@ -51,7 +51,7 @@ protected function init() { add_filter( MultiCurrency::FILTER_PREFIX . 'override_selected_currency', [ $this, 'override_selected_currency' ], 50 ); add_filter( MultiCurrency::FILTER_PREFIX . 'should_convert_product_price', [ $this, 'should_convert_product_price' ], 50, 2 ); add_filter( MultiCurrency::FILTER_PREFIX . 'should_convert_coupon_amount', [ $this, 'should_convert_coupon_amount' ], 50, 2 ); - add_filter( MultiCurrency::FILTER_PREFIX . 'should_hide_widgets', [ $this, 'should_hide_widgets' ], 50 ); + add_filter( MultiCurrency::FILTER_PREFIX . 'should_disable_currency_switching', [ $this, 'should_disable_currency_switching' ], 50 ); } } } @@ -254,13 +254,13 @@ public function should_convert_coupon_amount( bool $return, $coupon ): bool { } /** - * Checks to see if the widgets should be hidden. + * Checks to see if currency switching should be disabled. * * @param bool $return Whether widgets should be hidden or not. Default is false. * * @return bool */ - public function should_hide_widgets( bool $return ): bool { + public function should_disable_currency_switching( bool $return ): bool { // If it's already true, return it. if ( $return ) { return $return; diff --git a/includes/multi-currency/CurrencySwitcherBlock.php b/includes/multi-currency/CurrencySwitcherBlock.php index 6caf8bf7515..92a6e7e2ad1 100644 --- a/includes/multi-currency/CurrencySwitcherBlock.php +++ b/includes/multi-currency/CurrencySwitcherBlock.php @@ -117,7 +117,13 @@ public function init_block_widget() { * @return string The content to be displayed inside the block widget. */ public function render_block_widget( $block_attributes, $content ): string { - if ( $this->compatibility->should_hide_widgets() ) { + if ( $this->compatibility->should_disable_currency_switching() ) { + return ''; + } + + $enabled_currencies = $this->multi_currency->get_enabled_currencies(); + + if ( 1 === count( $enabled_currencies ) ) { return ''; } @@ -133,7 +139,7 @@ public function render_block_widget( $block_attributes, $content ): string { $widget_content .= '
'; $widget_content .= '', $result ); $this->assertStringContainsString( '', $result ); } + + /** + * The widget should not be displayed if should_disable_currency_switching returns true. + */ + public function test_widget_does_not_render_on_hide() { + // Arrange: Set the expected call and return value for should_disable_currency_switching. + $this->mock_compatibility + ->expects( $this->once() ) + ->method( 'should_disable_currency_switching' ) + ->willReturn( true ); + + // Act/Assert: Confirm that when calling the renger method nothing is returned. + $this->assertSame( '', $this->currency_switcher_block->render_block_widget( [], '' ) ); + } + + /** + * The widget should not be displayed if there's only a single currency enabled. + */ + public function test_widget_does_not_render_on_single_currency() { + // Arrange: Set the expected call and return values for should_disable_currency_switching and get_enabled_currencies. + $this->mock_compatibility + ->expects( $this->once() ) + ->method( 'should_disable_currency_switching' ) + ->willReturn( false ); + + $this->mock_multi_currency + ->expects( $this->once() ) + ->method( 'get_enabled_currencies' ) + ->willReturn( [ new Currency( 'USD' ) ] ); + + // Act/Assert: Confirm that when calling the renger method nothing is returned. + $this->assertSame( '', $this->currency_switcher_block->render_block_widget( [], '' ) ); + } } diff --git a/tests/unit/multi-currency/test-class-currency-switcher-widget.php b/tests/unit/multi-currency/test-class-currency-switcher-widget.php index 62afd3cce34..7f6f88e299c 100644 --- a/tests/unit/multi-currency/test-class-currency-switcher-widget.php +++ b/tests/unit/multi-currency/test-class-currency-switcher-widget.php @@ -55,7 +55,7 @@ public function set_up() { } public function test_widget_renders_title_with_args() { - $this->mock_compatibility->method( 'should_hide_widgets' )->willReturn( false ); + $this->mock_compatibility->method( 'should_disable_currency_switching' )->willReturn( false ); $instance = [ 'title' => 'Test Title', ]; @@ -64,13 +64,13 @@ public function test_widget_renders_title_with_args() { } public function test_widget_renders_enabled_currencies_with_symbol() { - $this->mock_compatibility->method( 'should_hide_widgets' )->willReturn( false ); + $this->mock_compatibility->method( 'should_disable_currency_switching' )->willReturn( false ); $this->expectOutputRegex( '/value="USD">$ USD.+value="CAD">$ CAD.+value="EUR">€ EUR.+value="CHF">CHF/s' ); $this->render_widget(); } public function test_widget_renders_enabled_currencies_without_symbol() { - $this->mock_compatibility->method( 'should_hide_widgets' )->willReturn( false ); + $this->mock_compatibility->method( 'should_disable_currency_switching' )->willReturn( false ); $instance = [ 'symbol' => 0, ]; @@ -79,7 +79,7 @@ public function test_widget_renders_enabled_currencies_without_symbol() { } public function test_widget_renders_enabled_currencies_with_symbol_and_flag() { - $this->mock_compatibility->method( 'should_hide_widgets' )->willReturn( false ); + $this->mock_compatibility->method( 'should_disable_currency_switching' )->willReturn( false ); $instance = [ 'symbol' => 1, 'flag' => 1, @@ -99,20 +99,20 @@ public function test_widget_renders_hidden_input() { } public function test_widget_selects_selected_currency() { - $this->mock_compatibility->method( 'should_hide_widgets' )->willReturn( false ); + $this->mock_compatibility->method( 'should_disable_currency_switching' )->willReturn( false ); $this->mock_multi_currency->method( 'get_selected_currency' )->willReturn( new Currency( 'CAD' ) ); $this->expectOutputRegex( '/
@@ -185,7 +240,6 @@ const PaymentMethod = ( { required={ required } status={ status } disabled={ disabled } - id={ id } />
@@ -196,7 +250,6 @@ const PaymentMethod = ( { required={ required } status={ status } disabled={ disabled } - id={ id } />
diff --git a/client/components/payment-methods-list/style.scss b/client/components/payment-methods-list/style.scss index 8c4e140dee5..7cf4f570e85 100644 --- a/client/components/payment-methods-list/style.scss +++ b/client/components/payment-methods-list/style.scss @@ -5,3 +5,10 @@ .woopayments-request-jcb { margin: $grid-unit-30 $grid-unit-30 0 $grid-unit-30 !important; } + +.wcpay-tooltip__tooltip { + &.wcpay-tooltip__tooltip--dark a { + color: $white; + text-decoration: underline; + } +} From c605942fdeab773009eea32a4fbc6396e6762e1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C4=81rlis=20Janisels?= Date: Fri, 6 Oct 2023 20:08:48 +0300 Subject: [PATCH 91/98] Point Klarna documentation to correct url from 'Contact WooCommerce Support' badge (#7410) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Kārlis Janisels --- changelog/fix-correct-documentation-url-for-klarna | 5 +++++ client/components/payment-method-disabled-tooltip/index.tsx | 1 + 2 files changed, 6 insertions(+) create mode 100644 changelog/fix-correct-documentation-url-for-klarna diff --git a/changelog/fix-correct-documentation-url-for-klarna b/changelog/fix-correct-documentation-url-for-klarna new file mode 100644 index 00000000000..3092cfe2b34 --- /dev/null +++ b/changelog/fix-correct-documentation-url-for-klarna @@ -0,0 +1,5 @@ +Significance: patch +Type: fix +Comment: Adding missed functionality from another PR + + diff --git a/client/components/payment-method-disabled-tooltip/index.tsx b/client/components/payment-method-disabled-tooltip/index.tsx index 8df2e14f594..a2b169bf98c 100644 --- a/client/components/payment-method-disabled-tooltip/index.tsx +++ b/client/components/payment-method-disabled-tooltip/index.tsx @@ -26,6 +26,7 @@ export const getDocumentationUrlForDisabledPaymentMethod = ( switch ( paymentMethodId ) { case PAYMENT_METHOD_IDS.AFTERPAY_CLEARPAY: case PAYMENT_METHOD_IDS.AFFIRM: + case PAYMENT_METHOD_IDS.KLARNA: url = DocumentationUrlForDisabledPaymentMethod.BNPLS; break; default: From 74d9de8c385b8e24189efbdbfb04aba134d1a099 Mon Sep 17 00:00:00 2001 From: Ricardo Metring Date: Fri, 6 Oct 2023 14:33:55 -0300 Subject: [PATCH 92/98] Implement loading state to WooPay express checkout button (#7366) --- .../add-7295-loading-state-to-woopay-button | 4 ++ .../woopay-express-checkout-button.js | 38 +++++++++++++++++-- client/checkout/woopay/style.scss | 17 +++++++-- 3 files changed, 53 insertions(+), 6 deletions(-) create mode 100644 changelog/add-7295-loading-state-to-woopay-button diff --git a/changelog/add-7295-loading-state-to-woopay-button b/changelog/add-7295-loading-state-to-woopay-button new file mode 100644 index 00000000000..7295b647d79 --- /dev/null +++ b/changelog/add-7295-loading-state-to-woopay-button @@ -0,0 +1,4 @@ +Significance: minor +Type: add + +Add loading state to WooPay button diff --git a/client/checkout/woopay/express-button/woopay-express-checkout-button.js b/client/checkout/woopay/express-button/woopay-express-checkout-button.js index 291dba45df8..ea53795faf4 100644 --- a/client/checkout/woopay/express-button/woopay-express-checkout-button.js +++ b/client/checkout/woopay/express-button/woopay-express-checkout-button.js @@ -3,6 +3,7 @@ */ import { sprintf, __ } from '@wordpress/i18n'; import React, { useCallback, useEffect, useState, useRef } from 'react'; +import classNames from 'classnames'; /** * Internal dependencies @@ -36,6 +37,7 @@ export const WoopayExpressCheckoutButton = ( { const buttonRef = useRef( null ); const isLoadingRef = useRef( false ); const { type: buttonType, height, size, theme, context } = buttonSettings; + const [ isLoading, setIsLoading ] = useState( false ); const [ buttonWidthType, setButtonWidthType ] = useState( buttonWidthTypes.wide ); @@ -183,6 +185,7 @@ export const WoopayExpressCheckoutButton = ( { // Set isLoadingRef to true to prevent multiple clicks. isLoadingRef.current = true; + setIsLoading( true ); wcpayTracks.recordUserEvent( wcpayTracks.events.WOOPAY_BUTTON_CLICK, @@ -234,6 +237,7 @@ export const WoopayExpressCheckoutButton = ( { ); showErrorMessage( context, errorMessage ); isLoadingRef.current = false; + setIsLoading( false ); } ); } ); } else { @@ -255,6 +259,7 @@ export const WoopayExpressCheckoutButton = ( { ); showErrorMessage( context, errorMessage ); isLoadingRef.current = false; + setIsLoading( false ); } ); } }; @@ -307,6 +312,7 @@ export const WoopayExpressCheckoutButton = ( { // Set button's default onClick handle to use modal checkout flow. initWoopayRef.current = defaultOnClick; isLoadingRef.current = false; + setIsLoading( false ); } }; @@ -315,6 +321,7 @@ export const WoopayExpressCheckoutButton = ( { return () => { window.removeEventListener( 'message', onMessage ); }; + // Note: Any changes to this dependency array may cause a duplicate iframe to be appended. }, [ context, defaultOnClick, isPreview, isProductPage, newIframe ] ); useEffect( () => { @@ -322,21 +329,46 @@ export const WoopayExpressCheckoutButton = ( { initWoopayRef.current = defaultOnClick; }, [ defaultOnClick ] ); + useEffect( () => { + const handlePageShow = ( event ) => { + // Re-enable the button after navigating back/forward to the page if bfcache is used. + if ( event?.persisted ) { + isLoadingRef.current = false; + setIsLoading( false ); + } + }; + + window.addEventListener( 'pageshow', handlePageShow ); + + return () => { + window.removeEventListener( 'pageshow', handlePageShow ); + }; + }, [] ); + return ( ); }; diff --git a/client/checkout/woopay/style.scss b/client/checkout/woopay/style.scss index 79cff325e79..97f6a4ff3c2 100644 --- a/client/checkout/woopay/style.scss +++ b/client/checkout/woopay/style.scss @@ -142,11 +142,22 @@ white-space: nowrap; text-transform: none; - &:hover { + &:not( :disabled ):hover { background: #d9baff !important; cursor: pointer; } + &:disabled { + opacity: 0.5; + cursor: not-allowed; + } + + &.is-loading, + &.is-loading:hover, + &.is-loading:disabled { + opacity: 1 !important; + } + svg { fill: $studio-woocommerce-purple-60; position: relative; @@ -179,14 +190,14 @@ svg { fill: $white; } - &:hover { + &:not( :disabled ):hover { background: #533582 !important; } } &[data-theme='light-outline'] { border-color: #674399 !important; - &:hover { + &:not( :disabled ):hover { background: #d9baff !important; } } From 193d40998e298e22127c5d7958763ba62c613091 Mon Sep 17 00:00:00 2001 From: Ricardo Metring Date: Fri, 6 Oct 2023 19:04:36 -0300 Subject: [PATCH 93/98] Add backup loading spinner style from WC blocks to WooPay button (#7432) --- .../fix-add-wc-blocks-loading-spinner-css | 4 ++ client/checkout/woopay/style.scss | 47 +++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 changelog/fix-add-wc-blocks-loading-spinner-css diff --git a/changelog/fix-add-wc-blocks-loading-spinner-css b/changelog/fix-add-wc-blocks-loading-spinner-css new file mode 100644 index 00000000000..d3fbea23ade --- /dev/null +++ b/changelog/fix-add-wc-blocks-loading-spinner-css @@ -0,0 +1,4 @@ +Significance: minor +Type: add + +Add WC blocks spinner to the WooPay checkout styles. diff --git a/client/checkout/woopay/style.scss b/client/checkout/woopay/style.scss index 97f6a4ff3c2..67b212331e3 100644 --- a/client/checkout/woopay/style.scss +++ b/client/checkout/woopay/style.scss @@ -270,3 +270,50 @@ } } } + +@keyframes spinner__animation { + 0% { + animation-timing-function: cubic-bezier( + 0.5856, + 0.0703, + 0.4143, + 0.9297 + ); + transform: rotate( 0deg ); + } + 100% { + transform: rotate( 360deg ); + } +} + +/** + * Sourced from https://github.com/woocommerce/woocommerce-blocks/blob/4dfe904f761423c1ac494f0d6319c602965b5efe/assets/js/base/components/spinner/style.scss. + * Depending on the wc-blocks version, these styles are not loaded, so they need to be included here. + */ +.wc-block-components-spinner { + position: absolute; + width: 100%; + height: 100%; + color: inherit; + box-sizing: content-box; + text-align: center; + font-size: 1.25em; + + &::after { + content: ' '; + position: absolute; + top: 50%; + left: 50%; + margin: -0.5em 0 0 -0.5em; + width: 1em; + height: 1em; + box-sizing: border-box; + transform-origin: 50% 50%; + transform: translateZ( 0 ) scale( 0.5 ); + backface-visibility: hidden; + border-radius: 50%; + border: 0.2em solid currentColor; + border-left-color: transparent; + animation: spinner__animation 1s infinite linear; + } +} From c1f7b63d4102703841099f5e2234b720e431a483 Mon Sep 17 00:00:00 2001 From: Alefe Souza Date: Sat, 7 Oct 2023 00:43:54 -0300 Subject: [PATCH 94/98] Show survey for merchants that disable WooPay (#7401) Co-authored-by: Malith Senaweera <6216000+malithsen@users.noreply.github.com> --- .../add-show-survey-users-disable-woopay | 4 ++ .../settings/save-settings-section/index.js | 61 ++++++++++++++++++- .../settings/woopay-disable-feedback/index.js | 50 +++++++++++++++ .../woopay-disable-feedback/style.scss | 23 +++++++ includes/admin/class-wc-payments-admin.php | 1 + includes/class-wc-payment-gateway-wcpay.php | 4 ++ 6 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 changelog/add-show-survey-users-disable-woopay create mode 100644 client/settings/woopay-disable-feedback/index.js create mode 100644 client/settings/woopay-disable-feedback/style.scss diff --git a/changelog/add-show-survey-users-disable-woopay b/changelog/add-show-survey-users-disable-woopay new file mode 100644 index 00000000000..edfd7514b8b --- /dev/null +++ b/changelog/add-show-survey-users-disable-woopay @@ -0,0 +1,4 @@ +Significance: minor +Type: add + +Show survey for merchants that disable WooPay. diff --git a/client/settings/save-settings-section/index.js b/client/settings/save-settings-section/index.js index 09f4aecf24b..63673f873ea 100644 --- a/client/settings/save-settings-section/index.js +++ b/client/settings/save-settings-section/index.js @@ -13,6 +13,7 @@ import { useSettings } from '../../data'; import wcpayTracks from '../../tracks'; import SettingsSection from '../settings-section'; import './style.scss'; +import WooPayDisableFeedback from '../woopay-disable-feedback'; const SaveSettingsSection = ( { disabled = false } ) => { const { saveSettings, isSaving, isLoading, settings } = useSettings(); @@ -23,6 +24,15 @@ const SaveSettingsSection = ( { disabled = false } ) => { initialIsPaymentRequestEnabled, setInitialIsPaymentRequestEnabled, ] = useState( null ); + // Keep the inital value of is_woopay_enabled + // in state for showing the feedback modal on change. + const [ initialIsWooPayEnabled, setInitialIsWooPayEnabled ] = useState( + null + ); + const [ + isWooPayDisableFeedbackOpen, + setIsWooPayDisableFeedbackOpen, + ] = useState( false ); if ( initialIsPaymentRequestEnabled === null && @@ -34,15 +44,26 @@ const SaveSettingsSection = ( { disabled = false } ) => { ); } + if ( + initialIsWooPayEnabled === null && + settings && + typeof settings.is_woopay_enabled !== 'undefined' + ) { + setInitialIsWooPayEnabled( settings.is_woopay_enabled ); + } + const saveOnClick = async () => { const isSuccess = await saveSettings(); + if ( ! isSuccess ) { + return; + } + // Track the event when the value changed and the // settings were successfully saved. if ( - isSuccess && initialIsPaymentRequestEnabled !== - settings.is_payment_request_enabled + settings.is_payment_request_enabled ) { wcpayTracks.recordEvent( wcpayTracks.events.PAYMENT_REQUEST_SETTINGS_CHANGE, @@ -56,6 +77,35 @@ const SaveSettingsSection = ( { disabled = false } ) => { settings.is_payment_request_enabled ); } + + // Show the feedback modal when WooPay is disabled. + if ( initialIsWooPayEnabled && ! settings.is_woopay_enabled ) { + const { woopayLastDisableDate } = wcpaySettings; + + // Do not show feedback modal if WooPay + // was disabled in the last 7 days. + if ( woopayLastDisableDate ) { + const date1 = new Date( woopayLastDisableDate ); + const date2 = new Date(); + const diffTime = Math.abs( date2 - date1 ); + const diffDays = Math.ceil( + diffTime / ( 1000 * 60 * 60 * 24 ) + ); + + if ( diffDays < 7 ) { + return; + } + } + + setIsWooPayDisableFeedbackOpen( true ); + + // Prevent show modal again. + setInitialIsPaymentRequestEnabled( true ); + // Set last disable date to prevent feedback window opening up + // on successive "Save button" clicks. This value is overwritten + // on page refresh. + wcpaySettings.woopayLastDisableDate = new Date(); + } }; return ( @@ -68,6 +118,13 @@ const SaveSettingsSection = ( { disabled = false } ) => { > { __( 'Save changes', 'woocommerce-payments' ) } + { isWooPayDisableFeedbackOpen ? ( + + setIsWooPayDisableFeedbackOpen( false ) + } + /> + ) : null } ); }; diff --git a/client/settings/woopay-disable-feedback/index.js b/client/settings/woopay-disable-feedback/index.js new file mode 100644 index 00000000000..a46f093e888 --- /dev/null +++ b/client/settings/woopay-disable-feedback/index.js @@ -0,0 +1,50 @@ +/** + * External dependencies + */ +import React, { useState } from 'react'; +import { __ } from '@wordpress/i18n'; +import { Modal } from '@wordpress/components'; + +/** + * Internal dependencies + */ +import './style.scss'; +import Loadable from 'wcpay/components/loadable'; +import WooPayIcon from 'assets/images/woopay.svg?asset'; + +const WooPayDisableFeedback = ( { onRequestClose } ) => { + const [ isLoading, setIsLoading ] = useState( true ); + + return ( + + } + isDismissible={ true } + shouldCloseOnClickOutside={ false } // Should be false because of the iframe. + shouldCloseOnEsc={ true } + onRequestClose={ onRequestClose } + className="woopay-disable-feedback" + > + +