mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-07 19:54:15 +08:00
Merge branch 'trunk' of github.com:woocommerce/woocommerce-paypal-payments into PCP-3942-add-help-center-components-ver2
This commit is contained in:
commit
b7ec9747a5
52 changed files with 2269 additions and 1453 deletions
|
@ -1 +1,3 @@
|
|||
export { default as openSignup } from './Icons/open-signup';
|
||||
export const NOTIFICATION_SUCCESS = '✔️';
|
||||
export const NOTIFICATION_ERROR = '❌';
|
||||
|
|
|
@ -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' ),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -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
|
||||
__(
|
||||
|
|
|
@ -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',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -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';
|
||||
|
||||
|
|
|
@ -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',
|
||||
};
|
||||
|
|
|
@ -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 };
|
||||
};
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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,
|
||||
} );
|
||||
},
|
||||
};
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -36,6 +36,7 @@ const defaultPersistent = Object.freeze( {
|
|||
useManualConnection: false,
|
||||
clientId: '',
|
||||
clientSecret: '',
|
||||
webhooks: [],
|
||||
} );
|
||||
|
||||
// Reducer logic.
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue