Merge branch 'trunk' of github.com:woocommerce/woocommerce-paypal-payments into PCP-3942-add-help-center-components-ver2

This commit is contained in:
Daniel Dudzic 2025-01-02 14:42:41 +01:00
commit b7ec9747a5
No known key found for this signature in database
GPG key ID: 31B40D33E3465483
52 changed files with 2269 additions and 1453 deletions

View file

@ -1 +1,3 @@
export { default as openSignup } from './Icons/open-signup';
export const NOTIFICATION_SUCCESS = '✔️';
export const NOTIFICATION_ERROR = '❌';

View file

@ -5,26 +5,29 @@ import { countryPriceInfo } from '../../utils/countryPriceInfo';
import { formatPrice } from '../../utils/formatPrice';
import TitleBadge, { TITLE_BADGE_INFO } from './TitleBadge';
const getFixedAmount = ( currency, priceList ) => {
if ( priceList[ currency ] ) {
return formatPrice( priceList[ currency ], currency );
const getFixedAmount = ( currency, priceList, itemFixedAmount ) => {
if ( priceList[ currency ] ) {
const sum = priceList[ currency ] + itemFixedAmount;
return formatPrice( sum, currency );
}
const [ defaultCurrency, defaultPrice ] = Object.entries( priceList )[ 0 ];
return formatPrice( defaultPrice, defaultCurrency );
const sum = defaultPrice + itemFixedAmount;
return formatPrice( sum, defaultCurrency );
};
const PricingTitleBadge = ( { item } ) => {
const { storeCountry } = CommonHooks.useWooSettings();
const { storeCountry, storeCurrency } = CommonHooks.useWooSettings();
const infos = countryPriceInfo[ storeCountry ];
const itemKey = item.split(' ')[0]; // Extract the first word, fastlane has more than one
if ( ! infos || ! infos[ item ] ) {
if ( ! infos || ! infos[ itemKey ] ) {
return null;
}
const percentage = infos[ item ].toFixed( 2 );
const fixedAmount = getFixedAmount( storeCountry, infos.fixedFee );
const percentage = typeof infos[itemKey] === 'number' ? infos[itemKey].toFixed(2) : infos[itemKey]['percentage'].toFixed(2);
const itemFixedAmount = infos[itemKey]['fixedFee'] ? infos[itemKey]['fixedFee'] : 0;
const fixedAmount = getFixedAmount( storeCurrency, infos.fixedFee, itemFixedAmount );
const label = sprintf(
__( 'from %1$s%% + %2$s', 'woocommerce-paypal-payments' ),

View file

@ -1,6 +1,6 @@
import { Button } from '@wordpress/components';
import SettingsBlock from './SettingsBlock';
import { Header, Title, Action, Description } from './SettingsBlockElements';
import { Action, Description, Header, Title } from './SettingsBlockElements';
const ButtonSettingsBlock = ( { title, description, ...props } ) => (
<SettingsBlock { ...props } className="ppcp-r-settings-block__button">
@ -10,6 +10,7 @@ const ButtonSettingsBlock = ( { title, description, ...props } ) => (
</Header>
<Action>
<Button
isBusy={ props.actionProps?.isBusy }
variant={ props.actionProps?.buttonType }
onClick={
props.actionProps?.callback

View file

@ -22,6 +22,7 @@ const FeatureSettingsBlock = ( { title, description, ...props } ) => {
const renderButton = ( button ) => {
const buttonElement = (
<Button
className={ button.class ? button.class : '' }
key={ button.text }
variant={ button.type }
onClick={ button.onClick }

View file

@ -53,6 +53,9 @@ const AcdcFlow = ( { isFastlane, isPayLater, storeCountry } ) => {
imageBadge={ [
'icon-payment-method-paypal-small.svg',
] }
textBadge={
<PricingTitleBadge item="plater" />
}
description={ sprintf(
// translators: %s: Link to PayPal business fees guide
__(

View file

@ -23,6 +23,7 @@ const Features = {
} );
},
showWhen: 'enabled',
class: 'small-button',
},
{
type: 'secondary',
@ -33,6 +34,7 @@ const Features = {
live: 'https://www.paypal.com/bizsignup/entry?product=ADVANCED_VAULTING',
},
showWhen: 'disabled',
class: 'small-button',
},
{
type: 'tertiary',
@ -41,6 +43,7 @@ const Features = {
sandbox: '#',
live: '#',
},
class: 'small-button',
},
],
},
@ -69,6 +72,7 @@ const Features = {
} );
},
showWhen: 'enabled',
class: 'small-button',
},
{
type: 'secondary',
@ -79,6 +83,7 @@ const Features = {
live: 'https://www.paypal.com/bizsignup/entry?product=ppcp',
},
showWhen: 'disabled',
class: 'small-button',
},
{
type: 'tertiary',
@ -87,6 +92,7 @@ const Features = {
sandbox: '#',
live: '#',
},
class: 'small-button',
},
],
},
@ -111,6 +117,7 @@ const Features = {
);
},
showWhen: 'enabled',
class: 'small-button',
},
{
type: 'secondary',
@ -120,6 +127,7 @@ const Features = {
live: '#',
},
showWhen: 'disabled',
class: 'small-button',
},
{
type: 'tertiary',
@ -128,6 +136,7 @@ const Features = {
sandbox: '#',
live: '#',
},
class: 'small-button',
},
],
},
@ -151,6 +160,7 @@ const Features = {
} );
},
showWhen: 'enabled',
class: 'small-button',
},
{
type: 'secondary',
@ -161,6 +171,7 @@ const Features = {
live: 'https://www.paypal.com/bizsignup/add-product?product=payment_methods&capabilities=GOOGLE_PAY',
},
showWhen: 'disabled',
class: 'small-button',
},
{
type: 'tertiary',
@ -169,6 +180,7 @@ const Features = {
sandbox: '#',
live: '#',
},
class: 'small-button',
},
],
notes: [
@ -198,6 +210,7 @@ const Features = {
} );
},
showWhen: 'enabled',
class: 'small-button',
},
{
type: 'secondary',
@ -211,6 +224,7 @@ const Features = {
live: 'https://www.paypal.com/uccservicing/apm/applepay',
},
showWhen: 'enabled',
class: 'small-button',
},
{
type: 'secondary',
@ -221,6 +235,7 @@ const Features = {
live: 'https://www.paypal.com/bizsignup/add-product?product=payment_methods&capabilities=APPLE_PAY',
},
showWhen: 'disabled',
class: 'small-button',
},
{
type: 'tertiary',
@ -229,6 +244,7 @@ const Features = {
sandbox: '#',
live: '#',
},
class: 'small-button',
},
],
},
@ -252,6 +268,7 @@ const Features = {
} );
},
showWhen: 'enabled',
class: 'small-button',
},
{
type: 'secondary',
@ -261,6 +278,7 @@ const Features = {
live: '#',
},
showWhen: 'disabled',
class: 'small-button',
},
{
type: 'tertiary',
@ -269,6 +287,7 @@ const Features = {
sandbox: '#',
live: '#',
},
class: 'small-button',
},
],
},

View file

@ -1,168 +0,0 @@
import { __ } from '@wordpress/i18n';
import {
Header,
Title,
Description,
AccordionSettingsBlock,
ToggleSettingsBlock,
ButtonSettingsBlock,
} from '../../../../ReusableComponents/SettingsBlocks';
import SettingsBlock from '../../../../ReusableComponents/SettingsBlocks/SettingsBlock';
const Troubleshooting = ( { updateFormValue, settings } ) => {
return (
<AccordionSettingsBlock
className="ppcp-r-settings-block--troubleshooting"
title={ __( 'Troubleshooting', 'woocommerce-paypal-payments' ) }
description={ __(
'Access tools to help debug and resolve issues.',
'woocommerce-paypal-payments'
) }
actionProps={ {
callback: updateFormValue,
key: 'payNowExperience',
value: settings.payNowExperience,
} }
>
<ToggleSettingsBlock
title={ __( 'Logging', 'woocommerce-paypal-payments' ) }
description={ __(
'Log additional debugging information in the WooCommerce logs that can assist technical staff to determine issues.',
'woocommerce-paypal-payments'
) }
actionProps={ {
callback: updateFormValue,
key: 'logging',
value: settings.logging,
} }
/>
<SettingsBlock>
<Header>
<Title>
{ __(
'Subscribed PayPal webhooks',
'woocommerce-paypal-payments'
) }
</Title>
<Description>
{ __(
'The following PayPal webhooks are subscribed. More information about the webhooks is available in the',
'woocommerce-paypal-payments'
) }{ ' ' }
<a href="https://woocommerce.com/document/woocommerce-paypal-payments/#webhook-status">
{ __(
'Webhook Status documentation',
'woocommerce-paypal-payments'
) }
</a>
.
</Description>
</Header>
<HooksTable data={ hooksExampleData() } />
</SettingsBlock>
<ButtonSettingsBlock
title={ __(
'Resubscribe webhooks',
'woocommerce-paypal-payments'
) }
description={ __(
'Click to remove the current webhook subscription and subscribe again, for example, if the website domain or URL structure changed.',
'woocommerce-paypal-payments'
) }
actionProps={ {
buttonType: 'secondary',
callback: () =>
console.log(
'Resubscribe webhooks',
'woocommerce-paypal-payments'
),
value: __(
'Resubscribe webhooks',
'woocommerce-paypal-payments'
),
} }
/>
<ButtonSettingsBlock
title={ __(
'Simulate webhooks',
'woocommerce-paypal-payments'
) }
actionProps={ {
buttonType: 'secondary',
callback: () =>
console.log(
'Simulate webhooks',
'woocommerce-paypal-payments'
),
value: __(
'Simulate webhooks',
'woocommerce-paypal-payments'
),
} }
/>
</AccordionSettingsBlock>
);
};
const hooksExampleData = () => {
return {
url: 'https://www.rt3.tech/wordpress/paypal-ux-testin/index.php?rest_route=/paypal/v1/incoming',
hooks: [
'billing plan pricing-change activated',
'billing plan updated',
'billing subscription cancelled',
'catalog product updated',
'checkout order approved',
'checkout order completed',
'checkout payment-approval reversed',
'payment authorization voided',
'payment capture completed',
'payment capture denied',
'payment capture pending',
'payment capture refunded',
'payment capture reversed',
'payment order cancelled',
'payment sale completed',
'payment sale refunded',
'vault payment-token created',
'vault payment-token deleted',
],
};
};
const HooksTable = ( { data } ) => {
return (
<table className="ppcp-r-table">
<thead>
<tr>
<th className="ppcp-r-table__hooks-url">
{ __( 'URL', 'woocommerce-paypal-payments' ) }
</th>
<th className="ppcp-r-table__hooks-events">
{ __(
'Tracked events',
'woocommerce-paypal-payments'
) }
</th>
</tr>
</thead>
<tbody>
<tr>
<td className="ppcp-r-table__hooks-url">{ data?.url }</td>
<td className="ppcp-r-table__hooks-events">
{ data.hooks.map( ( hook, index ) => (
<span key={ hook }>
{ hook }{ ' ' }
{ index !== data.hooks.length - 1 && ',' }
</span>
) ) }
</td>
</tr>
</tbody>
</table>
);
};
export default Troubleshooting;

View file

@ -0,0 +1,37 @@
import { __ } from '@wordpress/i18n';
import { CommonHooks } from '../../../../../../data';
const HooksTableBlock = () => {
const { webhooks } = CommonHooks.useWebhooks();
return (
<table className="ppcp-r-table">
<thead>
<tr>
<th className="ppcp-r-table__hooks-url">
{ __( 'URL', 'woocommerce-paypal-payments' ) }
</th>
<th className="ppcp-r-table__hooks-events">
{ __(
'Tracked events',
'woocommerce-paypal-payments'
) }
</th>
</tr>
</thead>
<tbody>
<tr>
<td className="ppcp-r-table__hooks-url">
{ webhooks?.url }
</td>
<td
className="ppcp-r-table__hooks-events"
dangerouslySetInnerHTML={ { __html: webhooks?.events } }
></td>
</tr>
</tbody>
</table>
);
};
export default HooksTableBlock;

View file

@ -0,0 +1,72 @@
import { useState } from '@wordpress/element';
import { STORE_NAME } from '../../../../../../data/common';
import { ButtonSettingsBlock } from '../../../../../ReusableComponents/SettingsBlocks';
import { __ } from '@wordpress/i18n';
import { useDispatch } from '@wordpress/data';
import { store as noticesStore } from '@wordpress/notices';
import {
NOTIFICATION_ERROR,
NOTIFICATION_SUCCESS,
} from '../../../../../ReusableComponents/Icons';
const ResubscribeBlock = () => {
const { createSuccessNotice, createErrorNotice } =
useDispatch( noticesStore );
const [ resubscribing, setResubscribing ] = useState( false );
const { resubscribeWebhooks } = useDispatch( STORE_NAME );
const startResubscribingWebhooks = async () => {
setResubscribing( true );
try {
await resubscribeWebhooks();
} catch ( error ) {
setResubscribing( false );
createErrorNotice(
__(
'Operation failed. Check WooCommerce logs for more details.',
'woocommerce-paypal-payments'
),
{
icon: NOTIFICATION_ERROR,
}
);
return;
}
setResubscribing( false );
createSuccessNotice(
__(
'Webhooks were successfully re-subscribed.',
'woocommerce-paypal-payments'
),
{
icon: NOTIFICATION_SUCCESS,
}
);
};
return (
<ButtonSettingsBlock
title={ __(
'Resubscribe webhooks',
'woocommerce-paypal-payments'
) }
description={ __(
'Click to remove the current webhook subscription and subscribe again, for example, if the website domain or URL structure changed.',
'woocommerce-paypal-payments'
) }
actionProps={ {
buttonType: 'secondary',
isBusy: resubscribing,
callback: () => startResubscribingWebhooks(),
value: __(
'Resubscribe webhooks',
'woocommerce-paypal-payments'
),
} }
/>
);
};
export default ResubscribeBlock;

