mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-05 08:59:14 +08:00
Clean up the Features store a bit and split the TabOverview into separate files
This commit is contained in:
parent
1497cbae52
commit
84854e737a
18 changed files with 643 additions and 901 deletions
|
@ -0,0 +1,36 @@
|
|||
import { __ } from '@wordpress/i18n';
|
||||
import { Button, Icon } from '@wordpress/components';
|
||||
import { reusableBlock } from '@wordpress/icons';
|
||||
|
||||
const FeatureDescription = ( { refreshHandler, isRefreshing } ) => {
|
||||
const buttonLabel = isRefreshing
|
||||
? __( 'Refreshing…', 'woocommerce-paypal-payments' )
|
||||
: __( 'Refresh', 'woocommerce-paypal-payments' );
|
||||
|
||||
return (
|
||||
<>
|
||||
<p>
|
||||
{ __(
|
||||
'Enable additional features and capabilities on your WooCommerce store.',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
</p>
|
||||
<p>
|
||||
{ __(
|
||||
'Click Refresh to update your current features after making changes.',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
</p>
|
||||
<Button
|
||||
variant="tertiary"
|
||||
onClick={ refreshHandler }
|
||||
disabled={ isRefreshing }
|
||||
>
|
||||
<Icon icon={ reusableBlock } size={ 18 } />
|
||||
{ buttonLabel }
|
||||
</Button>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default FeatureDescription;
|
|
@ -0,0 +1,70 @@
|
|||
import { __ } from '@wordpress/i18n';
|
||||
import { FeatureSettingsBlock } from '../../../../../ReusableComponents/SettingsBlocks';
|
||||
import { Content } from '../../../../../ReusableComponents/Elements';
|
||||
import { TITLE_BADGE_POSITIVE } from '../../../../../ReusableComponents/TitleBadge';
|
||||
import { selectTab, TAB_IDS } from '../../../../../../utils/tabSelector';
|
||||
import { setActiveModal } from '../../../../../../data/common/actions';
|
||||
|
||||
const FeatureItem = ( {
|
||||
isBusy,
|
||||
isSandbox,
|
||||
title,
|
||||
description,
|
||||
buttons,
|
||||
enabled,
|
||||
notes,
|
||||
} ) => {
|
||||
const getButtonUrl = ( button ) => {
|
||||
if ( button.urls ) {
|
||||
return isSandbox ? button.urls.sandbox : button.urls.live;
|
||||
}
|
||||
|
||||
return button.url;
|
||||
};
|
||||
|
||||
const visibleButtons = buttons.filter(
|
||||
( button ) =>
|
||||
! button.showWhen || // Learn more buttons
|
||||
( enabled && button.showWhen === 'enabled' ) ||
|
||||
( ! enabled && button.showWhen === 'disabled' )
|
||||
);
|
||||
const handleClick = async ( feature ) => {
|
||||
if ( feature.action?.type === 'tab' ) {
|
||||
const tabId = TAB_IDS[ feature.action.tab.toUpperCase() ];
|
||||
await selectTab( tabId, feature.action.section );
|
||||
}
|
||||
if ( feature.action?.modal ) {
|
||||
setActiveModal( feature.action.modal );
|
||||
}
|
||||
};
|
||||
|
||||
const actionProps = {
|
||||
isBusy,
|
||||
enabled,
|
||||
notes,
|
||||
buttons: visibleButtons.map( ( button ) => ( {
|
||||
...button,
|
||||
url: getButtonUrl( button ),
|
||||
onClick: () => handleClick( button ),
|
||||
} ) ),
|
||||
};
|
||||
|
||||
if ( enabled ) {
|
||||
actionProps.badge = {
|
||||
text: __( 'Active', 'woocommerce-paypal-payments' ),
|
||||
type: TITLE_BADGE_POSITIVE,
|
||||
};
|
||||
}
|
||||
|
||||
return (
|
||||
<Content>
|
||||
<FeatureSettingsBlock
|
||||
title={ title }
|
||||
description={ description }
|
||||
actionProps={ actionProps }
|
||||
/>
|
||||
</Content>
|
||||
);
|
||||
};
|
||||
|
||||
export default FeatureItem;
|
|
@ -0,0 +1,95 @@
|
|||
import { __, sprintf } from '@wordpress/i18n';
|
||||
import { useState } from '@wordpress/element';
|
||||
import { useDispatch } from '@wordpress/data';
|
||||
import { store as noticesStore } from '@wordpress/notices';
|
||||
import FeatureItem from './FeatureItem';
|
||||
import FeatureDescription from './FeatureDescription';
|
||||
import { ContentWrapper } from '../../../../../ReusableComponents/Elements';
|
||||
import SettingsCard from '../../../../../ReusableComponents/SettingsCard';
|
||||
import { useMerchantInfo } from '../../../../../../data/common/hooks';
|
||||
import { STORE_NAME as COMMON_STORE_NAME } from '../../../../../../data/common';
|
||||
import {
|
||||
NOTIFICATION_ERROR,
|
||||
NOTIFICATION_SUCCESS,
|
||||
} from '../../../../../ReusableComponents/Icons';
|
||||
import { useFeatures } from '../../../../../../data/features/hooks';
|
||||
|
||||
const Features = () => {
|
||||
const [ isRefreshing, setIsRefreshing ] = useState( false );
|
||||
const { merchant } = useMerchantInfo();
|
||||
const { features, fetchFeatures } = useFeatures();
|
||||
const { refreshFeatureStatuses } = useDispatch( COMMON_STORE_NAME );
|
||||
const { createSuccessNotice, createErrorNotice } =
|
||||
useDispatch( noticesStore );
|
||||
|
||||
if ( ! features || features.length === 0 ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const refreshHandler = async () => {
|
||||
setIsRefreshing( true );
|
||||
try {
|
||||
const statusResult = await refreshFeatureStatuses();
|
||||
if ( ! statusResult?.success ) {
|
||||
throw new Error(
|
||||
statusResult?.message || 'Failed to refresh status'
|
||||
);
|
||||
}
|
||||
|
||||
const featuresResult = await fetchFeatures();
|
||||
if ( featuresResult.success ) {
|
||||
createSuccessNotice(
|
||||
__(
|
||||
'Features refreshed successfully.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
{ icon: NOTIFICATION_SUCCESS }
|
||||
);
|
||||
} else {
|
||||
throw new Error(
|
||||
featuresResult?.message || 'Failed to fetch features'
|
||||
);
|
||||
}
|
||||
} catch ( error ) {
|
||||
createErrorNotice(
|
||||
sprintf(
|
||||
/* translators: %s: error message */
|
||||
__( 'Operation failed: %s', 'woocommerce-paypal-payments' ),
|
||||
error.message ||
|
||||
__( 'Unknown error', 'woocommerce-paypal-payments' )
|
||||
),
|
||||
{ icon: NOTIFICATION_ERROR }
|
||||
);
|
||||
} finally {
|
||||
setIsRefreshing( false );
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<SettingsCard
|
||||
className="ppcp-r-tab-overview-features"
|
||||
title={ __( 'Features', 'woocommerce-paypal-payments' ) }
|
||||
description={
|
||||
<FeatureDescription
|
||||
refreshHandler={ refreshHandler }
|
||||
isRefreshing={ isRefreshing }
|
||||
/>
|
||||
}
|
||||
contentContainer={ false }
|
||||
>
|
||||
<ContentWrapper>
|
||||
{ features.map( ( { id, isEligible, ...feature } ) => (
|
||||
<FeatureItem
|
||||
key={ id }
|
||||
isBusy={ isRefreshing }
|
||||
isSandbox={ merchant.isSandbox }
|
||||
enabled={ isEligible }
|
||||
{ ...feature }
|
||||
/>
|
||||
) ) }
|
||||
</ContentWrapper>
|
||||
</SettingsCard>
|
||||
);
|
||||
};
|
||||
|
||||
export default Features;
|
|
@ -0,0 +1,72 @@
|
|||
import { __ } from '@wordpress/i18n';
|
||||
import { FeatureSettingsBlock } from '../../../../../ReusableComponents/SettingsBlocks';
|
||||
import {
|
||||
Content,
|
||||
ContentWrapper,
|
||||
} from '../../../../../ReusableComponents/Elements';
|
||||
import SettingsCard from '../../../../../ReusableComponents/SettingsCard';
|
||||
|
||||
const Help = () => {
|
||||
return (
|
||||
<SettingsCard
|
||||
className="ppcp-r-tab-overview-help"
|
||||
title={ __( 'Help Center', 'woocommerce-paypal-payments' ) }
|
||||
description={ __(
|
||||
'Access detailed guides and responsive support to streamline setup and enhance your experience.',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
contentContainer={ false }
|
||||
>
|
||||
<ContentWrapper>
|
||||
<Content>
|
||||
<FeatureSettingsBlock
|
||||
title={ __(
|
||||
'Documentation',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
description={ __(
|
||||
'Find detailed guides and resources to help you set up, manage, and optimize your PayPal integration.',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
actionProps={ {
|
||||
buttons: [
|
||||
{
|
||||
type: 'tertiary',
|
||||
text: __(
|
||||
'View full documentation',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
url: 'https://woocommerce.com/document/woocommerce-paypal-payments/',
|
||||
},
|
||||
],
|
||||
} }
|
||||
/>
|
||||
</Content>
|
||||
|
||||
<Content>
|
||||
<FeatureSettingsBlock
|
||||
title={ __( 'Support', 'woocommerce-paypal-payments' ) }
|
||||
description={ __(
|
||||
'Need help? Access troubleshooting tips or contact our support team for personalized assistance.',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
actionProps={ {
|
||||
buttons: [
|
||||
{
|
||||
type: 'tertiary',
|
||||
text: __(
|
||||
'View support options',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
url: 'https://woocommerce.com/document/woocommerce-paypal-payments/#get-help ',
|
||||
},
|
||||
],
|
||||
} }
|
||||
/>
|
||||
</Content>
|
||||
</ContentWrapper>
|
||||
</SettingsCard>
|
||||
);
|
||||
};
|
||||
|
||||
export default Help;
|
|
@ -0,0 +1,86 @@
|
|||
import { __ } from '@wordpress/i18n';
|
||||
import { useState } from '@wordpress/element';
|
||||
import { Button, Icon } from '@wordpress/components';
|
||||
import { useDispatch } from '@wordpress/data';
|
||||
import { reusableBlock } from '@wordpress/icons';
|
||||
import { store as noticesStore } from '@wordpress/notices';
|
||||
import { TodoSettingsBlock } from '../../../../../ReusableComponents/SettingsBlocks';
|
||||
import SettingsCard from '../../../../../ReusableComponents/SettingsCard';
|
||||
import { useTodos } from '../../../../../../data/todos/hooks';
|
||||
import { STORE_NAME as COMMON_STORE_NAME } from '../../../../../../data/common';
|
||||
import { STORE_NAME as TODOS_STORE_NAME } from '../../../../../../data/todos';
|
||||
import { NOTIFICATION_SUCCESS } from '../../../../../ReusableComponents/Icons';
|
||||
|
||||
const Todos = () => {
|
||||
const [ isResetting, setIsResetting ] = useState( false );
|
||||
const { todos, isReady: areTodosReady, dismissTodo } = useTodos();
|
||||
// eslint-disable-next-line no-shadow
|
||||
const { setActiveModal, setActiveHighlight } =
|
||||
useDispatch( COMMON_STORE_NAME );
|
||||
const { resetDismissedTodos, setDismissedTodos } =
|
||||
useDispatch( TODOS_STORE_NAME );
|
||||
const { createSuccessNotice } = useDispatch( noticesStore );
|
||||
|
||||
const showTodos = areTodosReady && todos.length > 0;
|
||||
|
||||
const resetHandler = async () => {
|
||||
setIsResetting( true );
|
||||
try {
|
||||
await setDismissedTodos( [] );
|
||||
await resetDismissedTodos();
|
||||
|
||||
createSuccessNotice(
|
||||
__(
|
||||
'Dismissed items restored successfully.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
{ icon: NOTIFICATION_SUCCESS }
|
||||
);
|
||||
} finally {
|
||||
setIsResetting( false );
|
||||
}
|
||||
};
|
||||
|
||||
if ( ! showTodos ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<SettingsCard
|
||||
className="ppcp-r-tab-overview-todo"
|
||||
title={ __( 'Things to do next', 'woocommerce-paypal-payments' ) }
|
||||
description={
|
||||
<>
|
||||
<p>
|
||||
{ __(
|
||||
'Complete these tasks to keep your store updated with the latest products and services.',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
</p>
|
||||
<Button
|
||||
variant="tertiary"
|
||||
onClick={ resetHandler }
|
||||
disabled={ isResetting }
|
||||
>
|
||||
<Icon icon={ reusableBlock } size={ 18 } />
|
||||
{ isResetting
|
||||
? __( 'Restoring…', 'woocommerce-paypal-payments' )
|
||||
: __(
|
||||
'Restore dismissed Things To Do',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
</Button>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<TodoSettingsBlock
|
||||
todosData={ todos }
|
||||
setActiveModal={ setActiveModal }
|
||||
setActiveHighlight={ setActiveHighlight }
|
||||
onDismissTodo={ dismissTodo }
|
||||
/>
|
||||
</SettingsCard>
|
||||
);
|
||||
};
|
||||
|
||||
export default Todos;
|
|
@ -1,278 +0,0 @@
|
|||
import { __ } from '@wordpress/i18n';
|
||||
import { TAB_IDS, selectTab } from '../../../../../utils/tabSelector';
|
||||
import { payLaterMessaging } from './pay-later-messaging';
|
||||
|
||||
export const getFeatures = ( setActiveModal ) => {
|
||||
const storeCountry = ppcpSettings?.storeCountry;
|
||||
const features = [
|
||||
{
|
||||
id: 'save_paypal_and_venmo',
|
||||
title: __( 'Save PayPal and Venmo', 'woocommerce-paypal-payments' ),
|
||||
description: __(
|
||||
'Securely save PayPal and Venmo payment methods for subscriptions or return buyers.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
buttons: [
|
||||
{
|
||||
type: 'secondary',
|
||||
text: __( 'Configure', 'woocommerce-paypal-payments' ),
|
||||
onClick: () => {
|
||||
selectTab(
|
||||
TAB_IDS.SETTINGS,
|
||||
'ppcp--save-payment-methods'
|
||||
);
|
||||
},
|
||||
showWhen: 'enabled',
|
||||
class: 'small-button',
|
||||
},
|
||||
{
|
||||
type: 'secondary',
|
||||
text: __( 'Sign up', 'woocommerce-paypal-payments' ),
|
||||
urls: {
|
||||
sandbox:
|
||||
'https://www.sandbox.paypal.com/bizsignup/entry?product=ADVANCED_VAULTING',
|
||||
live: 'https://www.paypal.com/bizsignup/entry?product=ADVANCED_VAULTING',
|
||||
},
|
||||
showWhen: 'disabled',
|
||||
class: 'small-button',
|
||||
},
|
||||
{
|
||||
type: 'tertiary',
|
||||
text: __( 'Learn more', 'woocommerce-paypal-payments' ),
|
||||
url: 'https://www.paypal.com/us/enterprise/payment-processing/accept-venmo',
|
||||
class: 'small-button',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'advanced_credit_and_debit_cards',
|
||||
title: __(
|
||||
'Advanced Credit and Debit Cards',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
description: __(
|
||||
'Process major credit and debit cards including Visa, Mastercard, American Express and Discover.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
buttons: [
|
||||
{
|
||||
type: 'secondary',
|
||||
text: __( 'Configure', 'woocommerce-paypal-payments' ),
|
||||
onClick: () => {
|
||||
selectTab(
|
||||
TAB_IDS.PAYMENT_METHODS,
|
||||
'ppcp-card-payments-card'
|
||||
).then( () => {
|
||||
setActiveModal( 'ppcp-credit-card-gateway' );
|
||||
} );
|
||||
},
|
||||
showWhen: 'enabled',
|
||||
class: 'small-button',
|
||||
},
|
||||
{
|
||||
type: 'secondary',
|
||||
text: __( 'Sign up', 'woocommerce-paypal-payments' ),
|
||||
urls: {
|
||||
sandbox:
|
||||
'https://www.sandbox.paypal.com/bizsignup/entry?product=ppcp',
|
||||
live: 'https://www.paypal.com/bizsignup/entry?product=ppcp',
|
||||
},
|
||||
showWhen: 'disabled',
|
||||
class: 'small-button',
|
||||
},
|
||||
{
|
||||
type: 'tertiary',
|
||||
text: __( 'Learn more', 'woocommerce-paypal-payments' ),
|
||||
url: 'https://developer.paypal.com/studio/checkout/advanced',
|
||||
class: 'small-button',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'alternative_payment_methods',
|
||||
title: __(
|
||||
'Alternative Payment Methods',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
description: __(
|
||||
'Offer global, country-specific payment options for your customers.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
buttons: [
|
||||
{
|
||||
type: 'secondary',
|
||||
text: __( 'Configure', 'woocommerce-paypal-payments' ),
|
||||
onClick: () => {
|
||||
selectTab(
|
||||
TAB_IDS.PAYMENT_METHODS,
|
||||
'ppcp-alternative-payments-card'
|
||||
);
|
||||
},
|
||||
showWhen: 'enabled',
|
||||
class: 'small-button',
|
||||
},
|
||||
{
|
||||
type: 'secondary',
|
||||
text: __( 'Sign up', 'woocommerce-paypal-payments' ),
|
||||
url: 'https://developer.paypal.com/docs/checkout/apm/',
|
||||
showWhen: 'disabled',
|
||||
class: 'small-button',
|
||||
},
|
||||
{
|
||||
type: 'tertiary',
|
||||
text: __( 'Learn more', 'woocommerce-paypal-payments' ),
|
||||
url: 'https://developer.paypal.com/docs/checkout/apm/',
|
||||
class: 'small-button',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'google_pay',
|
||||
title: __( 'Google Pay', 'woocommerce-paypal-payments' ),
|
||||
description: __(
|
||||
'Let customers pay using their Google Pay wallet.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
buttons: [
|
||||
{
|
||||
type: 'secondary',
|
||||
text: __( 'Configure', 'woocommerce-paypal-payments' ),
|
||||
onClick: () => {
|
||||
selectTab(
|
||||
TAB_IDS.PAYMENT_METHODS,
|
||||
'ppcp-card-payments-card'
|
||||
).then( () => {
|
||||
setActiveModal( 'ppcp-googlepay' );
|
||||
} );
|
||||
},
|
||||
showWhen: 'enabled',
|
||||
class: 'small-button',
|
||||
},
|
||||
{
|
||||
type: 'secondary',
|
||||
text: __( 'Sign up', 'woocommerce-paypal-payments' ),
|
||||
urls: {
|
||||
sandbox:
|
||||
'https://www.sandbox.paypal.com/bizsignup/add-product?product=payment_methods&capabilities=GOOGLE_PAY',
|
||||
live: 'https://www.paypal.com/bizsignup/add-product?product=payment_methods&capabilities=GOOGLE_PAY',
|
||||
},
|
||||
showWhen: 'disabled',
|
||||
class: 'small-button',
|
||||
},
|
||||
{
|
||||
type: 'tertiary',
|
||||
text: __( 'Learn more', 'woocommerce-paypal-payments' ),
|
||||
url: 'https://developer.paypal.com/docs/checkout/apm/google-pay/',
|
||||
class: 'small-button',
|
||||
},
|
||||
],
|
||||
notes: [
|
||||
__(
|
||||
'¹PayPal Q2 Earnings-2021.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'apple_pay',
|
||||
title: __( 'Apple Pay', 'woocommerce-paypal-payments' ),
|
||||
description: __(
|
||||
'Let customers pay using their Apple Pay wallet.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
buttons: [
|
||||
{
|
||||
type: 'secondary',
|
||||
text: __( 'Configure', 'woocommerce-paypal-payments' ),
|
||||
onClick: () => {
|
||||
selectTab(
|
||||
TAB_IDS.PAYMENT_METHODS,
|
||||
'ppcp-card-payments-card'
|
||||
).then( () => {
|
||||
setActiveModal( 'ppcp-applepay' );
|
||||
} );
|
||||
},
|
||||
showWhen: 'enabled',
|
||||
class: 'small-button',
|
||||
},
|
||||
{
|
||||
type: 'secondary',
|
||||
text: __(
|
||||
'Domain registration',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
urls: {
|
||||
sandbox:
|
||||
'https://www.sandbox.paypal.com/uccservicing/apm/applepay',
|
||||
live: 'https://www.paypal.com/uccservicing/apm/applepay',
|
||||
},
|
||||
showWhen: 'enabled',
|
||||
class: 'small-button',
|
||||
},
|
||||
{
|
||||
type: 'secondary',
|
||||
text: __( 'Sign up', 'woocommerce-paypal-payments' ),
|
||||
urls: {
|
||||
sandbox:
|
||||
'https://www.sandbox.paypal.com/bizsignup/add-product?product=payment_methods&capabilities=APPLE_PAY',
|
||||
live: 'https://www.paypal.com/bizsignup/add-product?product=payment_methods&capabilities=APPLE_PAY',
|
||||
},
|
||||
showWhen: 'disabled',
|
||||
class: 'small-button',
|
||||
},
|
||||
{
|
||||
type: 'tertiary',
|
||||
text: __( 'Learn more', 'woocommerce-paypal-payments' ),
|
||||
url: 'https://developer.paypal.com/docs/checkout/apm/apple-pay/',
|
||||
class: 'small-button',
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const countryData = payLaterMessaging[ storeCountry ] || {};
|
||||
|
||||
if (
|
||||
!! window.ppcpSettings?.isPayLaterConfiguratorAvailable &&
|
||||
countryData
|
||||
) {
|
||||
const countryLocation = [
|
||||
'UK',
|
||||
'ES',
|
||||
'IT',
|
||||
'FR',
|
||||
'US',
|
||||
'DE',
|
||||
'AU',
|
||||
].includes( storeCountry )
|
||||
? storeCountry.toLowerCase()
|
||||
: 'us';
|
||||
features.push( {
|
||||
id: 'pay_later_messaging',
|
||||
title: __( 'Pay Later Messaging', 'woocommerce-paypal-payments' ),
|
||||
description: __(
|
||||
'Let customers know they can buy now and pay later with PayPal. Adding this messaging can boost conversion rates and increase cart sizes by 39%¹, with no extra cost to you—plus, you get paid up front.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
buttons: [
|
||||
{
|
||||
type: 'secondary',
|
||||
text: __( 'Configure', 'woocommerce-paypal-payments' ),
|
||||
onClick: () => {
|
||||
selectTab( TAB_IDS.PAY_LATER_MESSAGING );
|
||||
},
|
||||
showWhen: 'enabled',
|
||||
class: 'small-button',
|
||||
},
|
||||
{
|
||||
type: 'tertiary',
|
||||
text: __( 'Learn more', 'woocommerce-paypal-payments' ),
|
||||
url: `https://www.paypal.com/${ countryLocation }/business/accept-payments/checkout/installments`,
|
||||
class: 'small-button',
|
||||
},
|
||||
],
|
||||
} );
|
||||
}
|
||||
|
||||
return features;
|
||||
};
|
|
@ -1,356 +1,25 @@
|
|||
import { __, sprintf } from '@wordpress/i18n';
|
||||
import { useState, useEffect } from '@wordpress/element';
|
||||
import { Button, Icon } from '@wordpress/components';
|
||||
import { useDispatch } from '@wordpress/data';
|
||||
import { reusableBlock } from '@wordpress/icons';
|
||||
import { store as noticesStore } from '@wordpress/notices';
|
||||
|
||||
import {
|
||||
TodoSettingsBlock,
|
||||
FeatureSettingsBlock,
|
||||
} from '../../../ReusableComponents/SettingsBlocks';
|
||||
import { Content, ContentWrapper } from '../../../ReusableComponents/Elements';
|
||||
import SettingsCard from '../../../ReusableComponents/SettingsCard';
|
||||
import { TITLE_BADGE_POSITIVE } from '../../../ReusableComponents/TitleBadge';
|
||||
import { useTodos } from '../../../../data/todos/hooks';
|
||||
import { useMerchantInfo } from '../../../../data/common/hooks';
|
||||
import { STORE_NAME as COMMON_STORE_NAME } from '../../../../data/common';
|
||||
import { STORE_NAME as TODOS_STORE_NAME } from '../../../../data/todos';
|
||||
import { CommonHooks, TodosHooks } from '../../../../data';
|
||||
|
||||
import {
|
||||
NOTIFICATION_ERROR,
|
||||
NOTIFICATION_SUCCESS,
|
||||
} from '../../../ReusableComponents/Icons';
|
||||
import Todos from '../Components/Overview/Todos/Todos';
|
||||
import Features from '../Components/Overview/Features/Features';
|
||||
import Help from '../Components/Overview/Help/Help';
|
||||
import { TodosHooks, CommonHooks, FeaturesHooks } from '../../../../data';
|
||||
import SpinnerOverlay from '../../../ReusableComponents/SpinnerOverlay';
|
||||
import { useFeatures } from '../../../../data/features/hooks';
|
||||
import { selectTab, TAB_IDS } from '../../../../utils/tabSelector';
|
||||
import { setActiveModal } from '../../../../data/common/actions';
|
||||
|
||||
const TabOverview = () => {
|
||||
const { isReady: areTodosReady } = TodosHooks.useTodos();
|
||||
const { isReady: merchantIsReady } = CommonHooks.useMerchantInfo();
|
||||
const { isReady: featuresIsReady } = FeaturesHooks.useFeatures();
|
||||
|
||||
if ( ! areTodosReady || ! merchantIsReady ) {
|
||||
if ( ! areTodosReady || ! merchantIsReady || ! featuresIsReady ) {
|
||||
return <SpinnerOverlay asModal={ true } />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="ppcp-r-tab-overview">
|
||||
<OverviewTodos />
|
||||
<OverviewFeatures />
|
||||
<OverviewHelp />
|
||||
<Todos />
|
||||
<Features />
|
||||
<Help />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default TabOverview;
|
||||
|
||||
const OverviewTodos = () => {
|
||||
const [ isResetting, setIsResetting ] = useState( false );
|
||||
const { todos, isReady: areTodosReady, dismissTodo } = useTodos();
|
||||
// eslint-disable-next-line no-shadow
|
||||
const { setActiveModal, setActiveHighlight } =
|
||||
useDispatch( COMMON_STORE_NAME );
|
||||
const { resetDismissedTodos, setDismissedTodos } =
|
||||
useDispatch( TODOS_STORE_NAME );
|
||||
const { createSuccessNotice } = useDispatch( noticesStore );
|
||||
|
||||
const showTodos = areTodosReady && todos.length > 0;
|
||||
|
||||
const resetHandler = async () => {
|
||||
setIsResetting( true );
|
||||
try {
|
||||
await setDismissedTodos( [] );
|
||||
await resetDismissedTodos();
|
||||
|
||||
createSuccessNotice(
|
||||
__(
|
||||
'Dismissed items restored successfully.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
{ icon: NOTIFICATION_SUCCESS }
|
||||
);
|
||||
} finally {
|
||||
setIsResetting( false );
|
||||
}
|
||||
};
|
||||
|
||||
if ( ! showTodos ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<SettingsCard
|
||||
className="ppcp-r-tab-overview-todo"
|
||||
title={ __( 'Things to do next', 'woocommerce-paypal-payments' ) }
|
||||
description={
|
||||
<>
|
||||
<p>
|
||||
{ __(
|
||||
'Complete these tasks to keep your store updated with the latest products and services.',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
</p>
|
||||
<Button
|
||||
variant="tertiary"
|
||||
onClick={ resetHandler }
|
||||
disabled={ isResetting }
|
||||
>
|
||||
<Icon icon={ reusableBlock } size={ 18 } />
|
||||
{ isResetting
|
||||
? __( 'Restoring…', 'woocommerce-paypal-payments' )
|
||||
: __(
|
||||
'Restore dismissed Things To Do',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
</Button>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<TodoSettingsBlock
|
||||
todosData={ todos }
|
||||
setActiveModal={ setActiveModal }
|
||||
setActiveHighlight={ setActiveHighlight }
|
||||
onDismissTodo={ dismissTodo }
|
||||
/>
|
||||
</SettingsCard>
|
||||
);
|
||||
};
|
||||
|
||||
const OverviewFeatures = () => {
|
||||
const [ isRefreshing, setIsRefreshing ] = useState( false );
|
||||
const { merchant } = useMerchantInfo();
|
||||
const { refreshFeatureStatuses } = useDispatch( COMMON_STORE_NAME );
|
||||
const { createSuccessNotice, createErrorNotice } =
|
||||
useDispatch( noticesStore );
|
||||
const { features, fetchFeatures } = useFeatures();
|
||||
|
||||
useEffect( () => {
|
||||
fetchFeatures();
|
||||
}, [ fetchFeatures ] );
|
||||
|
||||
const refreshHandler = async () => {
|
||||
setIsRefreshing( true );
|
||||
|
||||
try {
|
||||
const result = await refreshFeatureStatuses();
|
||||
if ( result && ! result.success ) {
|
||||
const errorMessage = sprintf(
|
||||
/* translators: %s: error message */
|
||||
__(
|
||||
'Operation failed: %s Check WooCommerce logs for more details.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
result.message ||
|
||||
__( 'Unknown error', 'woocommerce-paypal-payments' )
|
||||
);
|
||||
|
||||
createErrorNotice( errorMessage, {
|
||||
icon: NOTIFICATION_ERROR,
|
||||
} );
|
||||
console.error(
|
||||
'Failed to refresh features:',
|
||||
result.message || 'Unknown error'
|
||||
);
|
||||
} else {
|
||||
createSuccessNotice(
|
||||
__(
|
||||
'Features refreshed successfully.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
{
|
||||
icon: NOTIFICATION_SUCCESS,
|
||||
}
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
setIsRefreshing( false );
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<SettingsCard
|
||||
className="ppcp-r-tab-overview-features"
|
||||
title={ __( 'Features', 'woocommerce-paypal-payments' ) }
|
||||
description={
|
||||
<OverviewFeatureDescription
|
||||
refreshHandler={ refreshHandler }
|
||||
isRefreshing={ isRefreshing }
|
||||
/>
|
||||
}
|
||||
contentContainer={ false }
|
||||
>
|
||||
<ContentWrapper>
|
||||
{ features.map( ( { id, ...feature } ) => (
|
||||
<OverviewFeatureItem
|
||||
key={ id }
|
||||
isBusy={ isRefreshing }
|
||||
isSandbox={ merchant.isSandbox }
|
||||
title={ feature.title }
|
||||
description={ feature.description }
|
||||
buttons={ feature.buttons }
|
||||
enabled={ feature.isEligible }
|
||||
notes={ feature.notes }
|
||||
/>
|
||||
) ) }
|
||||
</ContentWrapper>
|
||||
</SettingsCard>
|
||||
);
|
||||
};
|
||||
|
||||
const OverviewFeatureItem = ( {
|
||||
isBusy,
|
||||
isSandbox,
|
||||
title,
|
||||
description,
|
||||
buttons,
|
||||
enabled,
|
||||
notes,
|
||||
} ) => {
|
||||
const getButtonUrl = ( button ) => {
|
||||
if ( button.urls ) {
|
||||
return isSandbox ? button.urls.sandbox : button.urls.live;
|
||||
}
|
||||
|
||||
return button.url;
|
||||
};
|
||||
|
||||
const visibleButtons = buttons.filter(
|
||||
( button ) =>
|
||||
! button.showWhen || // Learn more buttons
|
||||
( enabled && button.showWhen === 'enabled' ) ||
|
||||
( ! enabled && button.showWhen === 'disabled' )
|
||||
);
|
||||
const handleClick = async ( feature ) => {
|
||||
if ( feature.action?.type === 'tab' ) {
|
||||
const tabId = TAB_IDS[ feature.action.tab.toUpperCase() ];
|
||||
await selectTab( tabId, feature.action.section );
|
||||
}
|
||||
if ( feature.action?.modal ) {
|
||||
setActiveModal( feature.action.modal );
|
||||
}
|
||||
};
|
||||
|
||||
const actionProps = {
|
||||
isBusy,
|
||||
enabled,
|
||||
notes,
|
||||
buttons: visibleButtons.map( ( button ) => ( {
|
||||
...button,
|
||||
url: getButtonUrl( button ),
|
||||
onClick: () => handleClick( button ),
|
||||
} ) ),
|
||||
};
|
||||
|
||||
if ( enabled ) {
|
||||
actionProps.badge = {
|
||||
text: __( 'Active', 'woocommerce-paypal-payments' ),
|
||||
type: TITLE_BADGE_POSITIVE,
|
||||
};
|
||||
}
|
||||
|
||||
return (
|
||||
<Content>
|
||||
<FeatureSettingsBlock
|
||||
title={ title }
|
||||
description={ description }
|
||||
actionProps={ actionProps }
|
||||
/>
|
||||
</Content>
|
||||
);
|
||||
};
|
||||
|
||||
const OverviewFeatureDescription = ( { refreshHandler, isRefreshing } ) => {
|
||||
const buttonLabel = isRefreshing
|
||||
? __( 'Refreshing…', 'woocommerce-paypal-payments' )
|
||||
: __( 'Refresh', 'woocommerce-paypal-payments' );
|
||||
|
||||
return (
|
||||
<>
|
||||
<p>
|
||||
{ __(
|
||||
'Enable additional features and capabilities on your WooCommerce store.',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
</p>
|
||||
<p>
|
||||
{ __(
|
||||
'Click Refresh to update your current features after making changes.',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
</p>
|
||||
<Button
|
||||
variant="tertiary"
|
||||
onClick={ refreshHandler }
|
||||
disabled={ isRefreshing }
|
||||
>
|
||||
<Icon icon={ reusableBlock } size={ 18 } />
|
||||
{ buttonLabel }
|
||||
</Button>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const OverviewHelp = () => {
|
||||
return (
|
||||
<SettingsCard
|
||||
className="ppcp-r-tab-overview-help"
|
||||
title={ __( 'Help Center', 'woocommerce-paypal-payments' ) }
|
||||
description={ __(
|
||||
'Access detailed guides and responsive support to streamline setup and enhance your experience.',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
contentContainer={ false }
|
||||
>
|
||||
<ContentWrapper>
|
||||
<Content>
|
||||
<FeatureSettingsBlock
|
||||
title={ __(
|
||||
'Documentation',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
description={ __(
|
||||
'Find detailed guides and resources to help you set up, manage, and optimize your PayPal integration.',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
actionProps={ {
|
||||
buttons: [
|
||||
{
|
||||
type: 'tertiary',
|
||||
text: __(
|
||||
'View full documentation',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
url: 'https://woocommerce.com/document/woocommerce-paypal-payments/',
|
||||
},
|
||||
],
|
||||
} }
|
||||
/>
|
||||
</Content>
|
||||
|
||||
<Content>
|
||||
<FeatureSettingsBlock
|
||||
title={ __( 'Support', 'woocommerce-paypal-payments' ) }
|
||||
description={ __(
|
||||
'Need help? Access troubleshooting tips or contact our support team for personalized assistance.',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
actionProps={ {
|
||||
buttons: [
|
||||
{
|
||||
type: 'tertiary',
|
||||
text: __(
|
||||
'View support options',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
url: 'https://woocommerce.com/document/woocommerce-paypal-payments/#get-help ',
|
||||
},
|
||||
],
|
||||
} }
|
||||
/>
|
||||
</Content>
|
||||
</ContentWrapper>
|
||||
</SettingsCard>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -8,8 +8,7 @@ export default {
|
|||
// Transient data
|
||||
SET_TRANSIENT: 'ppcp/features/SET_TRANSIENT',
|
||||
|
||||
// Persistent data
|
||||
SET_PERSISTENT: 'ppcp/features/SET_PERSISTENT',
|
||||
RESET: 'ppcp/features/RESET',
|
||||
// Persistant data
|
||||
SET_FEATURES: 'ppcp/features/SET_FEATURES',
|
||||
HYDRATE: 'ppcp/features/HYDRATE',
|
||||
};
|
||||
|
|
|
@ -2,16 +2,14 @@
|
|||
* Action Creators: Define functions to create action objects.
|
||||
*
|
||||
* These functions update state or trigger side effects (e.g., async operations).
|
||||
* Actions are categorized as Transient, Persistent, or Side effect.
|
||||
* Actions are categorized as Transient or Side effect.
|
||||
*
|
||||
* @file
|
||||
*/
|
||||
|
||||
import apiFetch from '@wordpress/api-fetch';
|
||||
|
||||
import ACTION_TYPES from './action-types';
|
||||
import { REST_PERSIST_PATH } from './constants';
|
||||
import { dispatch } from '@wordpress/data';
|
||||
import { REST_PATH } from './constants';
|
||||
|
||||
/**
|
||||
* @typedef {Object} Action An action object that is handled by a reducer or control.
|
||||
|
@ -20,14 +18,7 @@ import { dispatch } from '@wordpress/data';
|
|||
*/
|
||||
|
||||
/**
|
||||
* Special. Resets all values in the store to initial defaults.
|
||||
*
|
||||
* @return {Action} The action.
|
||||
*/
|
||||
export const reset = () => ( { type: ACTION_TYPES.RESET } );
|
||||
|
||||
/**
|
||||
* Persistent. Set the full store details during app initialization.
|
||||
* Set the full store details during app initialization.
|
||||
*
|
||||
* @param {{data: {}, flags?: {}}} payload
|
||||
* @return {Action} The action.
|
||||
|
@ -49,18 +40,6 @@ export const setTransient = ( prop, value ) => ( {
|
|||
payload: { [ prop ]: value },
|
||||
} );
|
||||
|
||||
/**
|
||||
* Generic persistent-data updater.
|
||||
*
|
||||
* @param {string} prop Name of the property to update.
|
||||
* @param {any} value The new value of the property.
|
||||
* @return {Action} The action.
|
||||
*/
|
||||
export const setPersistent = ( prop, value ) => ( {
|
||||
type: ACTION_TYPES.SET_PERSISTENT,
|
||||
payload: { [ prop ]: value },
|
||||
} );
|
||||
|
||||
/**
|
||||
* Transient. Marks the store as "ready", i.e., fully initialized.
|
||||
*
|
||||
|
@ -70,24 +49,39 @@ export const setPersistent = ( prop, value ) => ( {
|
|||
export const setIsReady = ( isReady ) => setTransient( 'isReady', isReady );
|
||||
|
||||
/**
|
||||
* Thunk action creator. Triggers the persistence of store data to the server.
|
||||
* Sets the features in the store.
|
||||
*
|
||||
* @return {Function} The thunk function.
|
||||
* @param {Array} features The features to set.
|
||||
* @return {Action} The action.
|
||||
*/
|
||||
export function persist() {
|
||||
return async ( { select } ) => {
|
||||
await apiFetch( {
|
||||
path: REST_PERSIST_PATH,
|
||||
method: 'POST',
|
||||
data: select.persistentData(),
|
||||
} );
|
||||
};
|
||||
}
|
||||
export const setFeatures = ( features ) => ( {
|
||||
type: ACTION_TYPES.SET_FEATURES,
|
||||
payload: features,
|
||||
} );
|
||||
|
||||
export function fetchFeatures() {
|
||||
return async () => {
|
||||
const response = await apiFetch( { path: REST_PERSIST_PATH } );
|
||||
const features = response?.data || [];
|
||||
dispatch( setFeatures( features ) );
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Fetches features from the server.
|
||||
*
|
||||
* @return {Promise<Array>} The features data.
|
||||
*/
|
||||
export const fetchFeatures = async () => {
|
||||
try {
|
||||
const response = await apiFetch( { path: REST_PATH } );
|
||||
if ( response?.data ) {
|
||||
return {
|
||||
success: true,
|
||||
features: response.data.features,
|
||||
};
|
||||
}
|
||||
return {
|
||||
success: false,
|
||||
features: [],
|
||||
};
|
||||
} catch ( e ) {
|
||||
return {
|
||||
success: false,
|
||||
error: e,
|
||||
message: e.message,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
|
|
@ -5,23 +5,4 @@
|
|||
*/
|
||||
|
||||
export const STORE_NAME = 'wc/paypal/features';
|
||||
|
||||
/**
|
||||
* REST path to hydrate data of this module by loading data from the WP DB.
|
||||
*
|
||||
* Used by: Resolvers
|
||||
* See: <UNKNOWN>.php
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
export const REST_HYDRATE_PATH = '/wc/v3/wc_paypal/features';
|
||||
|
||||
/**
|
||||
* REST path to persist data of this module to the WP DB.
|
||||
*
|
||||
* Used by: Controls
|
||||
* See: <UNKNOWN>.php
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
export const REST_PERSIST_PATH = '/wc/v3/wc_paypal/features';
|
||||
export const REST_PATH = '/wc/v3/wc_paypal/features';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Hooks: Provide the main API for components to interact with the store.
|
||||
* Hooks: Provide the main API for components to interact with the features store.
|
||||
*
|
||||
* These encapsulate store interactions, offering a consistent interface.
|
||||
* Hooks simplify data access and manipulation for components.
|
||||
|
@ -7,49 +7,61 @@
|
|||
* @file
|
||||
*/
|
||||
|
||||
import { useMemo } from '@wordpress/element';
|
||||
import { useDispatch, useSelect } from '@wordpress/data';
|
||||
|
||||
import { createHooksForStore } from '../utils';
|
||||
import { STORE_NAME } from './constants';
|
||||
|
||||
/**
|
||||
* Single source of truth for access Redux details.
|
||||
*
|
||||
* This hook returns a stable API to access actions, selectors and special hooks to generate
|
||||
* getter- and setters for transient or persistent properties.
|
||||
*
|
||||
* @return {{select, dispatch, useTransient, usePersistent}} Store data API.
|
||||
*/
|
||||
const useStoreData = () => {
|
||||
const select = useSelect( ( selectors ) => selectors( STORE_NAME ), [] );
|
||||
const dispatch = useDispatch( STORE_NAME );
|
||||
const { useTransient, usePersistent } = createHooksForStore( STORE_NAME );
|
||||
|
||||
return useMemo(
|
||||
() => ( {
|
||||
select,
|
||||
dispatch,
|
||||
useTransient,
|
||||
usePersistent,
|
||||
} ),
|
||||
[ select, dispatch, useTransient, usePersistent ]
|
||||
);
|
||||
};
|
||||
|
||||
export const useStore = () => {
|
||||
const { dispatch, useTransient } = useStoreData();
|
||||
const [ isReady ] = useTransient( 'isReady' );
|
||||
|
||||
return { persist: dispatch.persist, isReady };
|
||||
};
|
||||
import { useSelect, useDispatch } from '@wordpress/data';
|
||||
import { useEffect } from '@wordpress/element';
|
||||
import apiFetch from '@wordpress/api-fetch';
|
||||
import { STORE_NAME, REST_PATH } from './constants';
|
||||
|
||||
export const useFeatures = () => {
|
||||
const { usePersistent } = useStoreData();
|
||||
const [ features, fetchFeatures ] = usePersistent( 'features' );
|
||||
const { features, isReady } = useSelect( ( select ) => {
|
||||
const store = select( STORE_NAME );
|
||||
|
||||
return {
|
||||
features: store.getFeatures() || [],
|
||||
isReady: select( STORE_NAME ).transientData()?.isReady || false,
|
||||
};
|
||||
}, [] );
|
||||
|
||||
const { setFeatures, setIsReady } = useDispatch( STORE_NAME );
|
||||
|
||||
useEffect( () => {
|
||||
const loadInitialFeatures = async () => {
|
||||
try {
|
||||
const response = await apiFetch( { path: REST_PATH } );
|
||||
|
||||
if ( response?.data?.features ) {
|
||||
const featuresData = response.data.features;
|
||||
|
||||
if ( featuresData.length > 0 ) {
|
||||
await setFeatures( featuresData );
|
||||
await setIsReady( true );
|
||||
}
|
||||
}
|
||||
} catch ( error ) {}
|
||||
};
|
||||
|
||||
if ( ! isReady ) {
|
||||
loadInitialFeatures();
|
||||
}
|
||||
}, [ isReady, setFeatures, setIsReady ] );
|
||||
|
||||
return {
|
||||
features,
|
||||
fetchFeatures,
|
||||
isReady,
|
||||
fetchFeatures: async () => {
|
||||
try {
|
||||
const response = await apiFetch( { path: REST_PATH } );
|
||||
const featuresData = response.data?.features || [];
|
||||
|
||||
if ( featuresData.length > 0 ) {
|
||||
await setFeatures( featuresData );
|
||||
await setIsReady( true );
|
||||
return { success: true, features: featuresData };
|
||||
}
|
||||
return { success: false, features: [] };
|
||||
} catch ( error ) {
|
||||
return { success: false, error, message: error.message };
|
||||
}
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
|
@ -22,7 +22,7 @@ const defaultTransient = Object.freeze( {
|
|||
|
||||
/**
|
||||
* Persistent: Values that are loaded from and saved to the DB.
|
||||
* These represent the core todos configuration.
|
||||
* These represent the core features configuration.
|
||||
*/
|
||||
const defaultPersistent = Object.freeze( {
|
||||
features: [],
|
||||
|
@ -50,10 +50,10 @@ const reducer = createReducer( defaultTransient, defaultPersistent, {
|
|||
changeTransient( state, payload ),
|
||||
|
||||
/**
|
||||
* Updates todos list
|
||||
* Updates features list
|
||||
*
|
||||
* @param {Object} state Current state
|
||||
* @param {Object} payload Update payload
|
||||
* @param {Object} payload Update payload containing features array
|
||||
* @return {Object} Updated state
|
||||
*/
|
||||
[ ACTION_TYPES.SET_FEATURES ]: ( state, payload ) => {
|
||||
|
@ -65,7 +65,7 @@ const reducer = createReducer( defaultTransient, defaultPersistent, {
|
|||
*
|
||||
* @param {Object} state Current state
|
||||
* @param {Object} payload Hydration payload containing server data
|
||||
* @param {Object} payload.data The todos data to hydrate
|
||||
* @param {Object} payload.data The features data to hydrate
|
||||
* @return {Object} Hydrated state
|
||||
*/
|
||||
[ ACTION_TYPES.HYDRATE ]: ( state, payload ) =>
|
||||
|
|
|
@ -11,26 +11,24 @@
|
|||
import { __ } from '@wordpress/i18n';
|
||||
import apiFetch from '@wordpress/api-fetch';
|
||||
|
||||
import { REST_HYDRATE_PATH } from './constants';
|
||||
import { REST_PATH } from './constants';
|
||||
|
||||
/**
|
||||
* Retrieve settings from the site's REST API.
|
||||
* Hydrates the features data from the API.
|
||||
*
|
||||
* @return {Object} Action to dispatch.
|
||||
*/
|
||||
export function persistentData() {
|
||||
return async ( { dispatch, registry } ) => {
|
||||
export function getFeatures() {
|
||||
return async ( { dispatch } ) => {
|
||||
try {
|
||||
const result = await apiFetch( { path: REST_HYDRATE_PATH } );
|
||||
await dispatch.hydrate( result );
|
||||
await dispatch.setIsReady( true );
|
||||
} catch ( e ) {
|
||||
await registry
|
||||
.dispatch( 'core/notices' )
|
||||
.createErrorNotice(
|
||||
__(
|
||||
'Error retrieving features details.',
|
||||
'woocommerce-paypal-payments'
|
||||
)
|
||||
);
|
||||
const response = await apiFetch( { path: REST_PATH } );
|
||||
|
||||
if ( response?.features ) {
|
||||
dispatch.setFeatures( response.features );
|
||||
dispatch.setIsReady( true );
|
||||
}
|
||||
} catch ( error ) {
|
||||
console.error( 'Error fetching features:', error );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
*/
|
||||
|
||||
const EMPTY_OBJ = Object.freeze( {} );
|
||||
const EMPTY_ARR = Object.freeze( [] );
|
||||
|
||||
const getState = ( state ) => state || EMPTY_OBJ;
|
||||
|
||||
|
@ -19,3 +20,8 @@ export const transientData = ( state ) => {
|
|||
const { data, ...transientState } = getState( state );
|
||||
return transientState || EMPTY_OBJ;
|
||||
};
|
||||
|
||||
export const getFeatures = ( state ) => {
|
||||
const features = state?.features || persistentData( state ).features;
|
||||
return features || EMPTY_ARR;
|
||||
};
|
||||
|
|
|
@ -378,25 +378,25 @@ return array(
|
|||
$capabilities['google_pay'] && ! $gateways['google_pay'], // Enable Google Pay.
|
||||
);
|
||||
},
|
||||
'settings.rest.features' => static function ( ContainerInterface $container ) : FeaturesRestEndpoint {
|
||||
'settings.rest.features' => static function ( ContainerInterface $container ) : FeaturesRestEndpoint {
|
||||
return new FeaturesRestEndpoint(
|
||||
$container->get( 'settings.data.definition.features' ),
|
||||
$container->get( 'settings.rest.settings' )
|
||||
);
|
||||
},
|
||||
'settings.data.definition.features' => static function ( ContainerInterface $container ) : FeaturesDefinition {
|
||||
'settings.data.definition.features' => static function ( ContainerInterface $container ) : FeaturesDefinition {
|
||||
return new FeaturesDefinition(
|
||||
$container->get( 'settings.service.features_eligibilities' ),
|
||||
$container->get( 'settings.data.general' )
|
||||
);
|
||||
},
|
||||
'settings.service.features_eligibilities' => static function( ContainerInterface $container ): FeaturesEligibilityService {
|
||||
'settings.service.features_eligibilities' => static function( ContainerInterface $container ): FeaturesEligibilityService {
|
||||
$features = apply_filters(
|
||||
'woocommerce_paypal_payments_rest_common_merchant_features',
|
||||
array()
|
||||
);
|
||||
|
||||
$payment_endpoint = $container->get('settings.rest.payment');
|
||||
$payment_endpoint = $container->get( 'settings.rest.payment' );
|
||||
$settings = $payment_endpoint->get_details()->get_data();
|
||||
|
||||
// Settings status.
|
||||
|
@ -418,8 +418,8 @@ return array(
|
|||
$capabilities['save_paypal'], // Save PayPal and Venmo eligibility.
|
||||
$capabilities['acdc'] && ! $gateways['card-button'], // Advanced credit and debit cards eligibility.
|
||||
$capabilities['apm'], // Alternative payment methods eligibility.
|
||||
$capabilities['acdc'] && ! $capabilities['google_pay'], // Google Pay eligibility.
|
||||
$capabilities['acdc'] && ! $capabilities['apple_pay'], // Apple Pay eligibility.
|
||||
$capabilities['acdc'] && $capabilities['google_pay'], // Google Pay eligibility.
|
||||
$capabilities['acdc'] && $capabilities['apple_pay'], // Apple Pay eligibility.
|
||||
$capabilities['paylater'], // Pay Later eligibility.
|
||||
);
|
||||
},
|
||||
|
|
|
@ -18,8 +18,8 @@ use WooCommerce\PayPalCommerce\Settings\Data\GeneralSettings;
|
|||
* Provides the definitions for all available features in the system.
|
||||
* Each feature has a title, description, eligibility condition, and associated action.
|
||||
*/
|
||||
class FeaturesDefinition
|
||||
{
|
||||
class FeaturesDefinition {
|
||||
|
||||
|
||||
/**
|
||||
* The features eligibility service.
|
||||
|
@ -39,15 +39,14 @@ class FeaturesDefinition
|
|||
* Constructor.
|
||||
*
|
||||
* @param FeaturesEligibilityService $eligibilities The features eligibility service.
|
||||
* @param GeneralSettings $settings The general settings service.
|
||||
* @param GeneralSettings $settings The general settings service.
|
||||
*/
|
||||
public function __construct(
|
||||
FeaturesEligibilityService $eligibilities,
|
||||
GeneralSettings $settings
|
||||
)
|
||||
{
|
||||
GeneralSettings $settings
|
||||
) {
|
||||
$this->eligibilities = $eligibilities;
|
||||
$this->settings = $settings;
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -55,10 +54,9 @@ class FeaturesDefinition
|
|||
*
|
||||
* @return array The array of feature definitions.
|
||||
*/
|
||||
public function get(): array
|
||||
{
|
||||
public function get(): array {
|
||||
$eligibility_checks = $this->eligibilities->get_eligibility_checks();
|
||||
$paylaterCountries = [
|
||||
$paylater_countries = array(
|
||||
'UK',
|
||||
'ES',
|
||||
'IT',
|
||||
|
@ -66,216 +64,216 @@ class FeaturesDefinition
|
|||
'US',
|
||||
'DE',
|
||||
'AU',
|
||||
];
|
||||
$storeCountry = $this->settings->get_woo_settings()['country'];
|
||||
$countryLocation = in_array($storeCountry, $paylaterCountries) ? strtolower($storeCountry) : 'us';
|
||||
);
|
||||
$store_country = $this->settings->get_woo_settings()['country'];
|
||||
$country_location = in_array( $store_country, $paylater_countries, true ) ? strtolower( $store_country ) : 'us';
|
||||
|
||||
return array(
|
||||
'save_paypal_and_venmo' => array(
|
||||
'title' => __('Save PayPal and Venmo', 'woocommerce-paypal-payments'),
|
||||
'description' => __('Securely save PayPal and Venmo payment methods for subscriptions or return buyers.', 'woocommerce-paypal-payments'),
|
||||
'isEligible' => $eligibility_checks['save_paypal_and_venmo'],
|
||||
'buttons' => array(
|
||||
'save_paypal_and_venmo' => array(
|
||||
'title' => __( 'Save PayPal and Venmo', 'woocommerce-paypal-payments' ),
|
||||
'description' => __( 'Securely save PayPal and Venmo payment methods for subscriptions or return buyers.', 'woocommerce-paypal-payments' ),
|
||||
'isEligible' => $eligibility_checks['save_paypal_and_venmo'],
|
||||
'buttons' => array(
|
||||
array(
|
||||
'type' => 'secondary',
|
||||
'text' => __('Configure', 'woocommerce-paypal-payments'),
|
||||
'action' => array(
|
||||
'type' => 'tab',
|
||||
'tab' => 'settings',
|
||||
'type' => 'secondary',
|
||||
'text' => __( 'Configure', 'woocommerce-paypal-payments' ),
|
||||
'action' => array(
|
||||
'type' => 'tab',
|
||||
'tab' => 'settings',
|
||||
'section' => 'ppcp--save-payment-methods',
|
||||
),
|
||||
'showWhen' => 'enabled',
|
||||
'class' => 'small-button',
|
||||
'class' => 'small-button',
|
||||
),
|
||||
array(
|
||||
'type' => 'secondary',
|
||||
'text' => __('Sign up', 'woocommerce-paypal-payments'),
|
||||
'urls' => array(
|
||||
'type' => 'secondary',
|
||||
'text' => __( 'Sign up', 'woocommerce-paypal-payments' ),
|
||||
'urls' => array(
|
||||
'sandbox' => 'https://www.sandbox.paypal.com/bizsignup/entry?product=ADVANCED_VAULTING',
|
||||
'live' => 'https://www.paypal.com/bizsignup/entry?product=ADVANCED_VAULTING',
|
||||
'live' => 'https://www.paypal.com/bizsignup/entry?product=ADVANCED_VAULTING',
|
||||
),
|
||||
'showWhen' => 'disabled',
|
||||
'class' => 'small-button',
|
||||
'class' => 'small-button',
|
||||
),
|
||||
array(
|
||||
'type' => 'tertiary',
|
||||
'text' => __('Learn more', 'woocommerce-paypal-payments'),
|
||||
'url' => 'https://www.paypal.com/us/enterprise/payment-processing/accept-venmo',
|
||||
'type' => 'tertiary',
|
||||
'text' => __( 'Learn more', 'woocommerce-paypal-payments' ),
|
||||
'url' => 'https://www.paypal.com/us/enterprise/payment-processing/accept-venmo',
|
||||
'class' => 'small-button',
|
||||
),
|
||||
),
|
||||
),
|
||||
'advanced_credit_and_debit_cards' => array(
|
||||
'title' => __('Advanced Credit and Debit Cards', 'woocommerce-paypal-payments'),
|
||||
'description' => __('Process major credit and debit cards including Visa, Mastercard, American Express and Discover.', 'woocommerce-paypal-payments'),
|
||||
'isEligible' => $eligibility_checks['advanced_credit_and_debit_cards'],
|
||||
'buttons' => array(
|
||||
'title' => __( 'Advanced Credit and Debit Cards', 'woocommerce-paypal-payments' ),
|
||||
'description' => __( 'Process major credit and debit cards including Visa, Mastercard, American Express and Discover.', 'woocommerce-paypal-payments' ),
|
||||
'isEligible' => $eligibility_checks['advanced_credit_and_debit_cards'],
|
||||
'buttons' => array(
|
||||
array(
|
||||
'type' => 'secondary',
|
||||
'text' => __('Configure', 'woocommerce-paypal-payments'),
|
||||
'action' => array(
|
||||
'type' => 'tab',
|
||||
'tab' => 'payment_methods',
|
||||
'type' => 'secondary',
|
||||
'text' => __( 'Configure', 'woocommerce-paypal-payments' ),
|
||||
'action' => array(
|
||||
'type' => 'tab',
|
||||
'tab' => 'payment_methods',
|
||||
'section' => 'ppcp-card-payments-card',
|
||||
'modal' => 'ppcp-credit-card-gateway',
|
||||
'modal' => 'ppcp-credit-card-gateway',
|
||||
),
|
||||
'showWhen' => 'enabled',
|
||||
'class' => 'small-button',
|
||||
'class' => 'small-button',
|
||||
),
|
||||
array(
|
||||
'type' => 'secondary',
|
||||
'text' => __('Sign up', 'woocommerce-paypal-payments'),
|
||||
'urls' => array(
|
||||
'type' => 'secondary',
|
||||
'text' => __( 'Sign up', 'woocommerce-paypal-payments' ),
|
||||
'urls' => array(
|
||||
'sandbox' => 'https://www.sandbox.paypal.com/bizsignup/entry?product=ppcp',
|
||||
'live' => 'https://www.paypal.com/bizsignup/entry?product=ppcp',
|
||||
'live' => 'https://www.paypal.com/bizsignup/entry?product=ppcp',
|
||||
),
|
||||
'showWhen' => 'disabled',
|
||||
'class' => 'small-button',
|
||||
'class' => 'small-button',
|
||||
),
|
||||
array(
|
||||
'type' => 'tertiary',
|
||||
'text' => __('Learn more', 'woocommerce-paypal-payments'),
|
||||
'url' => 'https://developer.paypal.com/studio/checkout/advanced',
|
||||
'type' => 'tertiary',
|
||||
'text' => __( 'Learn more', 'woocommerce-paypal-payments' ),
|
||||
'url' => 'https://developer.paypal.com/studio/checkout/advanced',
|
||||
'class' => 'small-button',
|
||||
),
|
||||
),
|
||||
),
|
||||
'alternative_payment_methods' => array(
|
||||
'title' => __('Alternative Payment Methods', 'woocommerce-paypal-payments'),
|
||||
'description' => __('Offer global, country-specific payment options for your customers.', 'woocommerce-paypal-payments'),
|
||||
'isEligible' => $eligibility_checks['alternative_payment_methods'],
|
||||
'buttons' => array(
|
||||
'alternative_payment_methods' => array(
|
||||
'title' => __( 'Alternative Payment Methods', 'woocommerce-paypal-payments' ),
|
||||
'description' => __( 'Offer global, country-specific payment options for your customers.', 'woocommerce-paypal-payments' ),
|
||||
'isEligible' => $eligibility_checks['alternative_payment_methods'],
|
||||
'buttons' => array(
|
||||
array(
|
||||
'type' => 'secondary',
|
||||
'text' => __('Configure', 'woocommerce-paypal-payments'),
|
||||
'action' => array(
|
||||
'type' => 'tab',
|
||||
'tab' => 'payment_methods',
|
||||
'type' => 'secondary',
|
||||
'text' => __( 'Configure', 'woocommerce-paypal-payments' ),
|
||||
'action' => array(
|
||||
'type' => 'tab',
|
||||
'tab' => 'payment_methods',
|
||||
'section' => 'ppcp-alternative-payments-card',
|
||||
),
|
||||
'showWhen' => 'enabled',
|
||||
'class' => 'small-button',
|
||||
'class' => 'small-button',
|
||||
),
|
||||
array(
|
||||
'type' => 'secondary',
|
||||
'text' => __('Sign up', 'woocommerce-paypal-payments'),
|
||||
'url' => 'https://developer.paypal.com/docs/checkout/apm/',
|
||||
'type' => 'secondary',
|
||||
'text' => __( 'Sign up', 'woocommerce-paypal-payments' ),
|
||||
'url' => 'https://developer.paypal.com/docs/checkout/apm/',
|
||||
'showWhen' => 'disabled',
|
||||
'class' => 'small-button',
|
||||
'class' => 'small-button',
|
||||
),
|
||||
array(
|
||||
'type' => 'tertiary',
|
||||
'text' => __('Learn more', 'woocommerce-paypal-payments'),
|
||||
'url' => 'https://developer.paypal.com/docs/checkout/apm/',
|
||||
'type' => 'tertiary',
|
||||
'text' => __( 'Learn more', 'woocommerce-paypal-payments' ),
|
||||
'url' => 'https://developer.paypal.com/docs/checkout/apm/',
|
||||
'class' => 'small-button',
|
||||
),
|
||||
),
|
||||
),
|
||||
'google_pay' => array(
|
||||
'title' => __('Google Pay', 'woocommerce-paypal-payments'),
|
||||
'description' => __('Let customers pay using their Google Pay wallet.', 'woocommerce-paypal-payments'),
|
||||
'isEligible' => $eligibility_checks['google_pay'],
|
||||
'buttons' => array(
|
||||
'google_pay' => array(
|
||||
'title' => __( 'Google Pay', 'woocommerce-paypal-payments' ),
|
||||
'description' => __( 'Let customers pay using their Google Pay wallet.', 'woocommerce-paypal-payments' ),
|
||||
'isEligible' => $eligibility_checks['google_pay'],
|
||||
'buttons' => array(
|
||||
array(
|
||||
'type' => 'secondary',
|
||||
'text' => __('Configure', 'woocommerce-paypal-payments'),
|
||||
'action' => array(
|
||||
'type' => 'tab',
|
||||
'tab' => 'payment_methods',
|
||||
'type' => 'secondary',
|
||||
'text' => __( 'Configure', 'woocommerce-paypal-payments' ),
|
||||
'action' => array(
|
||||
'type' => 'tab',
|
||||
'tab' => 'payment_methods',
|
||||
'section' => 'ppcp-card-payments-card',
|
||||
'modal' => 'ppcp-googlepay',
|
||||
'modal' => 'ppcp-googlepay',
|
||||
),
|
||||
'showWhen' => 'enabled',
|
||||
'class' => 'small-button',
|
||||
'class' => 'small-button',
|
||||
),
|
||||
array(
|
||||
'type' => 'secondary',
|
||||
'text' => __('Sign up', 'woocommerce-paypal-payments'),
|
||||
'urls' => array(
|
||||
'type' => 'secondary',
|
||||
'text' => __( 'Sign up', 'woocommerce-paypal-payments' ),
|
||||
'urls' => array(
|
||||
'sandbox' => 'https://www.sandbox.paypal.com/bizsignup/add-product?product=payment_methods&capabilities=GOOGLE_PAY',
|
||||
'live' => 'https://www.paypal.com/bizsignup/add-product?product=payment_methods&capabilities=GOOGLE_PAY',
|
||||
'live' => 'https://www.paypal.com/bizsignup/add-product?product=payment_methods&capabilities=GOOGLE_PAY',
|
||||
),
|
||||
'showWhen' => 'disabled',
|
||||
'class' => 'small-button',
|
||||
'class' => 'small-button',
|
||||
),
|
||||
array(
|
||||
'type' => 'tertiary',
|
||||
'text' => __('Learn more', 'woocommerce-paypal-payments'),
|
||||
'url' => 'https://developer.paypal.com/docs/checkout/apm/google-pay/',
|
||||
'type' => 'tertiary',
|
||||
'text' => __( 'Learn more', 'woocommerce-paypal-payments' ),
|
||||
'url' => 'https://developer.paypal.com/docs/checkout/apm/google-pay/',
|
||||
'class' => 'small-button',
|
||||
),
|
||||
),
|
||||
'notes' => array(
|
||||
__('¹PayPal Q2 Earnings-2021.', 'woocommerce-paypal-payments'),
|
||||
'notes' => array(
|
||||
__( '¹PayPal Q2 Earnings-2021.', 'woocommerce-paypal-payments' ),
|
||||
),
|
||||
),
|
||||
'apple_pay' => array(
|
||||
'title' => __('Apple Pay', 'woocommerce-paypal-payments'),
|
||||
'description' => __('Let customers pay using their Apple Pay wallet.', 'woocommerce-paypal-payments'),
|
||||
'isEligible' => $eligibility_checks['apple_pay'],
|
||||
'buttons' => array(
|
||||
'apple_pay' => array(
|
||||
'title' => __( 'Apple Pay', 'woocommerce-paypal-payments' ),
|
||||
'description' => __( 'Let customers pay using their Apple Pay wallet.', 'woocommerce-paypal-payments' ),
|
||||
'isEligible' => $eligibility_checks['apple_pay'],
|
||||
'buttons' => array(
|
||||
array(
|
||||
'type' => 'secondary',
|
||||
'text' => __('Configure', 'woocommerce-paypal-payments'),
|
||||
'action' => array(
|
||||
'type' => 'tab',
|
||||
'tab' => 'payment_methods',
|
||||
'type' => 'secondary',
|
||||
'text' => __( 'Configure', 'woocommerce-paypal-payments' ),
|
||||
'action' => array(
|
||||
'type' => 'tab',
|
||||
'tab' => 'payment_methods',
|
||||
'section' => 'ppcp-card-payments-card',
|
||||
'modal' => 'ppcp-applepay',
|
||||
'modal' => 'ppcp-applepay',
|
||||
),
|
||||
'showWhen' => 'enabled',
|
||||
'class' => 'small-button',
|
||||
'class' => 'small-button',
|
||||
),
|
||||
array(
|
||||
'type' => 'secondary',
|
||||
'text' => __('Domain registration', 'woocommerce-paypal-payments'),
|
||||
'urls' => array(
|
||||
'type' => 'secondary',
|
||||
'text' => __( 'Domain registration', 'woocommerce-paypal-payments' ),
|
||||
'urls' => array(
|
||||
'sandbox' => 'https://www.sandbox.paypal.com/uccservicing/apm/applepay',
|
||||
'live' => 'https://www.paypal.com/uccservicing/apm/applepay',
|
||||
'live' => 'https://www.paypal.com/uccservicing/apm/applepay',
|
||||
),
|
||||
'showWhen' => 'enabled',
|
||||
'class' => 'small-button',
|
||||
'class' => 'small-button',
|
||||
),
|
||||
array(
|
||||
'type' => 'secondary',
|
||||
'text' => __('Sign up', 'woocommerce-paypal-payments'),
|
||||
'urls' => array(
|
||||
'type' => 'secondary',
|
||||
'text' => __( 'Sign up', 'woocommerce-paypal-payments' ),
|
||||
'urls' => array(
|
||||
'sandbox' => 'https://www.sandbox.paypal.com/bizsignup/add-product?product=payment_methods&capabilities=APPLE_PAY',
|
||||
'live' => 'https://www.paypal.com/bizsignup/add-product?product=payment_methods&capabilities=APPLE_PAY',
|
||||
'live' => 'https://www.paypal.com/bizsignup/add-product?product=payment_methods&capabilities=APPLE_PAY',
|
||||
),
|
||||
'showWhen' => 'disabled',
|
||||
'class' => 'small-button',
|
||||
'class' => 'small-button',
|
||||
),
|
||||
array(
|
||||
'type' => 'tertiary',
|
||||
'text' => __('Learn more', 'woocommerce-paypal-payments'),
|
||||
'url' => 'https://developer.paypal.com/docs/checkout/apm/apple-pay/',
|
||||
'type' => 'tertiary',
|
||||
'text' => __( 'Learn more', 'woocommerce-paypal-payments' ),
|
||||
'url' => 'https://developer.paypal.com/docs/checkout/apm/apple-pay/',
|
||||
'class' => 'small-button',
|
||||
),
|
||||
),
|
||||
),
|
||||
'pay_later' => array(
|
||||
'title' => __('Pay Later Messaging', 'woocommerce-paypal-payments'),
|
||||
'pay_later' => array(
|
||||
'title' => __( 'Pay Later Messaging', 'woocommerce-paypal-payments' ),
|
||||
'description' => __(
|
||||
'Let customers know they can buy now and pay later with PayPal. Adding this messaging can boost conversion rates and increase cart sizes by 39%¹, with no extra cost to you—plus, you get paid up front.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
'isEligible' => $eligibility_checks['pay_later'],
|
||||
'buttons' => array(
|
||||
'isEligible' => $eligibility_checks['pay_later'],
|
||||
'buttons' => array(
|
||||
array(
|
||||
'type' => 'secondary',
|
||||
'text' => __('Configure', 'woocommerce-paypal-payments'),
|
||||
'action' => array(
|
||||
'type' => 'secondary',
|
||||
'text' => __( 'Configure', 'woocommerce-paypal-payments' ),
|
||||
'action' => array(
|
||||
'type' => 'tab',
|
||||
'tab' => 'pay_later_messaging',
|
||||
),
|
||||
'showWhen' => 'enabled',
|
||||
'class' => 'small-button',
|
||||
'class' => 'small-button',
|
||||
),
|
||||
array(
|
||||
'type' => 'tertiary',
|
||||
'text' => __('Learn more', 'woocommerce-paypal-payments'),
|
||||
'url' => "https://www.paypal.com/$countryLocation/business/accept-payments/checkout/installments",
|
||||
'type' => 'tertiary',
|
||||
'text' => __( 'Learn more', 'woocommerce-paypal-payments' ),
|
||||
'url' => "https://www.paypal.com/{$country_location}/business/accept-payments/checkout/installments",
|
||||
'class' => 'small-button',
|
||||
),
|
||||
),
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
<?php
|
||||
/**
|
||||
* REST endpoint to manage the features items.
|
||||
* REST endpoint to manage features.
|
||||
*
|
||||
* Provides endpoints for retrieving features
|
||||
* via WP REST API routes.
|
||||
* Provides endpoints for retrieving features via WP REST API routes.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\Settings\Endpoint
|
||||
*/
|
||||
|
@ -17,7 +16,7 @@ use WP_REST_Response;
|
|||
use WooCommerce\PayPalCommerce\Settings\Data\Definition\FeaturesDefinition;
|
||||
|
||||
/**
|
||||
* REST controller for the features items in the Overview tab.
|
||||
* REST controller for the features in the Overview tab.
|
||||
*
|
||||
* This API acts as the intermediary between the "external world" and our
|
||||
* internal data model. It's responsible for checking eligibility and
|
||||
|
@ -48,8 +47,8 @@ class FeaturesRestEndpoint extends RestEndpoint {
|
|||
/**
|
||||
* FeaturesRestEndpoint constructor.
|
||||
*
|
||||
* @param FeaturesDefinition $features_definition The features definition instance.
|
||||
* @param SettingsRestEndpoint $settings The settings endpoint instance.
|
||||
* @param FeaturesDefinition $features_definition The features definition instance.
|
||||
* @param SettingsRestEndpoint $settings The settings endpoint instance.
|
||||
*/
|
||||
public function __construct(
|
||||
FeaturesDefinition $features_definition,
|
||||
|
@ -83,16 +82,21 @@ class FeaturesRestEndpoint extends RestEndpoint {
|
|||
* @return WP_REST_Response The response containing features data.
|
||||
*/
|
||||
public function get_features(): WP_REST_Response {
|
||||
|
||||
$features = array();
|
||||
foreach ( $this->features_definition->get() as $id => $feature ) {
|
||||
// Check eligibility and add to features if eligible.
|
||||
if ( $feature['isEligible']() ) {
|
||||
$features[] = array_merge(
|
||||
array( 'id' => $id ),
|
||||
array_diff_key( $feature, array( 'isEligible' => true ) )
|
||||
);
|
||||
// Evaluate eligibility check.
|
||||
if ( is_callable( $feature['isEligible'] ) ) {
|
||||
$is_eligible = $feature['isEligible']();
|
||||
} else {
|
||||
$is_eligible = (bool) $feature['isEligible'];
|
||||
}
|
||||
|
||||
// Include all features with their eligibility state.
|
||||
$features[] = array_merge(
|
||||
array( 'id' => $id ),
|
||||
array_diff_key( $feature, array( 'isEligible' => true ) ),
|
||||
array( 'isEligible' => $is_eligible )
|
||||
);
|
||||
}
|
||||
|
||||
return $this->return_success(
|
||||
|
|
|
@ -77,12 +77,12 @@ class FeaturesEligibilityService {
|
|||
bool $is_apple_pay_eligible,
|
||||
bool $is_pay_later_eligible
|
||||
) {
|
||||
$this->is_save_paypal_and_venmo_eligible = $is_save_paypal_and_venmo_eligible;
|
||||
$this->is_advanced_credit_and_debit_cards_eligible = $is_advanced_credit_and_debit_cards_eligible;
|
||||
$this->is_alternative_payment_methods_eligible = $is_alternative_payment_methods_eligible;
|
||||
$this->is_google_pay_eligible = $is_google_pay_eligible;
|
||||
$this->is_apple_pay_eligible = $is_apple_pay_eligible;
|
||||
$this->is_pay_later_eligible = $is_pay_later_eligible;
|
||||
$this->is_save_paypal_and_venmo_eligible = $is_save_paypal_and_venmo_eligible;
|
||||
$this->is_advanced_credit_and_debit_cards_eligible = $is_advanced_credit_and_debit_cards_eligible;
|
||||
$this->is_alternative_payment_methods_eligible = $is_alternative_payment_methods_eligible;
|
||||
$this->is_google_pay_eligible = $is_google_pay_eligible;
|
||||
$this->is_apple_pay_eligible = $is_apple_pay_eligible;
|
||||
$this->is_pay_later_eligible = $is_pay_later_eligible;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -92,12 +92,12 @@ class FeaturesEligibilityService {
|
|||
*/
|
||||
public function get_eligibility_checks(): array {
|
||||
return array(
|
||||
'save_paypal_and_venmo' => fn() => $this->is_save_paypal_and_venmo_eligible,
|
||||
'advanced_credit_and_debit_cards' => fn() => $this->is_advanced_credit_and_debit_cards_eligible,
|
||||
'alternative_payment_methods' => fn() => $this->is_alternative_payment_methods_eligible,
|
||||
'google_pay' => fn() => $this->is_google_pay_eligible,
|
||||
'apple_pay' => fn() => $this->is_apple_pay_eligible,
|
||||
'pay_later' => fn() => $this->is_pay_later_eligible,
|
||||
'save_paypal_and_venmo' => fn() => $this->is_save_paypal_and_venmo_eligible,
|
||||
'advanced_credit_and_debit_cards' => fn() => $this->is_advanced_credit_and_debit_cards_eligible,
|
||||
'alternative_payment_methods' => fn() => $this->is_alternative_payment_methods_eligible,
|
||||
'google_pay' => fn() => $this->is_google_pay_eligible,
|
||||
'apple_pay' => fn() => $this->is_apple_pay_eligible,
|
||||
'pay_later' => fn() => $this->is_pay_later_eligible,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue