diff --git a/plugins/woocommerce-admin/TESTING-INSTRUCTIONS.md b/plugins/woocommerce-admin/TESTING-INSTRUCTIONS.md
index 99ff463b48d..4fdf20dee42 100644
--- a/plugins/woocommerce-admin/TESTING-INSTRUCTIONS.md
+++ b/plugins/woocommerce-admin/TESTING-INSTRUCTIONS.md
@@ -11,6 +11,15 @@
5. Navigate to Homescreen.
6. Navigate back to previous Analytics Report.
7. Ensure that the time period is _still_ what you set on step 2.
+### Refactor payments to allow management of methods #6786
+
+1. Do not select "CBD industry" as a store industry during onboarding.
+2. Make various payment methods visible by switching to different countries.
+3. Attempt to set up various payment methods.
+4. Make sure that after setup, a `Manage` link is shown that links to the payment method settings page.
+5. Check that simple methods like, cash delivery or bank transfer initially have an `Enable` option.
+
+### Fix varation bug with Products reports #6647
### Fix varation bug with Products reports #6647
diff --git a/plugins/woocommerce-admin/client/layout/index.js b/plugins/woocommerce-admin/client/layout/index.js
index 3a5a4cec2f5..22efe9d487f 100644
--- a/plugins/woocommerce-admin/client/layout/index.js
+++ b/plugins/woocommerce-admin/client/layout/index.js
@@ -36,7 +36,7 @@ const StoreAlerts = lazy( () =>
const WCPayUsageModal = lazy( () =>
import(
- /* webpackChunkName: "wcpay-usage-modal" */ '../task-list/tasks/payments/wcpay/wcpay-usage-modal'
+ /* webpackChunkName: "wcpay-usage-modal" */ '../task-list/tasks/payments/methods/wcpay/wcpay-usage-modal'
)
);
diff --git a/plugins/woocommerce-admin/client/profile-wizard/steps/business-details/flows/selective-bundle/selective-extensions-bundle/index.js b/plugins/woocommerce-admin/client/profile-wizard/steps/business-details/flows/selective-bundle/selective-extensions-bundle/index.js
index 11f29961b72..88ee7ef5472 100644
--- a/plugins/woocommerce-admin/client/profile-wizard/steps/business-details/flows/selective-bundle/selective-extensions-bundle/index.js
+++ b/plugins/woocommerce-admin/client/profile-wizard/steps/business-details/flows/selective-bundle/selective-extensions-bundle/index.js
@@ -22,7 +22,7 @@ import { AppIllustration } from '../app-illustration';
import './style.scss';
import { setAllPropsToValue } from '~/lib/collections';
import { getCountryCode } from '~/dashboard/utils';
-import { isWCPaySupported } from '~/task-list/tasks/payments/wcpay';
+import { isWCPaySupported } from '~/task-list/tasks/payments/methods/wcpay';
const generatePluginDescriptionWithLink = (
description,
diff --git a/plugins/woocommerce-admin/client/task-list/tasks.js b/plugins/woocommerce-admin/client/task-list/tasks.js
index b8ae7a91874..6c0b69f0b9d 100644
--- a/plugins/woocommerce-admin/client/task-list/tasks.js
+++ b/plugins/woocommerce-admin/client/task-list/tasks.js
@@ -24,7 +24,7 @@ import Payments from './tasks/payments';
import {
installActivateAndConnectWcpay,
isWCPaySupported,
-} from './tasks/payments/wcpay';
+} from './tasks/payments/methods/wcpay';
import { groupListOfObjectsBy } from '../lib/collections';
import { getLinkTypeAndHref } from '~/store-management-links';
diff --git a/plugins/woocommerce-admin/client/task-list/tasks/payments/action.js b/plugins/woocommerce-admin/client/task-list/tasks/payments/action.js
new file mode 100644
index 00000000000..5302b74c507
--- /dev/null
+++ b/plugins/woocommerce-admin/client/task-list/tasks/payments/action.js
@@ -0,0 +1,98 @@
+/**
+ * External dependencies
+ */
+import { __ } from '@wordpress/i18n';
+import { Button, Spinner } from '@wordpress/components';
+import { getAdminLink } from '@woocommerce/wc-admin-settings';
+import { updateQueryString } from '@woocommerce/navigation';
+import { useState } from '@wordpress/element';
+
+export const Action = ( {
+ hasSetup = false,
+ isConfigured = false,
+ isEnabled = false,
+ isLoading = false,
+ isRecommended = false,
+ manageUrl = null,
+ markConfigured,
+ methodKey,
+ onSetUp = () => {},
+ onSetupCallback,
+} ) => {
+ const [ isBusy, setIsBusy ] = useState( false );
+
+ const classes = 'woocommerce-task-payment__action';
+
+ if ( isLoading ) {
+ return ;
+ }
+
+ const handleClick = async () => {
+ onSetUp( methodKey );
+
+ if ( onSetupCallback ) {
+ setIsBusy( true );
+ await new Promise( onSetupCallback )
+ .then( () => {
+ setIsBusy( false );
+ } )
+ .catch( () => {
+ setIsBusy( false );
+ } );
+
+ return;
+ }
+
+ updateQueryString( {
+ method: methodKey,
+ } );
+ };
+
+ if ( hasSetup && ! isConfigured ) {
+ return (
+
+
+
+ );
+ }
+
+ if ( ( hasSetup && isConfigured ) || ( ! hasSetup && isEnabled ) ) {
+ if ( ! manageUrl ) {
+ return null;
+ }
+
+ return (
+
+
+
+ );
+ }
+
+ return (
+
+ );
+};
diff --git a/plugins/woocommerce-admin/client/task-list/tasks/payments/index.js b/plugins/woocommerce-admin/client/task-list/tasks/payments/index.js
index 42d3a66e828..65121b56f50 100644
--- a/plugins/woocommerce-admin/client/task-list/tasks/payments/index.js
+++ b/plugins/woocommerce-admin/client/task-list/tasks/payments/index.js
@@ -1,41 +1,28 @@
/**
* External dependencies
*/
-import { __, sprintf } from '@wordpress/i18n';
import classnames from 'classnames';
-import { cloneElement, Component } from '@wordpress/element';
-import { compose } from '@wordpress/compose';
-import {
- Button,
- Card,
- CardBody,
- CardMedia,
- CardFooter,
- FormToggle,
- Spinner,
-} from '@wordpress/components';
-import { withDispatch, withSelect } from '@wordpress/data';
-import { H, Plugins } from '@woocommerce/components';
-import {
- getHistory,
- getNewPath,
- updateQueryString,
-} from '@woocommerce/navigation';
+import { Card, CardBody, CardMedia, CardFooter } from '@wordpress/components';
+import { useDispatch, useSelect } from '@wordpress/data';
+import { H } from '@woocommerce/components';
+import { getHistory, getNewPath } from '@woocommerce/navigation';
import {
ONBOARDING_STORE_NAME,
OPTIONS_STORE_NAME,
PLUGINS_STORE_NAME,
- pluginNames,
SETTINGS_STORE_NAME,
} from '@woocommerce/data';
import { recordEvent } from '@woocommerce/tracks';
+import { useMemo, useState } from '@wordpress/element';
/**
* Internal dependencies
*/
-import { createNoticesFromResponse } from '../../../lib/notices';
+import { Action } from './action';
import { getCountryCode } from '../../../dashboard/utils';
import { getPaymentMethods } from './methods';
+import { RecommendedRibbon } from './recommended-ribbon';
+import { Setup } from './setup';
export const setMethodEnabledOption = async (
optionName,
@@ -57,331 +44,19 @@ export const setMethodEnabledOption = async (
}
};
-class Payments extends Component {
- constructor( props ) {
- super( ...arguments );
- const { methods } = props;
+export const Payments = ( { query } ) => {
+ const { createNotice } = useDispatch( 'core/notices' );
+ const {
+ installAndActivatePlugins,
+ invalidateResolutionForStoreSelector: invalidatePluginStoreSelector,
+ } = useDispatch( PLUGINS_STORE_NAME );
+ const { updateOptions } = useDispatch( OPTIONS_STORE_NAME );
+ const {
+ invalidateResolution,
+ invalidateResolutionForStoreSelector,
+ } = useDispatch( ONBOARDING_STORE_NAME );
- const enabledMethods = {};
- methods.forEach(
- ( method ) => ( enabledMethods[ method.key ] = method.isEnabled )
- );
- this.state = {
- busyMethod: null,
- enabledMethods,
- recommendedMethod: this.getRecommendedMethod(),
- };
-
- this.markConfigured = this.markConfigured.bind( this );
- }
-
- componentDidUpdate() {
- const { recommendedMethod } = this.state;
-
- const method = this.getRecommendedMethod();
- if ( recommendedMethod !== method ) {
- this.setState( {
- recommendedMethod: method,
- } );
- }
- }
-
- getRecommendedMethod() {
- const { methods } = this.props;
- const recommendedMethod = methods.find(
- ( m ) =>
- ( m.key === 'wcpay' && m.visible ) ||
- ( m.key === 'mercadopago' && m.visible )
- );
- if ( ! recommendedMethod ) {
- return 'stripe';
- }
- return recommendedMethod.key;
- }
-
- async markConfigured( methodName, queryParams = {} ) {
- const { enabledMethods } = this.state;
- const { methods } = this.props;
-
- const method = methods.find( ( option ) => option.key === methodName );
-
- if ( ! method ) {
- throw `Method ${ methodName } not found in available methods list`;
- }
-
- this.setState( {
- enabledMethods: {
- ...enabledMethods,
- [ methodName ]: true,
- },
- } );
-
- await setMethodEnabledOption( method.optionName, 'yes', this.props );
-
- recordEvent( 'tasklist_payment_connect_method', {
- payment_method: methodName,
- } );
-
- getHistory().push(
- getNewPath( { ...queryParams, task: 'payments' }, '/', {} )
- );
- }
-
- getCurrentMethod() {
- const { methods, query } = this.props;
-
- if ( ! query.method ) {
- return;
- }
-
- const currentMethod = methods.find(
- ( method ) => method.key === query.method
- );
-
- if ( ! currentMethod ) {
- throw `Current method ${ query.method } not found in available methods list`;
- }
-
- return currentMethod;
- }
-
- getInstallStep() {
- const currentMethod = this.getCurrentMethod();
-
- if ( ! currentMethod.plugins || ! currentMethod.plugins.length ) {
- return;
- }
-
- const { activePlugins } = this.props;
- const pluginsToInstall = currentMethod.plugins.filter(
- ( method ) => ! activePlugins.includes( method )
- );
- const pluginNamesString = currentMethod.plugins
- .map( ( pluginSlug ) => pluginNames[ pluginSlug ] )
- .join( ' ' + __( 'and', 'woocommerce-admin' ) + ' ' );
-
- return {
- key: 'install',
- label: sprintf(
- __( 'Install %s', 'woocommerce-admin' ),
- pluginNamesString
- ),
- content: (
- {
- createNoticesFromResponse( response );
- recordEvent( 'tasklist_payment_install_method', {
- plugins: currentMethod.plugins,
- } );
- } }
- onError={ ( errors, response ) =>
- createNoticesFromResponse( response )
- }
- autoInstall
- pluginSlugs={ currentMethod.plugins }
- />
- ),
- isComplete: ! pluginsToInstall.length,
- };
- }
-
- async toggleMethod( key ) {
- const { methods } = this.props;
- const { enabledMethods } = this.state;
- const method = methods.find( ( option ) => option.key === key );
-
- if ( ! method ) {
- throw `Method ${ key } not found in available methods list`;
- }
-
- enabledMethods[ key ] = ! enabledMethods[ key ];
- this.setState( { enabledMethods } );
-
- recordEvent( 'tasklist_payment_toggle', {
- enabled: ! method.isEnabled,
- payment_method: key,
- } );
-
- await setMethodEnabledOption(
- method.optionName,
- method.isEnabled ? 'no' : 'yes',
- this.props
- );
- }
-
- async handleClick( method ) {
- const { methods } = this.props;
- const { key, onClick } = method;
-
- recordEvent( 'tasklist_payment_setup', {
- options: methods.map( ( option ) => option.key ),
- selected: key,
- } );
-
- if ( onClick ) {
- this.setState( { busyMethod: key } );
- await new Promise( onClick )
- .then( () => {
- this.setState( { busyMethod: null } );
- } )
- .catch( () => {
- this.setState( { busyMethod: null } );
- } );
-
- return;
- }
-
- updateQueryString( {
- method: key,
- } );
- }
-
- getSetupButtons( method ) {
- const { busyMethod, enabledMethods, recommendedMethod } = this.state;
- const { container, isConfigured, key } = method;
- if ( container && ! isConfigured ) {
- return (
-
-
-
- );
- }
- return (
- this.toggleMethod( key ) }
- onClick={ ( e ) => e.stopPropagation() }
- />
- );
- }
-
- render() {
- const currentMethod = this.getCurrentMethod();
- const { recommendedMethod } = this.state;
- const { methods, query } = this.props;
-
- if ( currentMethod ) {
- return (
-
-
- { cloneElement( currentMethod.container, {
- methodConfig: currentMethod,
- query,
- installStep: this.getInstallStep(),
- markConfigured: this.markConfigured,
- hasCbdIndustry: currentMethod.hasCbdIndustry,
- } ) }
-
-
- );
- }
-
- return (
-
- { methods.map( ( method ) => {
- const {
- before,
- content,
- isConfigured,
- key,
- title,
- visible,
- loading,
- } = method;
-
- if ( ! visible ) {
- return null;
- }
-
- const classes = classnames(
- 'woocommerce-task-payment',
- 'woocommerce-task-card',
- ! isConfigured &&
- 'woocommerce-task-payment-not-configured',
- 'woocommerce-task-payment-' + key
- );
-
- const isRecommended =
- key === recommendedMethod && ! isConfigured;
- const showRecommendedRibbon =
- isRecommended && key !== 'wcpay';
- const showRecommendedPill =
- isRecommended && key === 'wcpay';
- const recommendedText =
- key === 'mercadopago'
- ? __( 'Local Partner', 'woocommerce-admin' )
- : __( 'Recommended', 'woocommerce-admin' );
-
- return (
-
- { showRecommendedRibbon && (
-
- { recommendedText }
-
- ) }
- { before }
-
-
- { title }
- { showRecommendedPill && (
-
- { recommendedText }
-
- ) }
-
-
- { content }
-
-
-
- { loading ? (
-
- ) : (
- this.getSetupButtons( method )
- ) }
-
-
- );
- } ) }
-
- );
- }
-}
-
-export default compose(
- withDispatch( ( dispatch ) => {
- const { createNotice } = dispatch( 'core/notices' );
- const {
- installAndActivatePlugins,
- invalidateResolutionForStoreSelector: invalidatePluginStoreSelector,
- } = dispatch( PLUGINS_STORE_NAME );
- const { updateOptions } = dispatch( OPTIONS_STORE_NAME );
- const {
- invalidateResolution,
- invalidateResolutionForStoreSelector,
- } = dispatch( ONBOARDING_STORE_NAME );
- invalidateResolution( 'getProfileItems', [] );
- invalidateResolution( 'getTasksStatus', [] );
- return {
- clearTaskStatusCache: () => {
- invalidateResolutionForStoreSelector( 'getTasksStatus' );
- invalidatePluginStoreSelector( 'getPaypalOnboardingStatus' );
- },
- createNotice,
- installAndActivatePlugins,
- updateOptions,
- };
- } ),
- withSelect( ( select, props ) => {
- const { createNotice, installAndActivatePlugins } = props;
+ const { methods, options } = useSelect( ( select ) => {
const { getProfileItems } = select( ONBOARDING_STORE_NAME );
const { getOption } = select( OPTIONS_STORE_NAME );
const {
@@ -419,7 +94,7 @@ export default compose(
'woocommerce_woo-mercado-pago-basic_settings',
];
- const options = optionNames.reduce( ( result, name ) => {
+ const retrievedOptions = optionNames.reduce( ( result, name ) => {
result[ name ] = getOption( name );
return result;
}, {} );
@@ -433,27 +108,174 @@ export default compose(
? getPaypalOnboardingStatus()
: null;
- const methods = getPaymentMethods( {
- activePlugins,
- countryCode,
- createNotice,
- installAndActivatePlugins,
- isJetpackConnected: isJetpackConnected(),
- onboardingStatus,
- options,
- profileItems,
- paypalOnboardingStatus,
- loadingPaypalStatus:
- ! hasFinishedResolution( 'getPaypalOnboardingStatus' ) &&
- ! paypalOnboardingStatus,
+ return {
+ methods: getPaymentMethods( {
+ activePlugins,
+ countryCode,
+ createNotice,
+ installAndActivatePlugins,
+ isJetpackConnected: isJetpackConnected(),
+ onboardingStatus,
+ options: retrievedOptions,
+ profileItems,
+ paypalOnboardingStatus,
+ loadingPaypalStatus:
+ ! hasFinishedResolution( 'getPaypalOnboardingStatus' ) &&
+ ! paypalOnboardingStatus,
+ } ),
+ options: retrievedOptions,
+ };
+ } );
+
+ const [ enabledMethods, setEnabledMethods ] = useState(
+ methods.reduce( ( acc, method ) => {
+ acc[ method.key ] = method.isEnabled;
+ return acc;
+ }, {} )
+ );
+
+ const recommendedMethod = useMemo( () => {
+ const method = methods.find(
+ ( m ) =>
+ ( m.key === 'wcpay' && m.visible ) ||
+ ( m.key === 'mercadopago' && m.visible )
+ );
+ if ( ! method ) {
+ return 'stripe';
+ }
+ return method.key;
+ }, [ methods ] );
+
+ const markConfigured = async ( methodKey, queryParams = {} ) => {
+ const method = methods.find( ( option ) => option.key === methodKey );
+
+ if ( ! method ) {
+ throw `Method ${ methodKey } not found in available methods list`;
+ }
+
+ setEnabledMethods( {
+ ...enabledMethods,
+ [ methodKey ]: true,
} );
- return {
- countryCode,
- profileItems,
- activePlugins,
- options,
- methods,
+ const clearTaskStatusCache = () => {
+ invalidateResolution( 'getProfileItems', [] );
+ invalidateResolution( 'getTasksStatus', [] );
+ invalidateResolutionForStoreSelector( 'getTasksStatus' );
+ invalidatePluginStoreSelector( 'getPaypalOnboardingStatus' );
};
- } )
-)( Payments );
+
+ await setMethodEnabledOption( method.optionName, 'yes', {
+ clearTaskStatusCache,
+ updateOptions,
+ options,
+ } );
+
+ recordEvent( 'tasklist_payment_connect_method', {
+ payment_method: methodKey,
+ } );
+
+ getHistory().push(
+ getNewPath( { ...queryParams, task: 'payments' }, '/', {} )
+ );
+ };
+
+ const currentMethod = useMemo( () => {
+ if ( ! query.method ) {
+ return null;
+ }
+
+ const method = methods.find( ( m ) => m.key === query.method );
+
+ if ( ! method ) {
+ throw `Current method ${ query.method } not found in available methods list`;
+ }
+
+ return method;
+ }, [ query ] );
+
+ if ( currentMethod ) {
+ return (
+
+ );
+ }
+
+ return (
+
+ { methods.map( ( method ) => {
+ const {
+ before,
+ container,
+ content,
+ isConfigured,
+ key,
+ manageUrl,
+ title,
+ visible,
+ loading,
+ onClick,
+ } = method;
+
+ if ( ! visible ) {
+ return null;
+ }
+
+ const classes = classnames(
+ 'woocommerce-task-payment',
+ 'woocommerce-task-card',
+ ! isConfigured && 'woocommerce-task-payment-not-configured',
+ 'woocommerce-task-payment-' + key
+ );
+
+ const isRecommended =
+ key === recommendedMethod && ! isConfigured;
+
+ return (
+
+ { isRecommended && key !== 'wcpay' && (
+
+ ) }
+ { before }
+
+
+ { title }
+ { isRecommended && key === 'wcpay' && (
+
+ ) }
+
+
+ { content }
+
+
+
+
+ recordEvent( 'tasklist_payment_setup', {
+ options: methods.map(
+ ( option ) => option.key
+ ),
+ selected: key,
+ } )
+ }
+ onSetupCallback={ onClick }
+ />
+
+
+ );
+ } ) }
+
+ );
+};
+
+export default Payments;
diff --git a/plugins/woocommerce-admin/client/task-list/tasks/payments/bacs.js b/plugins/woocommerce-admin/client/task-list/tasks/payments/methods/bacs.js
similarity index 100%
rename from plugins/woocommerce-admin/client/task-list/tasks/payments/bacs.js
rename to plugins/woocommerce-admin/client/task-list/tasks/payments/methods/bacs.js
diff --git a/plugins/woocommerce-admin/client/task-list/tasks/payments/eway.js b/plugins/woocommerce-admin/client/task-list/tasks/payments/methods/eway.js
similarity index 100%
rename from plugins/woocommerce-admin/client/task-list/tasks/payments/eway.js
rename to plugins/woocommerce-admin/client/task-list/tasks/payments/methods/eway.js
diff --git a/plugins/woocommerce-admin/client/task-list/tasks/payments/methods.js b/plugins/woocommerce-admin/client/task-list/tasks/payments/methods/index.js
similarity index 92%
rename from plugins/woocommerce-admin/client/task-list/tasks/payments/methods.js
rename to plugins/woocommerce-admin/client/task-list/tasks/payments/methods/index.js
index 20c6a6a77bb..2c9389c7dd9 100644
--- a/plugins/woocommerce-admin/client/task-list/tasks/payments/methods.js
+++ b/plugins/woocommerce-admin/client/task-list/tasks/payments/methods/index.js
@@ -14,12 +14,12 @@ import { Link } from '@woocommerce/components';
* Internal dependencies
*/
import Bacs from './bacs';
-import BacsLogo from './images/bacs';
-import CodLogo from './images/cod';
-import WCPayLogo from './images/wcpay';
-import RazorpayLogo from './images/razorpay';
-import { MollieLogo } from './images/mollie';
-import { PayUIndiaLogo } from './images/payu-india';
+import BacsLogo from '../images/bacs';
+import CodLogo from '../images/cod';
+import WCPayLogo from '../images/wcpay';
+import RazorpayLogo from '../images/razorpay';
+import { MollieLogo } from '../images/mollie';
+import { PayUIndiaLogo } from '../images/payu-india';
import Stripe from './stripe';
import Square from './square';
import {
@@ -35,10 +35,16 @@ import EWay from './eway';
import Razorpay from './razorpay';
import { Mollie } from './mollie';
import { PayUIndia } from './payu-india';
-import { GenericPaymentStep } from './generic-payment-step';
+import { GenericPaymentStep } from '../generic-payment-step';
const wcAdminAssetUrl = getSetting( 'wcAdminAssetUrl', '' );
+const getPaymentsSettingsUrl = ( methodKey ) => {
+ return getAdminLink(
+ 'admin.php?page=wc-settings&tab=checkout§ion=' + methodKey
+ );
+};
+
export function getPaymentMethods( {
activePlugins,
countryCode,
@@ -98,6 +104,7 @@ export function getPaymentMethods( {
options.woocommerce_stripe_settings &&
options.woocommerce_stripe_settings.enabled === 'yes',
optionName: 'woocommerce_stripe_settings',
+ manageUrl: getPaymentsSettingsUrl( 'stripe' ),
},
{
key: 'paystack',
@@ -149,6 +156,7 @@ export function getPaymentMethods( {
},
};
},
+ manageUrl: getPaymentsSettingsUrl( 'paystack' ),
},
{
key: 'payfast',
@@ -209,6 +217,7 @@ export function getPaymentMethods( {
},
};
},
+ manageUrl: getPaymentsSettingsUrl( 'stripe' ),
},
{
key: 'mercadopago',
@@ -241,6 +250,7 @@ export function getPaymentMethods( {
options[ 'woocommerce_woo-mercado-pago-basic_settings' ]
.enabled === 'yes',
optionName: 'woocommerce_woo-mercado-pago-basic_settings',
+ manageUrl: getPaymentsSettingsUrl( 'woo-mercado-pago-basic' ),
},
{
key: 'paypal',
@@ -266,6 +276,7 @@ export function getPaymentMethods( {
loading: activePlugins.includes( PAYPAL_PLUGIN )
? loadingPaypalStatus
: false,
+ manageUrl: getPaymentsSettingsUrl( 'ppcp-gateway' ),
},
{
key: 'klarna_checkout',
@@ -290,6 +301,7 @@ export function getPaymentMethods( {
options.woocommerce_kco_settings &&
options.woocommerce_kco_settings.enabled === 'yes',
optionName: 'woocommerce_kco_settings',
+ manageUrl: getPaymentsSettingsUrl( 'kco' ),
},
{
key: 'klarna_payments',
@@ -325,6 +337,7 @@ export function getPaymentMethods( {
options.woocommerce_klarna_payments_settings &&
options.woocommerce_klarna_payments_settings.enabled === 'yes',
optionName: 'woocommerce_klarna_payments_settings',
+ manageUrl: getPaymentsSettingsUrl( 'klarna_payments' ),
},
{
key: 'mollie',
@@ -360,6 +373,7 @@ export function getPaymentMethods( {
options.woocommerce_mollie_payments_settings &&
options.woocommerce_mollie_payments_settings.enabled === 'yes',
optionName: 'woocommerce_mollie_payments_settings',
+ manageUrl: getPaymentsSettingsUrl( 'mollie_wc_gateway_creditcard' ),
},
{
key: 'square',
@@ -403,6 +417,7 @@ export function getPaymentMethods( {
'yes',
optionName: 'woocommerce_square_credit_card_settings',
hasCbdIndustry,
+ manageUrl: getPaymentsSettingsUrl( 'square_credit_card' ),
},
{
key: 'eway',
@@ -432,6 +447,7 @@ export function getPaymentMethods( {
options.woocommerce_eway_settings &&
options.woocommerce_eway_settings.enabled === 'yes',
optionName: 'woocommerce_eway_settings',
+ manageUrl: getPaymentsSettingsUrl( 'eway' ),
},
{
key: 'razorpay',
@@ -456,6 +472,7 @@ export function getPaymentMethods( {
options.woocommerce_razorpay_settings &&
options.woocommerce_razorpay_settings.enabled === 'yes',
optionName: 'woocommerce_razorpay_settings',
+ manageUrl: getPaymentsSettingsUrl( 'razorpay' ),
},
{
key: 'payubiz',
@@ -475,6 +492,7 @@ export function getPaymentMethods( {
isConfigured: activePlugins.includes( 'payu-india' ),
isEnabled: enabledPaymentGateways.includes( 'payubiz' ),
optionName: 'woocommerce_payubiz_settings',
+ manageUrl: getPaymentsSettingsUrl( 'payubiz' ),
},
{
key: 'cod',
@@ -489,6 +507,7 @@ export function getPaymentMethods( {
options.woocommerce_cod_settings &&
options.woocommerce_cod_settings.enabled === 'yes',
optionName: 'woocommerce_cod_settings',
+ manageUrl: getPaymentsSettingsUrl( 'cod' ),
},
{
key: 'bacs',
@@ -507,6 +526,7 @@ export function getPaymentMethods( {
options.woocommerce_bacs_settings &&
options.woocommerce_bacs_settings.enabled === 'yes',
optionName: 'woocommerce_bacs_settings',
+ manageUrl: getPaymentsSettingsUrl( 'bacs' ),
},
];
@@ -608,6 +628,7 @@ export function getPaymentMethods( {
options.woocommerce_woocommerce_payments_settings.enabled ===
'yes',
optionName: 'woocommerce_woocommerce_payments_settings',
+ manageUrl: getPaymentsSettingsUrl( 'woocommerce_payments' ),
} );
}
diff --git a/plugins/woocommerce-admin/client/task-list/tasks/payments/klarna.js b/plugins/woocommerce-admin/client/task-list/tasks/payments/methods/klarna.js
similarity index 100%
rename from plugins/woocommerce-admin/client/task-list/tasks/payments/klarna.js
rename to plugins/woocommerce-admin/client/task-list/tasks/payments/methods/klarna.js
diff --git a/plugins/woocommerce-admin/client/task-list/tasks/payments/mercadopago.js b/plugins/woocommerce-admin/client/task-list/tasks/payments/methods/mercadopago.js
similarity index 97%
rename from plugins/woocommerce-admin/client/task-list/tasks/payments/mercadopago.js
rename to plugins/woocommerce-admin/client/task-list/tasks/payments/methods/mercadopago.js
index f190e16b96a..0771ba858f5 100644
--- a/plugins/woocommerce-admin/client/task-list/tasks/payments/mercadopago.js
+++ b/plugins/woocommerce-admin/client/task-list/tasks/payments/methods/mercadopago.js
@@ -12,7 +12,7 @@ import { SETTINGS_STORE_NAME } from '@woocommerce/data';
/**
* Internal dependencies
*/
-import { getCountryCode } from '../../../dashboard/utils';
+import { getCountryCode } from '~/dashboard/utils';
export const MERCADOPAGO_PLUGIN = 'woocommerce-mercadopago';
diff --git a/plugins/woocommerce-admin/client/task-list/tasks/payments/mollie.js b/plugins/woocommerce-admin/client/task-list/tasks/payments/methods/mollie.js
similarity index 100%
rename from plugins/woocommerce-admin/client/task-list/tasks/payments/mollie.js
rename to plugins/woocommerce-admin/client/task-list/tasks/payments/methods/mollie.js
diff --git a/plugins/woocommerce-admin/client/task-list/tasks/payments/paypal.js b/plugins/woocommerce-admin/client/task-list/tasks/payments/methods/paypal.js
similarity index 100%
rename from plugins/woocommerce-admin/client/task-list/tasks/payments/paypal.js
rename to plugins/woocommerce-admin/client/task-list/tasks/payments/methods/paypal.js
diff --git a/plugins/woocommerce-admin/client/task-list/tasks/payments/payu-india.js b/plugins/woocommerce-admin/client/task-list/tasks/payments/methods/payu-india.js
similarity index 100%
rename from plugins/woocommerce-admin/client/task-list/tasks/payments/payu-india.js
rename to plugins/woocommerce-admin/client/task-list/tasks/payments/methods/payu-india.js
diff --git a/plugins/woocommerce-admin/client/task-list/tasks/payments/razorpay.js b/plugins/woocommerce-admin/client/task-list/tasks/payments/methods/razorpay.js
similarity index 100%
rename from plugins/woocommerce-admin/client/task-list/tasks/payments/razorpay.js
rename to plugins/woocommerce-admin/client/task-list/tasks/payments/methods/razorpay.js
diff --git a/plugins/woocommerce-admin/client/task-list/tasks/payments/square.js b/plugins/woocommerce-admin/client/task-list/tasks/payments/methods/square.js
similarity index 100%
rename from plugins/woocommerce-admin/client/task-list/tasks/payments/square.js
rename to plugins/woocommerce-admin/client/task-list/tasks/payments/methods/square.js
diff --git a/plugins/woocommerce-admin/client/task-list/tasks/payments/stripe.js b/plugins/woocommerce-admin/client/task-list/tasks/payments/methods/stripe.js
similarity index 100%
rename from plugins/woocommerce-admin/client/task-list/tasks/payments/stripe.js
rename to plugins/woocommerce-admin/client/task-list/tasks/payments/methods/stripe.js
diff --git a/plugins/woocommerce-admin/client/task-list/tasks/payments/wcpay/index.js b/plugins/woocommerce-admin/client/task-list/tasks/payments/methods/wcpay/index.js
similarity index 100%
rename from plugins/woocommerce-admin/client/task-list/tasks/payments/wcpay/index.js
rename to plugins/woocommerce-admin/client/task-list/tasks/payments/methods/wcpay/index.js
diff --git a/plugins/woocommerce-admin/client/task-list/tasks/payments/wcpay/install-activate-and-connect.js b/plugins/woocommerce-admin/client/task-list/tasks/payments/methods/wcpay/install-activate-and-connect.js
similarity index 93%
rename from plugins/woocommerce-admin/client/task-list/tasks/payments/wcpay/install-activate-and-connect.js
rename to plugins/woocommerce-admin/client/task-list/tasks/payments/methods/wcpay/install-activate-and-connect.js
index db9bfb94bc0..74683e2942b 100644
--- a/plugins/woocommerce-admin/client/task-list/tasks/payments/wcpay/install-activate-and-connect.js
+++ b/plugins/woocommerce-admin/client/task-list/tasks/payments/methods/wcpay/install-activate-and-connect.js
@@ -9,7 +9,7 @@ import { recordEvent } from '@woocommerce/tracks';
/**
* Internal dependencies
*/
-import { createNoticesFromResponse } from '../../../../lib/notices';
+import { createNoticesFromResponse } from '~/lib/notices';
export function installActivateAndConnectWcpay(
reject,
diff --git a/plugins/woocommerce-admin/client/task-list/tasks/payments/wcpay/is-supported.js b/plugins/woocommerce-admin/client/task-list/tasks/payments/methods/wcpay/is-supported.js
similarity index 100%
rename from plugins/woocommerce-admin/client/task-list/tasks/payments/wcpay/is-supported.js
rename to plugins/woocommerce-admin/client/task-list/tasks/payments/methods/wcpay/is-supported.js
diff --git a/plugins/woocommerce-admin/client/task-list/tasks/payments/wcpay/wcpay-usage-modal.js b/plugins/woocommerce-admin/client/task-list/tasks/payments/methods/wcpay/wcpay-usage-modal.js
similarity index 95%
rename from plugins/woocommerce-admin/client/task-list/tasks/payments/wcpay/wcpay-usage-modal.js
rename to plugins/woocommerce-admin/client/task-list/tasks/payments/methods/wcpay/wcpay-usage-modal.js
index f62153c8c5e..efc0f213a59 100644
--- a/plugins/woocommerce-admin/client/task-list/tasks/payments/wcpay/wcpay-usage-modal.js
+++ b/plugins/woocommerce-admin/client/task-list/tasks/payments/methods/wcpay/wcpay-usage-modal.js
@@ -10,7 +10,7 @@ import { Link } from '@woocommerce/components';
/**
* Internal dependencies
*/
-import UsageModal from '../../../../profile-wizard/steps/usage-modal';
+import UsageModal from '~/profile-wizard/steps/usage-modal';
const WCPayUsageModal = () => {
const query = getQuery();
diff --git a/plugins/woocommerce-admin/client/task-list/tasks/payments/wcpay/wcpay.js b/plugins/woocommerce-admin/client/task-list/tasks/payments/methods/wcpay/wcpay.js
similarity index 100%
rename from plugins/woocommerce-admin/client/task-list/tasks/payments/wcpay/wcpay.js
rename to plugins/woocommerce-admin/client/task-list/tasks/payments/methods/wcpay/wcpay.js
diff --git a/plugins/woocommerce-admin/client/task-list/tasks/payments/recommended-ribbon.js b/plugins/woocommerce-admin/client/task-list/tasks/payments/recommended-ribbon.js
new file mode 100644
index 00000000000..73d4019d24f
--- /dev/null
+++ b/plugins/woocommerce-admin/client/task-list/tasks/payments/recommended-ribbon.js
@@ -0,0 +1,22 @@
+/**
+ * External dependencies
+ */
+import { __ } from '@wordpress/i18n';
+
+const localPartners = [ 'mercadopago' ];
+
+export const RecommendedRibbon = ( { methodKey, isPill = false } ) => {
+ const classes = isPill
+ ? 'woocommerce-task-payment__recommended-pill'
+ : 'woocommerce-task-payment__recommended-ribbon';
+
+ const text = localPartners.includes( methodKey )
+ ? __( 'Local Partner', 'woocommerce-admin' )
+ : __( 'Recommended', 'woocommerce-admin' );
+
+ return (
+
+ { text }
+
+ );
+};
diff --git a/plugins/woocommerce-admin/client/task-list/tasks/payments/setup.js b/plugins/woocommerce-admin/client/task-list/tasks/payments/setup.js
new file mode 100644
index 00000000000..038ec1034bc
--- /dev/null
+++ b/plugins/woocommerce-admin/client/task-list/tasks/payments/setup.js
@@ -0,0 +1,81 @@
+/**
+ * External dependencies
+ */
+import { __, sprintf } from '@wordpress/i18n';
+import { Card, CardBody } from '@wordpress/components';
+import { cloneElement, useMemo } from '@wordpress/element';
+import { Plugins } from '@woocommerce/components';
+import { PLUGINS_STORE_NAME, pluginNames } from '@woocommerce/data';
+import { recordEvent } from '@woocommerce/tracks';
+import { useSelect } from '@wordpress/data';
+
+/**
+ * Internal dependencies
+ */
+import { createNoticesFromResponse } from '~/lib/notices';
+
+export const Setup = ( { method, markConfigured, query } ) => {
+ const { activePlugins } = useSelect( ( select ) => {
+ const { getActivePlugins } = select( PLUGINS_STORE_NAME );
+
+ return {
+ activePlugins: getActivePlugins(),
+ };
+ } );
+
+ const installStep = useMemo( () => {
+ if ( ! method.plugins || ! method.plugins.length ) {
+ return;
+ }
+
+ const pluginsToInstall = method.plugins.filter(
+ ( m ) => ! activePlugins.includes( m )
+ );
+ const pluginNamesString = method.plugins
+ .map( ( pluginSlug ) => pluginNames[ pluginSlug ] )
+ .join( ' ' + __( 'and', 'woocommerce-admin' ) + ' ' );
+
+ return {
+ key: 'install',
+ label: sprintf(
+ /* translators: %s = one or more plugin names joined by "and" */
+ __( 'Install %s', 'woocommerce-admin' ),
+ pluginNamesString
+ ),
+ content: (
+ {
+ createNoticesFromResponse( response );
+ recordEvent( 'tasklist_payment_install_method', {
+ plugins: method.plugins,
+ } );
+ } }
+ onError={ ( errors, response ) =>
+ createNoticesFromResponse( response )
+ }
+ autoInstall
+ pluginSlugs={ method.plugins }
+ />
+ ),
+ isComplete: ! pluginsToInstall.length,
+ };
+ }, [ activePlugins, method.plugins ] );
+
+ if ( ! method.container ) {
+ return null;
+ }
+
+ return (
+
+
+ { cloneElement( method.container, {
+ methodConfig: method,
+ query,
+ installStep,
+ markConfigured,
+ hasCbdIndustry: method.hasCbdIndustry,
+ } ) }
+
+
+ );
+};
diff --git a/plugins/woocommerce-admin/client/task-list/test/payments.js b/plugins/woocommerce-admin/client/task-list/test/payments.js
index f2bfebde652..9fdb7103842 100644
--- a/plugins/woocommerce-admin/client/task-list/test/payments.js
+++ b/plugins/woocommerce-admin/client/task-list/test/payments.js
@@ -8,7 +8,7 @@ import apiFetch from '@wordpress/api-fetch';
/**
* Internal dependencies
*/
-import { PayPal, PAYPAL_PLUGIN } from '../tasks/payments/paypal';
+import { PayPal, PAYPAL_PLUGIN } from '../tasks/payments/methods/paypal';
import { getPaymentMethods } from '../tasks/payments/methods';
import { setMethodEnabledOption } from '../../task-list/tasks/payments';
import { GenericPaymentStep } from '../tasks/payments/generic-payment-step';
diff --git a/plugins/woocommerce-admin/readme.txt b/plugins/woocommerce-admin/readme.txt
index acc76cfa254..a57adc730f6 100644
--- a/plugins/woocommerce-admin/readme.txt
+++ b/plugins/woocommerce-admin/readme.txt
@@ -80,6 +80,7 @@ Release and roadmap notes are available on the [WooCommerce Developers Blog](htt
- Fix: Retain persisted queries when navigating to Homescreen #6614
- Update: Update choose niche note cta URL #6733
- Fix: Update folded header style #6724
+- Tweak: Refactor payments to allow management of methods #6786
- Fix: Fix unreleated variations showing up in the Products reports #6647
- Tweak: Add tracking data for the preview site btn #6623
- Tweak: Update WC Payments copy on the task list #6734
diff --git a/plugins/woocommerce-admin/tests/e2e/pages/PaymentsSetup.ts b/plugins/woocommerce-admin/tests/e2e/pages/PaymentsSetup.ts
index b692fea1086..35c3795ddd7 100644
--- a/plugins/woocommerce-admin/tests/e2e/pages/PaymentsSetup.ts
+++ b/plugins/woocommerce-admin/tests/e2e/pages/PaymentsSetup.ts
@@ -3,6 +3,7 @@
*/
import { waitForElementByText } from '../utils/actions';
import { BasePage } from './BasePage';
+import { getElementByText } from '../utils/actions';
type PaymentMethodWithSetupButton =
| 'wcpay'
@@ -39,15 +40,10 @@ export class PaymentsSetup extends BasePage {
}
async methodHasBeenSetup( method: PaymentMethod ) {
- const toggle = this.getFormToggle(
- `.woocommerce-task-payment-${ method }`
- );
-
- await toggle.isEnabled();
+ await getElementByText( 'button', 'Manage', `.woocommerce-task-payment-${ method }` )
}
async enableCashOnDelivery() {
- const toggle = this.getFormToggle( '.woocommerce-task-payment-cod' );
- await toggle.switchOn();
+ await this.clickButtonWithText( 'Enable' );
}
}
diff --git a/plugins/woocommerce-admin/tests/e2e/specs/tasks/payment.test.ts b/plugins/woocommerce-admin/tests/e2e/specs/tasks/payment.test.ts
index 59fc6aba8e7..7ff7851f00c 100644
--- a/plugins/woocommerce-admin/tests/e2e/specs/tasks/payment.test.ts
+++ b/plugins/woocommerce-admin/tests/e2e/specs/tasks/payment.test.ts
@@ -53,7 +53,7 @@ describe( 'Payment setup task', () => {
await paymentsSetup.methodHasBeenSetup( 'bacs' );
} );
- it( 'Toggling cash on delivery enables the payment method', async () => {
+ it( 'Enabling cash on delivery enables the payment method', async () => {
await paymentsSetup.enableCashOnDelivery();
await paymentsSetup.methodHasBeenSetup( 'cod' );
} );