View file

@ -0,0 +1,129 @@
import { useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { ButtonSettingsBlock } from '../../../../../ReusableComponents/SettingsBlocks';
import { useDispatch } from '@wordpress/data';
import { store as noticesStore } from '@wordpress/notices';
import { CommonHooks } from '../../../../../../data';
import {
NOTIFICATION_ERROR,
NOTIFICATION_SUCCESS,
} from '../../../../../ReusableComponents/Icons';
const SimulationBlock = () => {
const {
createSuccessNotice,
createInfoNotice,
createErrorNotice,
removeNotice,
} = useDispatch( noticesStore );
const { startWebhookSimulation, checkWebhookSimulationState } =
CommonHooks.useWebhooks();
const [ simulating, setSimulating ] = useState( false );
const sleep = ( ms ) => {
return new Promise( ( resolve ) => setTimeout( resolve, ms ) );
};
const startSimulation = async ( maxRetries ) => {
const webhookInfoNoticeId = 'paypal-webhook-simulation-info-notice';
const triggerWebhookInfoNotice = () => {
createInfoNotice(
__(
'Waiting for the webhook to arrive…',
'woocommerce-paypal-payments'
),
{
id: webhookInfoNoticeId,
}
);
};
const stopSimulation = () => {
removeNotice( webhookInfoNoticeId );
setSimulating( false );
};
setSimulating( true );
triggerWebhookInfoNotice();
try {
await startWebhookSimulation();
} catch ( error ) {
console.error( error );
setSimulating( false );
createErrorNotice(
__(
'Operation failed. Check WooCommerce logs for more details.',
'woocommerce-paypal-payments'
),
{
icon: NOTIFICATION_ERROR,
}
);
return;
}
for ( let i = 0; i < maxRetries; i++ ) {
await sleep( 2000 );
const simulationStateResponse = await checkWebhookSimulationState();
try {
if ( ! simulationStateResponse.success ) {
console.error(
'Simulation state query failed: ' +
simulationStateResponse?.data
);
continue;
}
if ( simulationStateResponse?.data?.state === 'received' ) {
createSuccessNotice(
__(
'The webhook was received successfully.',
'woocommerce-paypal-payments'
),
{
icon: NOTIFICATION_SUCCESS,
}
);
stopSimulation();
return;
}
removeNotice( webhookInfoNoticeId );
triggerWebhookInfoNotice();
} catch ( error ) {
console.error( error );
}
}
stopSimulation();
createErrorNotice(
__(
'Looks like the webhook cannot be received. Check that your website is accessible from the internet.',
'woocommerce-paypal-payments'
),
{
icon: NOTIFICATION_ERROR,
}
);
};
return (
<>
<ButtonSettingsBlock
title={ __(
'Simulate webhooks',
'woocommerce-paypal-payments'
) }
actionProps={ {
buttonType: 'secondary',
isBusy: simulating,
callback: () => startSimulation( 30 ),
value: __(
'Simulate webhooks',
'woocommerce-paypal-payments'
),
} }
/>
</>
);
};
export default SimulationBlock;

View file

@ -0,0 +1,72 @@
import { __ } from '@wordpress/i18n';
import {
AccordionSettingsBlock,
Description,
Header,
Title,
ToggleSettingsBlock,
} from '../../../../../ReusableComponents/SettingsBlocks';
import SettingsBlock from '../../../../../ReusableComponents/SettingsBlocks/SettingsBlock';
import SimulationBlock from './SimulationBlock';
import ResubscribeBlock from './ResubscribeBlock';
import HooksTableBlock from './HooksTableBlock';
const Troubleshooting = ( { updateFormValue, settings } ) => {
return (
<AccordionSettingsBlock
className="ppcp-r-settings-block--troubleshooting"
title={ __( 'Troubleshooting', 'woocommerce-paypal-payments' ) }
description={ __(
'Access tools to help debug and resolve issues.',
'woocommerce-paypal-payments'
) }
actionProps={ {
callback: updateFormValue,
key: 'payNowExperience',
value: settings.payNowExperience,
} }
>
<ToggleSettingsBlock
title={ __( 'Logging', 'woocommerce-paypal-payments' ) }
description={ __(
'Log additional debugging information in the WooCommerce logs that can assist technical staff to determine issues.',
'woocommerce-paypal-payments'
) }
actionProps={ {
callback: updateFormValue,
key: 'logging',
value: settings.logging,
} }
/>
<SettingsBlock>
<Header>
<Title>
{ __(
'Subscribed PayPal webhooks',
'woocommerce-paypal-payments'
) }
</Title>
<Description>
{ __(
'The following PayPal webhooks are subscribed. More information about the webhooks is available in the',
'woocommerce-paypal-payments'
) }{ ' ' }
<a href="https://woocommerce.com/document/woocommerce-paypal-payments/#webhook-status">
{ __(
'Webhook Status documentation',
'woocommerce-paypal-payments'
) }
</a>
.
</Description>
</Header>
<HooksTableBlock />
<ResubscribeBlock />
<SimulationBlock />
</SettingsBlock>
</AccordionSettingsBlock>
);
};
export default Troubleshooting;

View file

@ -5,7 +5,7 @@ import {
ContentWrapper,
} from '../../../ReusableComponents/SettingsBlocks';
import Sandbox from './Blocks/Sandbox';
import Troubleshooting from './Blocks/Troubleshooting';
import Troubleshooting from './Blocks/Troubleshooting/Troubleshooting';
import PaypalSettings from './Blocks/PaypalSettings';
import OtherSettings from './Blocks/OtherSettings';

View file

@ -24,4 +24,8 @@ export default {
DO_PRODUCTION_LOGIN: 'COMMON:DO_PRODUCTION_LOGIN',
DO_REFRESH_MERCHANT: 'COMMON:DO_REFRESH_MERCHANT',
DO_REFRESH_FEATURES: 'DO_REFRESH_FEATURES',
DO_RESUBSCRIBE_WEBHOOKS: 'COMMON:DO_RESUBSCRIBE_WEBHOOKS',
DO_START_WEBHOOK_SIMULATION: 'COMMON:DO_START_WEBHOOK_SIMULATION',
DO_CHECK_WEBHOOK_SIMULATION_STATE:
'COMMON:DO_CHECK_WEBHOOK_SIMULATION_STATE',
};

View file

@ -7,7 +7,7 @@
* @file
*/
import { dispatch, select } from '@wordpress/data';
import { select } from '@wordpress/data';
import ACTION_TYPES from './action-types';
import { STORE_NAME } from './constants';
@ -225,3 +225,48 @@ export const refreshFeatureStatuses = function* () {
return result;
};
/**
* Persistent. Changes the "webhooks" value.
*
* @param {string} webhooks
* @return {Action} The action.
*/
export const setWebhooks = ( webhooks ) => ( {
type: ACTION_TYPES.SET_PERSISTENT,
payload: { webhooks },
} );
/**
* Side effect
* Refreshes subscribed webhooks via a REST request
*
* @return {Action} The action.
*/
export const resubscribeWebhooks = function* () {
const result = yield { type: ACTION_TYPES.DO_RESUBSCRIBE_WEBHOOKS };
if ( result && result.success ) {
yield hydrate( result );
}
return result;
};
/**
* Side effect. Starts webhook simulation.
*
* @return {Action} The action.
*/
export const startWebhookSimulation = function* () {
return yield { type: ACTION_TYPES.DO_START_WEBHOOK_SIMULATION };
};
/**
* Side effect. Checks webhook simulation.
*
* @return {Action} The action.
*/
export const checkWebhookSimulationState = function* () {
return yield { type: ACTION_TYPES.DO_CHECK_WEBHOOK_SIMULATION_STATE };
};

View file

@ -54,6 +54,26 @@ export const REST_MANUAL_CONNECTION_PATH = '/wc/v3/wc_paypal/connect_manual';
*/
export const REST_CONNECTION_URL_PATH = '/wc/v3/wc_paypal/login_link';
/**
* REST path to fetch webhooks data or resubscribe webhooks,
*
* Used by: Controls
* See: WebhookSettingsEndpoint.php
*
* @type {string}
*/
export const REST_WEBHOOKS = '/wc/v3/wc_paypal/webhook_settings';
/**
* REST path to start webhook simulation and observe the state,
*
* Used by: Controls
* See: WebhookSettingsEndpoint.php
*
* @type {string}
*/
export const REST_WEBHOOKS_SIMULATE = '/wc/v3/wc_paypal/webhook_simulate';
/**
* REST path to refresh the feature status.
*

View file

@ -10,11 +10,13 @@
import apiFetch from '@wordpress/api-fetch';
import {
REST_PERSIST_PATH,
REST_MANUAL_CONNECTION_PATH,
REST_CONNECTION_URL_PATH,
REST_HYDRATE_MERCHANT_PATH,
REST_MANUAL_CONNECTION_PATH,
REST_PERSIST_PATH,
REST_REFRESH_FEATURES_PATH,
REST_WEBHOOKS,
REST_WEBHOOKS_SIMULATE,
} from './constants';
import ACTION_TYPES from './action-types';
@ -115,4 +117,24 @@ export const controls = {
};
}
},
async [ ACTION_TYPES.DO_RESUBSCRIBE_WEBHOOKS ]() {
return await apiFetch( {
method: 'POST',
path: REST_WEBHOOKS,
} );
},
async [ ACTION_TYPES.DO_START_WEBHOOK_SIMULATION ]() {
return await apiFetch( {
method: 'POST',
path: REST_WEBHOOKS_SIMULATE,
} );
},
async [ ACTION_TYPES.DO_CHECK_WEBHOOK_SIMULATION_STATE ]() {
return await apiFetch( {
path: REST_WEBHOOKS_SIMULATE,
} );
},
};

View file

@ -9,7 +9,6 @@
import { useDispatch, useSelect } from '@wordpress/data';
import { useCallback } from '@wordpress/element';
import { STORE_NAME } from './constants';
const useTransient = ( key ) =>
@ -35,6 +34,8 @@ const useHooks = () => {
connectToProduction,
connectViaIdAndSecret,
setActiveModal,
startWebhookSimulation,
checkWebhookSimulationState,
} = useDispatch( STORE_NAME );
// Transient accessors.
@ -46,7 +47,7 @@ const useHooks = () => {
const clientSecret = usePersistent( 'clientSecret' );
const isSandboxMode = usePersistent( 'useSandbox' );
const isManualConnectionMode = usePersistent( 'useManualConnection' );
const webhooks = usePersistent( 'webhooks' );
const merchant = useSelect(
( select ) => select( STORE_NAME ).merchant(),
[]
@ -86,6 +87,9 @@ const useHooks = () => {
connectViaIdAndSecret,
merchant,
wooSettings,
webhooks,
startWebhookSimulation,
checkWebhookSimulationState,
};
};
@ -129,6 +133,22 @@ export const useWooSettings = () => {
return wooSettings;
};
export const useWebhooks = () => {
const {
webhooks,
setWebhooks,
registerWebhooks,
startWebhookSimulation,
checkWebhookSimulationState,
} = useHooks();
return {
webhooks,
setWebhooks,
registerWebhooks,
startWebhookSimulation,
checkWebhookSimulationState,
};
};
export const useMerchantInfo = () => {
const { merchant } = useHooks();
const { refreshMerchantData } = useDispatch( STORE_NAME );

View file

@ -36,6 +36,7 @@ const defaultPersistent = Object.freeze( {
useManualConnection: false,
clientId: '',
clientSecret: '',
webhooks: [],
} );
// Reducer logic.

View file

@ -12,7 +12,7 @@ import { dispatch } from '@wordpress/data';
import { __ } from '@wordpress/i18n';
import { apiFetch } from '@wordpress/data-controls';
import { STORE_NAME, REST_HYDRATE_PATH } from './constants';
import { STORE_NAME, REST_HYDRATE_PATH, REST_WEBHOOKS } from './constants';
export const resolvers = {
/**
@ -21,6 +21,9 @@ export const resolvers = {
*persistentData() {
try {
const result = yield apiFetch( { path: REST_HYDRATE_PATH } );
const webhooks = yield apiFetch( { path: REST_WEBHOOKS } );
result.data = { ...result.data, ...webhooks.data };
yield dispatch( STORE_NAME ).hydrate( result );
yield dispatch( STORE_NAME ).setIsReady( true );

View file

@ -33,3 +33,7 @@ export const merchant = ( state ) => {
export const wooSettings = ( state ) => {
return getState( state ).wooSettings || EMPTY_OBJ;
};
export const webhooks = ( state ) => {
return getState( state ).webhooks || EMPTY_OBJ;
};

View file

@ -2,81 +2,139 @@ export const countryPriceInfo = {
US: {
fixedFee: {
USD: 0.49,
GBP: 0.39,
CAD: 0.59,
AUD: 0.59,
EUR: 0.39,
},
checkout: 3.49,
ccf: 2.59,
dw: 2.59,
apm: 2.59,
fastlane: 2.59,
plater: 4.99,
ccf: {
percentage: 2.59,
fixedFee: 0.29,
},
dw: {
percentage: 2.59,
fixedFee: 0.29,
},
apm: {
percentage: 2.89,
fixedFee: 0.29,
},
fast: {
percentage: 2.59,
fixedFee: 0.29,
},
standardCardFields: 2.99,
},
UK: {
fixedFee: {
GPB: 0.3,
USD: 0.3,
CAD: 0.3,
AUD: 0.3,
EUR: 0.35,
},
checkout: 2.9,
plater: 2.9,
ccf: 1.2,
dw: 1.2,
fast: 1.2,
apm: 1.2,
standardCardFields: 1.2,
},
CA: {
fixedFee: {
CAD: 0.3,
USD: 0.3,
GBP: 0.2,
AUD: 0.3,
EUR: 0.35,
},
checkout: 2.9,
ccf: 2.7,
dw: 2.7,
fast: 2.7,
apm: 2.9,
standardCardFields: 2.9,
},
AU: {
fixedFee: {
AUD: 0.3,
USD: 0.3,
GBP: 0.2,
CAD: 0.3,
EUR: 0.35,
},
checkout: 2.6,
plater: 2.6,
ccf: 1.75,
dw: 1.75,
fast: 1.75,
apm: 2.6,
standardCardFields: 2.6,
},
FR: {
fixedFee: {
EUR: 0.35,
USD: 0.3,
GBP: 0.3,
CAD: 0.3,
AUD: 0.3,
},
checkout: 2.9,
plater: 2.9,
ccf: 1.2,
dw: 1.2,
fast: 1.2,
apm: 1.2,
standardCardFields: 1.2,
},
IT: {
fixedFee: {
EUR: 0.35,
EUR: 0.35,
USD: 0.3,
GBP: 0.3,
CAD: 0.3,
AUD: 0.3,
},
checkout: 3.4,
plater: 3.4,
ccf: 1.2,
dw: 1.2,
fast: 1.2,
apm: 1.2,
standardCardFields: 1.2,
},
DE: {
fixedFee: {
EUR: 0.39,
USD: 0.49,
GBP: 0.29,
CAD: 0.59,
AUD: 0.59,
},
checkout: 2.99,
plater: 2.99,
ccf: 2.99,
dw: 2.99,
fast: 2.99,
apm: 2.99,
standardCardFields: 2.99,
},
ES: {
fixedFee: {
EUR: 0.35,
EUR: 0.35,
USD: 0.3,
GBP: 0.3,
CAD: 0.3,
AUD: 0.3,
},
checkout: 2.9,
plater: 2.9,
ccf: 1.2,
dw: 1.2,
fast: 1.2,
apm: 1.2,
standardCardFields: 1.2,
},