From f86b08e94ee0a4a186f2656dc3e4d48fe54d766d Mon Sep 17 00:00:00 2001 From: Daniel Mallory Date: Mon, 11 Sep 2023 12:11:48 +0100 Subject: [PATCH] Add New Task to Enable Payment Methods (#7129) --- changelog/dev-6779-po-new-task | 4 ++ .../add-payment-methods-task.js | 46 ++++++++++--------- client/globals.d.ts | 1 + client/index.js | 4 +- client/overview/index.js | 2 + client/overview/task-list/strings.tsx | 12 ++++- client/overview/task-list/tasks.tsx | 29 ++++++------ .../task-list/tasks/add-apms-task.tsx | 32 +++++++++++++ client/overview/task-list/tasks/po-task.tsx | 42 ++++++++--------- includes/admin/class-wc-payments-admin.php | 26 +++++++++++ 10 files changed, 139 insertions(+), 59 deletions(-) create mode 100644 changelog/dev-6779-po-new-task create mode 100644 client/overview/task-list/tasks/add-apms-task.tsx diff --git a/changelog/dev-6779-po-new-task b/changelog/dev-6779-po-new-task new file mode 100644 index 00000000000..c49c78654fa --- /dev/null +++ b/changelog/dev-6779-po-new-task @@ -0,0 +1,4 @@ +Significance: minor +Type: add + +Add a new task prompt to set up APMs after onboarding. Fixed an issue where a notice would show up in some unintended circumstances on the APM setup. diff --git a/client/additional-methods-setup/upe-preview-methods-selector/add-payment-methods-task.js b/client/additional-methods-setup/upe-preview-methods-selector/add-payment-methods-task.js index 7fd26fec10d..b619ae96044 100644 --- a/client/additional-methods-setup/upe-preview-methods-selector/add-payment-methods-task.js +++ b/client/additional-methods-setup/upe-preview-methods-selector/add-payment-methods-task.js @@ -264,29 +264,31 @@ const AddPaymentMethodsTask = () => { } ) }

- - - { __( - 'Some payment methods cannot be enabled because more information is needed about your account. ', - 'woocommerce-payments' - ) } - - - { __( - 'Learn more about enabling additional payment methods.', - 'woocommerce-payments' - ) } - - + + { __( + 'Some payment methods cannot be enabled because more information is needed about your account. ', + 'woocommerce-payments' + ) } + + + { __( + 'Learn more about enabling additional payment methods.', + 'woocommerce-payments' + ) } + + + ) } { overviewTasksVisibility, showUpdateDetailsTask, wpcomReconnectUrl, + enabledPaymentMethods, } = wcpaySettings; const { isLoading: settingsIsLoading, settings } = useSettings(); @@ -70,6 +71,7 @@ const OverviewPage = () => { showUpdateDetailsTask, wpcomReconnectUrl, activeDisputes, + enabledPaymentMethods, } ); const tasks = Array.isArray( tasksUnsorted ) && tasksUnsorted.sort( taskSort ); diff --git a/client/overview/task-list/strings.tsx b/client/overview/task-list/strings.tsx index a826f9ebed4..8ca397211ed 100644 --- a/client/overview/task-list/strings.tsx +++ b/client/overview/task-list/strings.tsx @@ -285,7 +285,7 @@ export default { ), }, // Strings needed for the progressive onboarding related tasks. - po_tasks: { + tasks: { no_payment_14_days: { title: __( 'Please add your bank details to keep selling', @@ -412,5 +412,15 @@ export default { }, action_label: __( 'Verify bank details', 'woocommerce-payments' ), }, + add_apms: { + title: __( + 'Add more ways for buyers to pay', + 'woocommerce-payments' + ), + description: __( + 'Enable payment methods that work seamlessly with WooPayments.', + 'woocommerce-payments' + ), + }, }, }; diff --git a/client/overview/task-list/tasks.tsx b/client/overview/task-list/tasks.tsx index a8435f75d72..eb1fbf3cfc6 100644 --- a/client/overview/task-list/tasks.tsx +++ b/client/overview/task-list/tasks.tsx @@ -17,6 +17,7 @@ import { getReconnectWpcomTask } from './tasks/reconnect-task'; import { getUpdateBusinessDetailsTask } from './tasks/update-business-details-task'; import { CachedDispute } from 'wcpay/types/disputes'; import { TaskItemProps } from './types'; +import { getAddApmsTask } from './tasks/add-apms-task'; // Requirements we don't want to show to the user because they are too generic/not useful. These refer to Stripe error codes. const requirementBlacklist = [ 'invalid_value_other' ]; @@ -25,12 +26,14 @@ interface TaskListProps { showUpdateDetailsTask: boolean; wpcomReconnectUrl: string; activeDisputes?: CachedDispute[]; + enabledPaymentMethods?: string[]; } export const getTasks = ( { showUpdateDetailsTask, wpcomReconnectUrl, activeDisputes = [], + enabledPaymentMethods = [], }: TaskListProps ): TaskItemProps[] => { const { status, @@ -63,27 +66,26 @@ export const getTasks = ( { }; const isPoEnabled = progressiveOnboarding?.isEnabled; + const isPoComplete = progressiveOnboarding?.isComplete; + const isPoInProgress = isPoEnabled && ! isPoComplete; const errorMessages = getErrorMessagesFromRequirements(); + const isUpdateDetailsTaskVisible = + showUpdateDetailsTask && + ( ! isPoEnabled || ( isPoEnabled && ! detailsSubmitted ) ); + const isDisputeTaskVisible = !! activeDisputes && // Only show the dispute task if there are disputes due within 7 days. 0 < getDisputesDueWithinDays( activeDisputes, 7 ).length; + const isAddApmsTaskVisible = + enabledPaymentMethods?.length === 1 && + detailsSubmitted && + ! isPoInProgress; + return [ - showUpdateDetailsTask && - ! isPoEnabled && - getUpdateBusinessDetailsTask( - errorMessages, - status ?? '', - accountLink, - Number( currentDeadline ) ?? null, - pastDue ?? false, - detailsSubmitted ?? true - ), - showUpdateDetailsTask && - isPoEnabled && - ! detailsSubmitted && + isUpdateDetailsTaskVisible && getUpdateBusinessDetailsTask( errorMessages, status ?? '', @@ -95,6 +97,7 @@ export const getTasks = ( { wpcomReconnectUrl && getReconnectWpcomTask( wpcomReconnectUrl ), isDisputeTaskVisible && getDisputeResolutionTask( activeDisputes ), isPoEnabled && detailsSubmitted && getVerifyBankAccountTask(), + isAddApmsTaskVisible && getAddApmsTask(), ].filter( Boolean ); }; diff --git a/client/overview/task-list/tasks/add-apms-task.tsx b/client/overview/task-list/tasks/add-apms-task.tsx new file mode 100644 index 00000000000..29eb599339b --- /dev/null +++ b/client/overview/task-list/tasks/add-apms-task.tsx @@ -0,0 +1,32 @@ +/** + * External dependencies + */ + +/** + * Internal dependencies + */ +import type { TaskItemProps } from '../types'; +import strings from '../strings'; +import { getAdminUrl } from 'wcpay/utils'; + +export const getAddApmsTask = (): TaskItemProps | null => { + const handleClick = () => { + window.location.href = getAdminUrl( { + page: 'wc-admin', + path: '/payments/additional-payment-methods', + } ); + }; + + return { + key: 'add-apms', + level: 3, + content: '', + title: strings.tasks.add_apms.title, + additionalInfo: strings.tasks.add_apms.description, + completed: false, + onClick: handleClick, + action: handleClick, + expandable: false, + showActionButton: false, + }; +}; diff --git a/client/overview/task-list/tasks/po-task.tsx b/client/overview/task-list/tasks/po-task.tsx index 973a6c0c31a..79aa738415e 100644 --- a/client/overview/task-list/tasks/po-task.tsx +++ b/client/overview/task-list/tasks/po-task.tsx @@ -58,27 +58,27 @@ export const getVerifyBankAccountTask = (): any => { // When account is created less than 14 days ago, we also show a notice but it's just info. if ( 14 > daysFromAccountCreation ) { - title = strings.po_tasks.after_payment.title; + title = strings.tasks.after_payment.title; level = 3; - description = strings.po_tasks.after_payment.description( + description = strings.tasks.after_payment.description( verifyDetailsDueDate ); - actionLabelText = strings.po_tasks.after_payment.action_label; + actionLabelText = strings.tasks.after_payment.action_label; } if ( 14 <= daysFromAccountCreation ) { - title = strings.po_tasks.no_payment_14_days.title; + title = strings.tasks.no_payment_14_days.title; level = 2; - description = strings.po_tasks.no_payment_14_days.description( + description = strings.tasks.no_payment_14_days.description( verifyDetailsDueDate ); - actionLabelText = strings.po_tasks.no_payment_14_days.action_label; + actionLabelText = strings.tasks.no_payment_14_days.action_label; } if ( 30 <= daysFromAccountCreation ) { - title = strings.po_tasks.no_payment_30_days.title; + title = strings.tasks.no_payment_30_days.title; level = 1; - description = strings.po_tasks.no_payment_30_days.description; - actionLabelText = strings.po_tasks.no_payment_30_days.action_label; + description = strings.tasks.no_payment_30_days.description; + actionLabelText = strings.tasks.no_payment_30_days.action_label; } } else { const tpvInUsd = tpv / 100; @@ -87,39 +87,39 @@ export const getVerifyBankAccountTask = (): any => { .format( 'MMMM D, YYYY' ); const daysFromFirstPayment = moment().diff( firstPaymentDate, 'days' ); - title = strings.po_tasks.after_payment.title; + title = strings.tasks.after_payment.title; level = 3; - description = strings.po_tasks.after_payment.description( + description = strings.tasks.after_payment.description( verifyDetailsDueDate ); - actionLabelText = strings.po_tasks.after_payment.action_label; + actionLabelText = strings.tasks.after_payment.action_label; // Balance is rising. if ( tpvLimit * 0.2 <= tpvInUsd || 7 <= daysFromFirstPayment ) { - title = strings.po_tasks.balance_rising.title; + title = strings.tasks.balance_rising.title; level = 2; - description = strings.po_tasks.balance_rising.description( + description = strings.tasks.balance_rising.description( verifyDetailsDueDate ); - actionLabelText = strings.po_tasks.balance_rising.action_label; + actionLabelText = strings.tasks.balance_rising.action_label; } // Near threshold. if ( tpvLimit * 0.6 <= tpvInUsd || 21 <= daysFromFirstPayment ) { - title = strings.po_tasks.near_threshold.title; + title = strings.tasks.near_threshold.title; level = 1; - description = strings.po_tasks.near_threshold.description( + description = strings.tasks.near_threshold.description( verifyDetailsDueDate ); - actionLabelText = strings.po_tasks.near_threshold.action_label; + actionLabelText = strings.tasks.near_threshold.action_label; } // Threshold reached. if ( tpvLimit <= tpvInUsd || 30 <= daysFromFirstPayment ) { - title = strings.po_tasks.threshold_reached.title; + title = strings.tasks.threshold_reached.title; level = 1; - description = strings.po_tasks.threshold_reached.description( + description = strings.tasks.threshold_reached.description( verifyDetailsDueDate ); - actionLabelText = strings.po_tasks.threshold_reached.action_label; + actionLabelText = strings.tasks.threshold_reached.action_label; } } diff --git a/includes/admin/class-wc-payments-admin.php b/includes/admin/class-wc-payments-admin.php index c8434190b7a..ad937541204 100644 --- a/includes/admin/class-wc-payments-admin.php +++ b/includes/admin/class-wc-payments-admin.php @@ -829,6 +829,7 @@ private function get_js_settings(): array { 'fraudProtection' => [ 'isWelcomeTourDismissed' => WC_Payments_Features::is_fraud_protection_welcome_tour_dismissed(), ], + 'enabledPaymentMethods' => $this->get_enabled_payment_method_ids(), 'progressiveOnboarding' => $this->account->get_progressive_onboarding_details(), 'accountDefaultCurrency' => $this->account->get_account_default_currency(), 'frtDiscoverBannerSettings' => get_option( 'wcpay_frt_discover_banner_settings', '' ), @@ -842,6 +843,31 @@ private function get_js_settings(): array { return apply_filters( 'wcpay_js_settings', $this->wcpay_js_settings ); } + /** + * Helper function to retrieve enabled UPE payment methods. + * + * TODO: This is duplicating code located in the settings container, we should refactor so that + * this is stored in a centralised place and can be retrieved from there. + * + * @return array + */ + private function get_enabled_payment_method_ids(): array { + $available_upe_payment_methods = $this->wcpay_gateway->get_upe_available_payment_methods(); + /** + * It might be possible that enabled payment methods settings have an invalid state. As an example, + * if an account is switched to a new country and earlier country had PM's that are no longer valid; or if the PM is not available anymore. + * To keep saving settings working, we are ensuring the enabled payment methods are yet available. + */ + $enabled_payment_methods = array_values( + array_intersect( + $this->wcpay_gateway->get_upe_enabled_payment_method_ids(), + $available_upe_payment_methods + ) + ); + + return $enabled_payment_methods; + } + /** * Creates an array of features enabled only when external dependencies are of certain versions. *