mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-08-30 05:00:51 +08:00
🔀 Merge branch 'trunk'
This commit is contained in:
commit
0b55aa3fb6
42 changed files with 3573 additions and 1992 deletions
|
@ -172,6 +172,11 @@ export default class PaymentButton {
|
|||
*/
|
||||
#contextHandler;
|
||||
|
||||
/**
|
||||
* Button attributes.
|
||||
*/
|
||||
#buttonAttributes;
|
||||
|
||||
/**
|
||||
* Whether the current browser/website support the payment method.
|
||||
*
|
||||
|
@ -216,6 +221,7 @@ export default class PaymentButton {
|
|||
* @param {Object} buttonConfig - Payment button specific configuration.
|
||||
* @param {Object} ppcpConfig - Plugin wide configuration object.
|
||||
* @param {unknown} contextHandler - Handler object.
|
||||
* @param {Object} buttonAttributes - Button attributes.
|
||||
* @return {PaymentButton} The button instance.
|
||||
*/
|
||||
static createButton(
|
||||
|
@ -223,7 +229,8 @@ export default class PaymentButton {
|
|||
externalHandler,
|
||||
buttonConfig,
|
||||
ppcpConfig,
|
||||
contextHandler
|
||||
contextHandler,
|
||||
buttonAttributes
|
||||
) {
|
||||
const buttonInstances = getInstances();
|
||||
const instanceKey = `${ this.methodId }.${ context }`;
|
||||
|
@ -234,7 +241,8 @@ export default class PaymentButton {
|
|||
externalHandler,
|
||||
buttonConfig,
|
||||
ppcpConfig,
|
||||
contextHandler
|
||||
contextHandler,
|
||||
buttonAttributes
|
||||
);
|
||||
|
||||
buttonInstances.set( instanceKey, button );
|
||||
|
@ -283,13 +291,15 @@ export default class PaymentButton {
|
|||
* @param {Object} buttonConfig - Payment button specific configuration.
|
||||
* @param {Object} ppcpConfig - Plugin wide configuration object.
|
||||
* @param {Object} contextHandler - Handler object.
|
||||
* @param {Object} buttonAttributes - Button attributes.
|
||||
*/
|
||||
constructor(
|
||||
context,
|
||||
externalHandler = null,
|
||||
buttonConfig = {},
|
||||
ppcpConfig = {},
|
||||
contextHandler = null
|
||||
contextHandler = null,
|
||||
buttonAttributes = {}
|
||||
) {
|
||||
if ( this.methodId === PaymentButton.methodId ) {
|
||||
throw new Error( 'Cannot initialize the PaymentButton base class' );
|
||||
|
@ -307,6 +317,7 @@ export default class PaymentButton {
|
|||
this.#ppcpConfig = ppcpConfig;
|
||||
this.#externalHandler = externalHandler;
|
||||
this.#contextHandler = contextHandler;
|
||||
this.#buttonAttributes = buttonAttributes;
|
||||
|
||||
this.#logger = new ConsoleLogger( methodName, context );
|
||||
|
||||
|
@ -921,13 +932,18 @@ export default class PaymentButton {
|
|||
|
||||
const styleSelector = `style[data-hide-gateway="${ this.methodId }"]`;
|
||||
const wrapperSelector = `#${ this.wrappers.Default }`;
|
||||
const paymentMethodLi = document.querySelector(`.wc_payment_method.payment_method_${ this.methodId }`);
|
||||
const paymentMethodLi = document.querySelector(
|
||||
`.wc_payment_method.payment_method_${ this.methodId }`
|
||||
);
|
||||
|
||||
document
|
||||
.querySelectorAll( styleSelector )
|
||||
.forEach( ( el ) => el.remove() );
|
||||
|
||||
if (paymentMethodLi.style.display === 'none' || paymentMethodLi.style.display === '') {
|
||||
if (
|
||||
paymentMethodLi.style.display === 'none' ||
|
||||
paymentMethodLi.style.display === ''
|
||||
) {
|
||||
paymentMethodLi.style.display = 'block';
|
||||
}
|
||||
|
||||
|
@ -1007,7 +1023,7 @@ export default class PaymentButton {
|
|||
this.removeButton();
|
||||
}
|
||||
|
||||
this.log( 'addButton', button );
|
||||
this.log( 'insertButton', button );
|
||||
|
||||
this.#button = button;
|
||||
wrapper.appendChild( this.#button );
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/* Front end display */
|
||||
.ppcp-button-apm .gpay-card-info-container-fill .gpay-card-info-container {
|
||||
outline-offset: -1px;
|
||||
border-radius: var(--apm-button-border-radius);
|
||||
}
|
||||
|
||||
/* Admin preview */
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
import { useState, useEffect } from '@wordpress/element';
|
||||
import { useState } from '@wordpress/element';
|
||||
import useGooglepayApiToGenerateButton from '../hooks/useGooglepayApiToGenerateButton';
|
||||
import usePayPalScript from '../hooks/usePayPalScript';
|
||||
import useGooglepayScript from '../hooks/useGooglepayScript';
|
||||
import useGooglepayConfig from '../hooks/useGooglepayConfig';
|
||||
|
||||
const GooglepayButton = ( { namespace, buttonConfig, ppcpConfig } ) => {
|
||||
const [ buttonHtml, setButtonHtml ] = useState( '' );
|
||||
const [ buttonElement, setButtonElement ] = useState( null );
|
||||
const GooglepayButton = ( {
|
||||
namespace,
|
||||
buttonConfig,
|
||||
ppcpConfig,
|
||||
buttonAttributes,
|
||||
} ) => {
|
||||
const [ componentFrame, setComponentFrame ] = useState( null );
|
||||
const isPayPalLoaded = usePayPalScript( namespace, ppcpConfig );
|
||||
|
||||
|
@ -18,35 +21,45 @@ const GooglepayButton = ( { namespace, buttonConfig, ppcpConfig } ) => {
|
|||
|
||||
const googlepayConfig = useGooglepayConfig( namespace, isGooglepayLoaded );
|
||||
|
||||
useEffect( () => {
|
||||
if ( ! buttonElement ) {
|
||||
return;
|
||||
}
|
||||
|
||||
setComponentFrame( buttonElement.ownerDocument );
|
||||
}, [ buttonElement ] );
|
||||
|
||||
const googlepayButton = useGooglepayApiToGenerateButton(
|
||||
const { button, containerStyles } = useGooglepayApiToGenerateButton(
|
||||
componentFrame,
|
||||
namespace,
|
||||
buttonConfig,
|
||||
ppcpConfig,
|
||||
googlepayConfig
|
||||
googlepayConfig,
|
||||
buttonAttributes
|
||||
);
|
||||
|
||||
useEffect( () => {
|
||||
if ( googlepayButton ) {
|
||||
const hideLoader =
|
||||
'<style>.block-editor-iframe__html .gpay-card-info-animated-progress-bar-container {display:none !important}</style>';
|
||||
setButtonHtml( googlepayButton.outerHTML + hideLoader );
|
||||
}
|
||||
}, [ googlepayButton ] );
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
ref={ setButtonElement }
|
||||
dangerouslySetInnerHTML={ { __html: buttonHtml } }
|
||||
id="express-payment-method-ppcp-googlepay"
|
||||
style={ containerStyles }
|
||||
ref={ ( node ) => {
|
||||
if ( ! node ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set component frame
|
||||
setComponentFrame( node.ownerDocument );
|
||||
|
||||
// Handle button mounting
|
||||
while ( node.firstChild ) {
|
||||
node.removeChild( node.firstChild );
|
||||
}
|
||||
if ( button ) {
|
||||
node.appendChild( button );
|
||||
}
|
||||
} }
|
||||
/>
|
||||
{ button && (
|
||||
<style>
|
||||
{ `.block-editor-iframe__html .gpay-card-info-animated-progress-bar-container {
|
||||
display: none !important
|
||||
}` }
|
||||
</style>
|
||||
) }
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,19 +1,26 @@
|
|||
import { useMemo } from '@wordpress/element';
|
||||
import { combineStyles } from '../../../../../ppcp-button/resources/js/modules/Helper/PaymentButtonHelpers';
|
||||
|
||||
const useButtonStyles = ( buttonConfig, ppcpConfig ) => {
|
||||
const useButtonStyles = ( buttonConfig, ppcpConfig, buttonAttributes ) => {
|
||||
return useMemo( () => {
|
||||
const styles = combineStyles(
|
||||
ppcpConfig?.button || {},
|
||||
buttonConfig?.button || {}
|
||||
);
|
||||
|
||||
if ( styles.MiniCart && styles.MiniCart.type === 'buy' ) {
|
||||
if ( buttonAttributes && styles.Default ) {
|
||||
styles.Default.height =
|
||||
buttonAttributes.height || styles.Default.height;
|
||||
styles.Default.borderRadius =
|
||||
buttonAttributes.borderRadius || styles.Default.borderRadius;
|
||||
}
|
||||
|
||||
if ( styles.MiniCart?.type === 'buy' ) {
|
||||
styles.MiniCart.type = 'pay';
|
||||
}
|
||||
|
||||
return styles;
|
||||
}, [ buttonConfig, ppcpConfig ] );
|
||||
}, [ buttonConfig, ppcpConfig, buttonAttributes ] );
|
||||
};
|
||||
|
||||
export default useButtonStyles;
|
||||
|
|
|
@ -6,10 +6,16 @@ const useGooglepayApiToGenerateButton = (
|
|||
namespace,
|
||||
buttonConfig,
|
||||
ppcpConfig,
|
||||
googlepayConfig
|
||||
googlepayConfig,
|
||||
buttonAttributes
|
||||
) => {
|
||||
const [ googlepayButton, setGooglepayButton ] = useState( null );
|
||||
const buttonStyles = useButtonStyles( buttonConfig, ppcpConfig );
|
||||
|
||||
const buttonStyles = useButtonStyles(
|
||||
buttonConfig,
|
||||
ppcpConfig,
|
||||
buttonAttributes
|
||||
);
|
||||
|
||||
useEffect( () => {
|
||||
if (
|
||||
|
@ -35,14 +41,13 @@ const useGooglepayApiToGenerateButton = (
|
|||
buttonType: buttonConfig.buttonType || 'pay',
|
||||
buttonLocale: buttonConfig.buttonLocale || 'en',
|
||||
buttonSizeMode: 'fill',
|
||||
};
|
||||
|
||||
const button = paymentsClient.createButton( {
|
||||
...googlePayButtonOptions,
|
||||
buttonRadius: parseInt( buttonStyles?.Default?.borderRadius ),
|
||||
onClick: ( event ) => {
|
||||
event.preventDefault();
|
||||
},
|
||||
} );
|
||||
};
|
||||
|
||||
const button = paymentsClient.createButton( googlePayButtonOptions );
|
||||
|
||||
setGooglepayButton( button );
|
||||
|
||||
|
@ -51,7 +56,15 @@ const useGooglepayApiToGenerateButton = (
|
|||
};
|
||||
}, [ namespace, buttonConfig, ppcpConfig, googlepayConfig, buttonStyles ] );
|
||||
|
||||
return googlepayButton;
|
||||
// Return both the button and the styles needed for the container
|
||||
return {
|
||||
button: googlepayButton,
|
||||
containerStyles: {
|
||||
height: buttonStyles?.Default?.height
|
||||
? `${ buttonStyles.Default.height }px`
|
||||
: '',
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export default useGooglepayApiToGenerateButton;
|
||||
|
|
|
@ -106,8 +106,40 @@ class GooglepayButton extends PaymentButton {
|
|||
*/
|
||||
#transactionInfo = null;
|
||||
|
||||
/**
|
||||
* The currently visible payment button.
|
||||
*
|
||||
* @type {HTMLElement|null}
|
||||
*/
|
||||
#button = null;
|
||||
|
||||
/**
|
||||
* The Google Pay configuration object.
|
||||
*
|
||||
* @type {Object|null}
|
||||
*/
|
||||
googlePayConfig = null;
|
||||
|
||||
/**
|
||||
* The start time of the configuration process.
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
#configureStartTime = 0;
|
||||
|
||||
/**
|
||||
* The maximum time to wait for buttonAttributes before proceeding with initialization.
|
||||
* @type {number}
|
||||
*/
|
||||
#maxWaitTime = 1000;
|
||||
|
||||
/**
|
||||
* The stored button attributes.
|
||||
*
|
||||
* @type {null}
|
||||
*/
|
||||
#storedButtonAttributes = null;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
|
@ -142,7 +174,8 @@ class GooglepayButton extends PaymentButton {
|
|||
externalHandler,
|
||||
buttonConfig,
|
||||
ppcpConfig,
|
||||
contextHandler
|
||||
contextHandler,
|
||||
buttonAttributes
|
||||
) {
|
||||
// Disable debug output in the browser console:
|
||||
// buttonConfig.is_debug = false;
|
||||
|
@ -152,7 +185,8 @@ class GooglepayButton extends PaymentButton {
|
|||
externalHandler,
|
||||
buttonConfig,
|
||||
ppcpConfig,
|
||||
contextHandler
|
||||
contextHandler,
|
||||
buttonAttributes
|
||||
);
|
||||
|
||||
this.init = this.init.bind( this );
|
||||
|
@ -240,6 +274,22 @@ class GooglepayButton extends PaymentButton {
|
|||
() => ! this.contextHandler?.validateContext(),
|
||||
`Invalid context handler.`
|
||||
);
|
||||
|
||||
invalidIf(
|
||||
() =>
|
||||
this.buttonAttributes?.height &&
|
||||
isNaN( parseInt( this.buttonAttributes.height ) ),
|
||||
'Invalid height in buttonAttributes'
|
||||
);
|
||||
|
||||
invalidIf(
|
||||
() =>
|
||||
this.buttonAttributes?.borderRadius &&
|
||||
isNaN( parseInt( this.buttonAttributes.borderRadius ) ),
|
||||
'Invalid borderRadius in buttonAttributes'
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -247,22 +297,72 @@ class GooglepayButton extends PaymentButton {
|
|||
*
|
||||
* @param {Object} apiConfig - API configuration.
|
||||
* @param {Object} transactionInfo - Transaction details; required before "init" call.
|
||||
* @param {Object} buttonAttributes - Button attributes.
|
||||
*/
|
||||
configure( apiConfig, transactionInfo ) {
|
||||
configure( apiConfig, transactionInfo, buttonAttributes = {} ) {
|
||||
// Start timing on first configure call
|
||||
if ( ! this.#configureStartTime ) {
|
||||
this.#configureStartTime = Date.now();
|
||||
}
|
||||
|
||||
// If valid buttonAttributes, store them
|
||||
if ( buttonAttributes?.height && buttonAttributes?.borderRadius ) {
|
||||
this.#storedButtonAttributes = { ...buttonAttributes };
|
||||
}
|
||||
|
||||
// Use stored attributes if current ones are missing
|
||||
const attributes = buttonAttributes?.height
|
||||
? buttonAttributes
|
||||
: this.#storedButtonAttributes;
|
||||
|
||||
// Check if we've exceeded wait time
|
||||
const timeWaited = Date.now() - this.#configureStartTime;
|
||||
if ( timeWaited > this.#maxWaitTime ) {
|
||||
this.log(
|
||||
'GooglePay: Timeout waiting for buttonAttributes - proceeding with initialization'
|
||||
);
|
||||
this.googlePayConfig = apiConfig;
|
||||
this.#transactionInfo = transactionInfo;
|
||||
this.buttonAttributes = attributes || buttonAttributes;
|
||||
this.allowedPaymentMethods =
|
||||
this.googlePayConfig.allowedPaymentMethods;
|
||||
this.baseCardPaymentMethod = this.allowedPaymentMethods[ 0 ];
|
||||
this.init();
|
||||
return;
|
||||
}
|
||||
|
||||
// Block any initialization until we have valid buttonAttributes
|
||||
if ( ! attributes?.height || ! attributes?.borderRadius ) {
|
||||
setTimeout(
|
||||
() =>
|
||||
this.configure(
|
||||
apiConfig,
|
||||
transactionInfo,
|
||||
buttonAttributes
|
||||
),
|
||||
100
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset timer for future configure calls
|
||||
this.#configureStartTime = 0;
|
||||
|
||||
this.googlePayConfig = apiConfig;
|
||||
this.#transactionInfo = transactionInfo;
|
||||
this.buttonAttributes = attributes;
|
||||
this.allowedPaymentMethods = this.googlePayConfig.allowedPaymentMethods;
|
||||
this.baseCardPaymentMethod = this.allowedPaymentMethods[ 0 ];
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
// Use `reinit()` to force a full refresh of an initialized button.
|
||||
// Skip if already initialized
|
||||
if ( this.isInitialized ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Stop, if configuration is invalid.
|
||||
// Validate configuration
|
||||
if ( ! this.validateConfiguration() ) {
|
||||
return;
|
||||
}
|
||||
|
@ -270,16 +370,6 @@ class GooglepayButton extends PaymentButton {
|
|||
super.init();
|
||||
this.#paymentsClient = this.createPaymentsClient();
|
||||
|
||||
if ( ! this.isPresent ) {
|
||||
this.log( 'Payment wrapper not found', this.wrapperId );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! this.paymentsClient ) {
|
||||
this.log( 'Could not initialize the payments client' );
|
||||
return;
|
||||
}
|
||||
|
||||
this.paymentsClient
|
||||
.isReadyToPay(
|
||||
this.buildReadyToPayRequest(
|
||||
|
@ -357,30 +447,86 @@ class GooglepayButton extends PaymentButton {
|
|||
}
|
||||
|
||||
/**
|
||||
* Creates the payment button and calls `this.insertButton()` to make the button visible in the
|
||||
* correct wrapper.
|
||||
* Creates the payment button and calls `super.insertButton()` to make the button visible in the correct wrapper.
|
||||
*/
|
||||
addButton() {
|
||||
if ( ! this.paymentsClient ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If current buttonAttributes are missing, try to use stored ones
|
||||
if (
|
||||
! this.buttonAttributes?.height &&
|
||||
this.#storedButtonAttributes?.height
|
||||
) {
|
||||
this.buttonAttributes = { ...this.#storedButtonAttributes };
|
||||
}
|
||||
|
||||
this.removeButton();
|
||||
|
||||
const baseCardPaymentMethod = this.baseCardPaymentMethod;
|
||||
const { color, type, language } = this.style;
|
||||
|
||||
/**
|
||||
* @see https://developers.google.com/pay/api/web/reference/client#createButton
|
||||
*/
|
||||
const button = this.paymentsClient.createButton( {
|
||||
const buttonOptions = {
|
||||
buttonColor: color || 'black',
|
||||
buttonSizeMode: 'fill',
|
||||
buttonLocale: language || 'en',
|
||||
buttonType: type || 'pay',
|
||||
buttonRadius: parseInt( this.buttonAttributes?.borderRadius, 10 ),
|
||||
onClick: this.onButtonClick,
|
||||
allowedPaymentMethods: [ baseCardPaymentMethod ],
|
||||
buttonColor: color || 'black',
|
||||
buttonType: type || 'pay',
|
||||
buttonLocale: language || 'en',
|
||||
buttonSizeMode: 'fill',
|
||||
} );
|
||||
};
|
||||
|
||||
this.insertButton( button );
|
||||
const button = this.paymentsClient.createButton( buttonOptions );
|
||||
this.#button = button;
|
||||
|
||||
super.insertButton( button );
|
||||
this.applyWrapperStyles();
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies CSS classes and inline styling to the payment button wrapper.
|
||||
* Extends parent implementation to handle Google Pay specific styling.
|
||||
*/
|
||||
applyWrapperStyles() {
|
||||
super.applyWrapperStyles();
|
||||
|
||||
const wrapper = this.wrapperElement;
|
||||
if ( ! wrapper ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Try stored attributes if current ones are missing
|
||||
const attributes = this.buttonAttributes?.height
|
||||
? this.buttonAttributes
|
||||
: this.#storedButtonAttributes;
|
||||
|
||||
if ( attributes?.height ) {
|
||||
const height = parseInt( attributes.height, 10 );
|
||||
if ( ! isNaN( height ) ) {
|
||||
wrapper.style.height = `${ height }px`;
|
||||
wrapper.style.minHeight = `${ height }px`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the payment button from the DOM.
|
||||
*/
|
||||
removeButton() {
|
||||
if ( ! this.isPresent || ! this.#button ) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.log( 'removeButton' );
|
||||
|
||||
try {
|
||||
this.wrapperElement.removeChild( this.#button );
|
||||
} catch ( Exception ) {
|
||||
// Ignore this.
|
||||
}
|
||||
|
||||
this.#button = null;
|
||||
}
|
||||
|
||||
//------------------------
|
||||
|
|
|
@ -3,10 +3,11 @@ import GooglepayButton from './GooglepayButton';
|
|||
import ContextHandlerFactory from './Context/ContextHandlerFactory';
|
||||
|
||||
class GooglepayManager {
|
||||
constructor( namespace, buttonConfig, ppcpConfig ) {
|
||||
constructor( namespace, buttonConfig, ppcpConfig, buttonAttributes = {} ) {
|
||||
this.namespace = namespace;
|
||||
this.buttonConfig = buttonConfig;
|
||||
this.ppcpConfig = ppcpConfig;
|
||||
this.buttonAttributes = buttonAttributes;
|
||||
this.googlePayConfig = null;
|
||||
this.transactionInfo = null;
|
||||
this.contextHandler = null;
|
||||
|
@ -26,13 +27,18 @@ class GooglepayManager {
|
|||
bootstrap.handler,
|
||||
buttonConfig,
|
||||
ppcpConfig,
|
||||
this.contextHandler
|
||||
this.contextHandler,
|
||||
this.buttonAttributes
|
||||
);
|
||||
|
||||
this.buttons.push( button );
|
||||
|
||||
const initButton = () => {
|
||||
button.configure( this.googlePayConfig, this.transactionInfo );
|
||||
button.configure(
|
||||
this.googlePayConfig,
|
||||
this.transactionInfo,
|
||||
this.buttonAttributes
|
||||
);
|
||||
button.init();
|
||||
};
|
||||
|
||||
|
@ -70,7 +76,8 @@ class GooglepayManager {
|
|||
for ( const button of this.buttons ) {
|
||||
button.configure(
|
||||
this.googlePayConfig,
|
||||
this.transactionInfo
|
||||
this.transactionInfo,
|
||||
this.buttonAttributes
|
||||
);
|
||||
button.init();
|
||||
}
|
||||
|
|
|
@ -4,11 +4,13 @@ const GooglepayManagerBlockEditor = ( {
|
|||
namespace,
|
||||
buttonConfig,
|
||||
ppcpConfig,
|
||||
buttonAttributes,
|
||||
} ) => (
|
||||
<GooglepayButton
|
||||
namespace={ namespace }
|
||||
buttonConfig={ buttonConfig }
|
||||
ppcpConfig={ ppcpConfig }
|
||||
buttonAttributes={ buttonAttributes }
|
||||
/>
|
||||
);
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ if ( typeof window.PayPalCommerceGateway === 'undefined' ) {
|
|||
window.PayPalCommerceGateway = ppcpConfig;
|
||||
}
|
||||
|
||||
const GooglePayComponent = ( { isEditing } ) => {
|
||||
const GooglePayComponent = ( { isEditing, buttonAttributes } ) => {
|
||||
const [ paypalLoaded, setPaypalLoaded ] = useState( false );
|
||||
const [ googlePayLoaded, setGooglePayLoaded ] = useState( false );
|
||||
const [ manager, setManager ] = useState( null );
|
||||
|
@ -48,11 +48,18 @@ const GooglePayComponent = ( { isEditing } ) => {
|
|||
const newManager = new GooglepayManager(
|
||||
namespace,
|
||||
buttonConfig,
|
||||
ppcpConfig
|
||||
ppcpConfig,
|
||||
buttonAttributes
|
||||
);
|
||||
setManager( newManager );
|
||||
}
|
||||
}, [ paypalLoaded, googlePayLoaded, isEditing, manager ] );
|
||||
}, [
|
||||
paypalLoaded,
|
||||
googlePayLoaded,
|
||||
isEditing,
|
||||
manager,
|
||||
buttonAttributes,
|
||||
] );
|
||||
|
||||
if ( isEditing ) {
|
||||
return (
|
||||
|
@ -60,6 +67,7 @@ const GooglePayComponent = ( { isEditing } ) => {
|
|||
namespace={ namespace }
|
||||
buttonConfig={ buttonConfig }
|
||||
ppcpConfig={ ppcpConfig }
|
||||
buttonAttributes={ buttonAttributes }
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -89,5 +97,6 @@ registerExpressPaymentMethod( {
|
|||
canMakePayment: () => buttonData.enabled,
|
||||
supports: {
|
||||
features,
|
||||
style: [ 'height', 'borderRadius' ],
|
||||
},
|
||||
} );
|
||||
|
|
6
modules/ppcp-settings/images/icon-settings-common.svg
Normal file
6
modules/ppcp-settings/images/icon-settings-common.svg
Normal file
|
@ -0,0 +1,6 @@
|
|||
<svg width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8 10.6667C8 9.19391 9.19391 8 10.6667 8H45.3333C46.8061 8 48 9.19391 48 10.6667V45.3333C48 46.8061 46.8061 48 45.3333 48H10.6667C9.19391 48 8 46.8061 8 45.3333V10.6667Z" fill="#5BBBFC"/>
|
||||
<path d="M16 18.6667C16 17.1939 17.1939 16 18.6667 16H53.3333C54.8061 16 56 17.1939 56 18.6667V53.3333C56 54.8061 54.8061 56 53.3333 56H18.6667C17.1939 56 16 54.8061 16 53.3333V18.6667Z" fill="#FFD140"/>
|
||||
<path d="M48 16V45.3333C48 46.8061 46.8061 48 45.3333 48H16V18.6667C16 17.1939 17.1939 16 18.6667 16H48Z" fill="#FAF8F5"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M35.5851 24.5273V22.5185C35.586 22.3632 35.5558 22.2092 35.4963 22.0655C35.4367 21.9217 35.349 21.791 35.2382 21.6809C35.1273 21.5707 34.9955 21.4833 34.8504 21.4237C34.7052 21.364 34.5496 21.3333 34.3924 21.3333H29.6078C29.4506 21.3333 29.2949 21.364 29.1498 21.4237C29.0046 21.4833 28.8728 21.5707 28.762 21.6809C28.6512 21.791 28.5634 21.9217 28.5039 22.0655C28.4444 22.2092 28.4142 22.3632 28.4151 22.5185V24.5273C28.0087 24.7187 27.6188 24.9427 27.2494 25.1969L25.5145 24.2126C25.2446 24.0621 24.9261 24.0213 24.6263 24.0988C24.3265 24.1762 24.069 24.366 23.9083 24.6277L21.5161 28.719C21.3606 28.9913 21.3197 29.3131 21.4021 29.6149C21.4845 29.9168 21.6836 30.1746 21.9566 30.3327L23.6644 31.3237C23.6644 31.5447 23.6644 31.7656 23.6644 31.9933C23.6644 32.221 23.6644 32.4419 23.6644 32.6629L21.9295 33.6472C21.6565 33.8054 21.4574 34.0631 21.375 34.365C21.2926 34.6669 21.3335 34.9886 21.489 35.2609L23.9083 39.3589C23.9869 39.4932 24.0915 39.6108 24.2162 39.7051C24.3409 39.7994 24.4832 39.8684 24.6349 39.9082C24.7867 39.948 24.9449 39.9578 25.1005 39.9371C25.256 39.9164 25.406 39.8655 25.5416 39.7874L27.2765 38.8031C27.6459 39.0573 28.0358 39.2813 28.4422 39.4727V41.4815C28.4413 41.6368 28.4715 41.7908 28.531 41.9345C28.5905 42.0783 28.6783 42.209 28.7891 42.3191C28.9 42.4293 29.0317 42.5167 29.1769 42.5763C29.3221 42.636 29.4777 42.6667 29.6349 42.6667H34.4195C34.5767 42.6667 34.7323 42.636 34.8775 42.5763C35.0227 42.5167 35.1544 42.4293 35.2653 42.3191C35.3761 42.209 35.4639 42.0783 35.5234 41.9345C35.5829 41.7908 35.6131 41.6368 35.6122 41.4815V39.4727C36.0186 39.2813 36.4085 39.0573 36.7779 38.8031L38.5128 39.7874C38.7843 39.9367 39.104 39.9755 39.404 39.8955C39.7039 39.8155 39.9605 39.6229 40.1189 39.3589L42.5044 35.2676C42.5835 35.1336 42.635 34.9855 42.656 34.8317C42.6769 34.678 42.667 34.5217 42.6267 34.3718C42.5864 34.2219 42.5166 34.0813 42.4212 33.9581C42.3257 33.8349 42.2066 33.7315 42.0707 33.6539L40.3358 32.6629C40.3358 32.4419 40.3358 32.2143 40.3358 31.9933C40.3358 31.7723 40.3358 31.5447 40.3358 31.3237L42.0707 30.3394C42.2066 30.2618 42.3257 30.1584 42.4212 30.0352C42.5166 29.912 42.5864 29.7714 42.6267 29.6215C42.667 29.4716 42.6769 29.3153 42.656 29.1616C42.635 29.0078 42.5835 28.8597 42.5044 28.7257L40.1189 24.6277C40.0404 24.4934 39.9358 24.3758 39.8111 24.2815C39.6864 24.1872 39.5441 24.1182 39.3924 24.0784C39.2406 24.0386 39.0824 24.0288 38.9268 24.0495C38.7712 24.0702 38.6213 24.1211 38.4857 24.1992L36.7847 25.1902C36.4042 24.9367 36.0029 24.7149 35.5851 24.5273ZM37.1235 28.9533C36.5931 28.0797 35.8427 27.3566 34.9454 26.8546C34.0482 26.3526 33.0346 26.0887 32.0035 26.0887C30.9723 26.0887 29.9588 26.3526 29.0615 26.8546C28.1643 27.3566 27.4139 28.0797 26.8835 28.9533L26.7615 29.1542C26.2744 30.0267 26.0189 31.0069 26.0189 32.0033C26.0189 32.9998 26.2744 33.98 26.7615 34.8525L26.8699 35.04C27.4012 35.9135 28.1523 36.6364 29.0501 37.1382C29.9479 37.6401 30.9618 37.9038 31.9933 37.9038C33.0248 37.9038 34.0388 37.6401 34.9366 37.1382C35.8344 36.6364 36.5854 35.9135 37.1167 35.04L37.2252 34.8525C37.7098 33.978 37.9638 32.997 37.9638 32C37.9638 31.003 37.7098 30.022 37.2252 29.1475L37.1235 28.9533Z" fill="#001C64"/>
|
||||
</svg>
|
After Width: | Height: | Size: 3.8 KiB |
6
modules/ppcp-settings/images/icon-settings-expert.svg
Normal file
6
modules/ppcp-settings/images/icon-settings-expert.svg
Normal file
|
@ -0,0 +1,6 @@
|
|||
<svg width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8 10.6669C8 9.19415 9.19391 8.00024 10.6667 8.00024H45.3333C46.8061 8.00024 48 9.19415 48 10.6669V45.3336C48 46.8063 46.8061 48.0002 45.3333 48.0002H10.6667C9.19391 48.0002 8 46.8063 8 45.3336V10.6669Z" fill="#C6C6C6"/>
|
||||
<path d="M16 18.6669C16 17.1942 17.1939 16.0002 18.6667 16.0002H53.3333C54.8061 16.0002 56 17.1942 56 18.6669V53.3336C56 54.8063 54.8061 56.0002 53.3333 56.0002H18.6667C17.1939 56.0002 16 54.8063 16 53.3336V18.6669Z" fill="#5BBBFC"/>
|
||||
<path d="M48 16.0002V45.3336C48 46.8063 46.8061 48.0002 45.3333 48.0002H16V18.6669C16 17.1942 17.1939 16.0002 18.6667 16.0002H48Z" fill="#FAF8F5"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M35.2518 24.1945V22.1857C35.2527 22.0304 35.2225 21.8765 35.163 21.7327C35.1034 21.5889 35.0157 21.4582 34.9048 21.3481C34.794 21.238 34.6622 21.1506 34.5171 21.0909C34.3719 21.0313 34.2162 21.0006 34.059 21.0006H29.2745C29.1173 21.0006 28.9616 21.0313 28.8165 21.0909C28.6713 21.1506 28.5395 21.238 28.4287 21.3481C28.3178 21.4582 28.2301 21.5889 28.1706 21.7327C28.111 21.8765 28.0808 22.0304 28.0817 22.1857V24.1945C27.6753 24.386 27.2855 24.6099 26.9161 24.8641L25.1812 23.8798C24.9113 23.7293 24.5928 23.6885 24.293 23.766C23.9932 23.8435 23.7357 24.0332 23.575 24.295L21.1827 28.3862C21.0273 28.6585 20.9863 28.9803 21.0687 29.2821C21.1511 29.584 21.3503 29.8418 21.6232 29.9999L23.331 30.9909C23.331 31.2119 23.331 31.4329 23.331 31.6605C23.331 31.8882 23.331 32.1092 23.331 32.3301L21.5961 33.3144C21.3232 33.4726 21.124 33.7304 21.0416 34.0322C20.9592 34.3341 21.0002 34.6559 21.1556 34.9282L23.575 39.0261C23.6536 39.1604 23.7582 39.2781 23.8829 39.3723C24.0076 39.4666 24.1498 39.5356 24.3016 39.5754C24.4533 39.6152 24.6115 39.6251 24.7671 39.6043C24.9227 39.5836 25.0726 39.5327 25.2083 39.4546L26.9432 38.4703C27.3126 38.7246 27.7024 38.9485 28.1088 39.1399V41.1487C28.1079 41.304 28.1381 41.458 28.1977 41.6018C28.2572 41.7455 28.3449 41.8762 28.4558 41.9864C28.5666 42.0965 28.6984 42.1839 28.8436 42.2436C28.9887 42.3032 29.1444 42.3339 29.3016 42.3339H34.0861C34.2434 42.3339 34.399 42.3032 34.5442 42.2436C34.6893 42.1839 34.8211 42.0965 34.932 41.9864C35.0428 41.8762 35.1305 41.7455 35.1901 41.6018C35.2496 41.458 35.2798 41.304 35.2789 41.1487V39.1399C35.6853 38.9485 36.0751 38.7246 36.4445 38.4703L38.1795 39.4546C38.4509 39.604 38.7707 39.6428 39.0706 39.5627C39.3706 39.4827 39.6271 39.2902 39.7856 39.0261L42.1711 34.9349C42.2502 34.8008 42.3017 34.6527 42.3226 34.499C42.3436 34.3452 42.3337 34.1889 42.2934 34.039C42.2531 33.8891 42.1832 33.7485 42.0878 33.6253C41.9924 33.5021 41.8733 33.3987 41.7374 33.3211L40.0025 32.3301C40.0025 32.1092 40.0025 31.8815 40.0025 31.6605C40.0025 31.4396 40.0025 31.2119 40.0025 30.9909L41.7374 30.0066C41.8733 29.929 41.9924 29.8256 42.0878 29.7025C42.1832 29.5793 42.2531 29.4387 42.2934 29.2888C42.3337 29.1388 42.3436 28.9825 42.3226 28.8288C42.3017 28.6751 42.2502 28.5269 42.1711 28.3929L39.7856 24.295C39.707 24.1607 39.6024 24.043 39.4778 23.9487C39.3531 23.8545 39.2108 23.7854 39.059 23.7456C38.9073 23.7058 38.7491 23.696 38.5935 23.7167C38.4379 23.7375 38.288 23.7883 38.1523 23.8664L36.4513 24.8574C36.0708 24.6039 35.6696 24.3822 35.2518 24.1945ZM36.7902 28.6206C36.2598 27.7469 35.5094 27.0238 34.6121 26.5218C33.7148 26.0198 32.7013 25.756 31.6701 25.756C30.639 25.756 29.6255 26.0198 28.7282 26.5218C27.8309 27.0238 27.0805 27.7469 26.5501 28.6206L26.4281 28.8214C25.9411 29.694 25.6856 30.6741 25.6856 31.6706C25.6856 32.667 25.9411 33.6472 26.4281 34.5197L26.5366 34.7072C27.0679 35.5808 27.8189 36.3036 28.7167 36.8055C29.6145 37.3073 30.6285 37.5711 31.66 37.5711C32.6915 37.5711 33.7054 37.3073 34.6032 36.8055C35.501 36.3036 36.2521 35.5808 36.7834 34.7072L36.8918 34.5197C37.3765 33.6452 37.6305 32.6642 37.6305 31.6672C37.6305 30.6702 37.3765 29.6892 36.8918 28.8148L36.7902 28.6206Z" fill="#001C64"/>
|
||||
</svg>
|
After Width: | Height: | Size: 3.9 KiB |
|
@ -13,6 +13,7 @@
|
|||
"@wordpress/scripts": "^30.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@woocommerce/settings": "^1.0.0"
|
||||
"@woocommerce/settings": "^1.0.0",
|
||||
"react-select": "^5.8.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,10 +40,17 @@
|
|||
font-style: italic;
|
||||
}
|
||||
|
||||
@mixin primaryFont{
|
||||
font-family: "PayPalPro", sans-serif;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
& {
|
||||
font-family: "PayPalPro", sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
box-sizing: border-box;
|
||||
color: $color-gray-700;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
@mixin hide-input-field(){
|
||||
@mixin hide-input-field() {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
|
@ -18,7 +18,7 @@
|
|||
border-radius: 0;
|
||||
}
|
||||
|
||||
@mixin fake-input-field($border-radius:0){
|
||||
@mixin fake-input-field($border-radius:0) {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border: 1px solid $color-gray-600;
|
||||
|
@ -26,3 +26,20 @@
|
|||
pointer-events: none;
|
||||
border-radius: $border-radius;
|
||||
}
|
||||
|
||||
@mixin small-button {
|
||||
border-radius: 2px;
|
||||
padding: 6px 12px;
|
||||
@include font(13, 20, 400);
|
||||
}
|
||||
|
||||
@mixin vertical-layout-event-gap($gap:0) {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $gap;
|
||||
}
|
||||
|
||||
@mixin horizontal-layout-even-gap($gap:0) {
|
||||
display: flex;
|
||||
gap: $gap;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ $color-gray-900: #1E1E1E;
|
|||
$color-gray-800: #2F2F2F;
|
||||
$color-gray-700: #757575;
|
||||
$color-gray-600: #949494;
|
||||
$color-gray-500: #2c2c2c;
|
||||
$color-gray-500: #BBBBBB;
|
||||
$color-gray-400: #CCCCCC;
|
||||
$color-gray-300: #EBEBEB;
|
||||
$color-gray-200: #E0E0E0;
|
||||
|
|
|
@ -40,4 +40,71 @@
|
|||
&__checkbox-presentation {
|
||||
@include fake-input-field(2px);
|
||||
}
|
||||
|
||||
&__radio-wrapper {
|
||||
display: flex;
|
||||
gap: 18px;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
|
||||
label {
|
||||
@include font(14, 20, 400);
|
||||
color: $color-gray-800;
|
||||
}
|
||||
}
|
||||
|
||||
&__radio-description {
|
||||
@include font(14, 20, 400);
|
||||
margin: 0;
|
||||
color: $color-gray-800;
|
||||
}
|
||||
|
||||
&__radio-content-additional {
|
||||
padding-left: 38px;
|
||||
padding-top: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
.components-base-control {
|
||||
&__label {
|
||||
color: $color-gray-900;
|
||||
@include font(13, 16, 600);
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
&__input {
|
||||
border: 1px solid $color-gray-700;
|
||||
border-radius: 2px;
|
||||
box-shadow: none;
|
||||
|
||||
&:focus {
|
||||
border-color: $color-blueberry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
input[type='text'] {
|
||||
padding: 7px 11px;
|
||||
@include font(14, 20, 400);
|
||||
@include primaryFont;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
select {
|
||||
padding: 7px 27px 7px 11px;
|
||||
@include font(14, 20, 400);
|
||||
}
|
||||
|
||||
.components-form-toggle.is-checked > .components-form-toggle__track {
|
||||
background-color: $color-blueberry;
|
||||
}
|
||||
|
||||
.ppcp-r-vertical-text-control {
|
||||
.components-base-control__field {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,9 +40,7 @@
|
|||
display: block;
|
||||
}
|
||||
|
||||
button {
|
||||
margin-left: auto;
|
||||
@include font(13, 20, 400);
|
||||
padding: 6px 12px !important;
|
||||
button.is-secondary {
|
||||
@include small-button;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,16 +69,9 @@
|
|||
|
||||
|
||||
input[type='text'] {
|
||||
padding: 7px 11px;
|
||||
@include font(14, 20, 400);
|
||||
margin: 0;
|
||||
border-color: $color-gray-700;
|
||||
}
|
||||
|
||||
label {
|
||||
@include font(14, 16, 400);
|
||||
color: $color-gray-900;
|
||||
}
|
||||
}
|
||||
|
||||
&__field-rows {
|
||||
|
@ -92,9 +85,7 @@
|
|||
}
|
||||
|
||||
.ppcp-r-modal__field-row--save button.is-primary {
|
||||
border-radius: 2px;
|
||||
padding: 6px 12px;
|
||||
@include font(13, 20, 400);
|
||||
@include small-button;
|
||||
}
|
||||
|
||||
&__content-title {
|
||||
|
@ -109,15 +100,4 @@
|
|||
margin: 0 0 24px 0;
|
||||
color: $color-black;
|
||||
}
|
||||
|
||||
&__field-rdb {
|
||||
display: flex;
|
||||
gap: 18px;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
label {
|
||||
@include font(14, 20, 400);
|
||||
color: $color-black;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
.components-base-control {
|
||||
&__label {
|
||||
color: $color-gray-900;
|
||||
@include font(13, 16, 600);
|
||||
margin: 0 0 8px 0;
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
&__input {
|
||||
border: 1px solid $color-gray-700;
|
||||
border-radius: 2px;
|
||||
box-shadow: none;
|
||||
&:focus{
|
||||
border-color:$color-blueberry;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -86,18 +86,13 @@
|
|||
margin: 0 0 8px 0;
|
||||
|
||||
strong {
|
||||
@include font(14, 20, 700);
|
||||
@include font(14, 24, 700);
|
||||
color: $color-black;
|
||||
}
|
||||
}
|
||||
|
||||
&__show-all-data {
|
||||
margin-left: 12px;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
&__status-label {
|
||||
|
@ -113,21 +108,37 @@
|
|||
gap: 12px;
|
||||
}
|
||||
|
||||
&__status-toggle--toggled{
|
||||
.ppcp-r-connection-status__show-all-data{
|
||||
transform:rotate(180deg);
|
||||
}
|
||||
}
|
||||
|
||||
&__status-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
*{
|
||||
user-select: none;
|
||||
}
|
||||
strong {
|
||||
@include font(14, 20, 600);
|
||||
@include font(14, 24, 600);
|
||||
color: $color-gray-800;
|
||||
margin-right: 12px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
span {
|
||||
@include font(14, 20, 400);
|
||||
span:not(.ppcp-r-connection-status__status-toggle) {
|
||||
@include font(14, 24, 400);
|
||||
color: $color-gray-800;
|
||||
}
|
||||
.ppcp-r-connection-status__status-toggle{
|
||||
line-height: 0;
|
||||
}
|
||||
&--first{
|
||||
&:hover{
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 767px) {
|
||||
|
|
|
@ -0,0 +1,312 @@
|
|||
// Global settings styles
|
||||
.ppcp-r-settings {
|
||||
@include vertical-layout-event-gap(48px);
|
||||
}
|
||||
|
||||
|
||||
.ppcp-r-settings-card__content {
|
||||
> .ppcp-r-settings-block {
|
||||
&:not(:last-child) {
|
||||
border-bottom: 1.5px solid $color-gray-700;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ppcp-r-settings-block {
|
||||
.ppcp-r-settings-block__header {
|
||||
display: flex;
|
||||
gap: 48px;
|
||||
|
||||
&-inner {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
&__action {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
&--primary {
|
||||
> .ppcp-r-settings-block__header {
|
||||
.ppcp-r-settings-block__title {
|
||||
@include font(16, 20, 700);
|
||||
color: $color-black;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&--secondary {
|
||||
> .ppcp-r-settings-block__header {
|
||||
.ppcp-r-settings-block__title {
|
||||
@include font(16, 20, 600);
|
||||
color: $color-gray-800;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&--tertiary {
|
||||
padding-bottom: 0;
|
||||
margin-bottom: 24px;
|
||||
|
||||
> .ppcp-r-settings-block__header {
|
||||
align-items: center;
|
||||
|
||||
.ppcp-r-settings-block__title {
|
||||
color: $color-gray-800;
|
||||
@include font(14, 20, 400);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ppcp-r-settings-block__description {
|
||||
margin: 0;
|
||||
@include font(14, 20, 400);
|
||||
color: $color-gray-800;
|
||||
|
||||
a {
|
||||
color: $color-blueberry;
|
||||
}
|
||||
|
||||
strong {
|
||||
color: $color-gray-800;
|
||||
}
|
||||
}
|
||||
|
||||
// Types
|
||||
&--toggle-content {
|
||||
&.ppcp-r-settings-block--content-visible {
|
||||
.ppcp-r-settings-block__toggle-content {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
|
||||
.ppcp-r-settings-block__header {
|
||||
user-select: none;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&--sandbox-connected {
|
||||
.ppcp-r-settings-block__content {
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
button.is-secondary {
|
||||
@include small-button;
|
||||
}
|
||||
|
||||
.ppcp-r-connection-status__data {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
&--expert-rdb{
|
||||
@include vertical-layout-event-gap(24px);
|
||||
}
|
||||
&--connect-sandbox {
|
||||
button.components-button {
|
||||
@include small-button;
|
||||
}
|
||||
|
||||
.ppcp-r__radio-content-additional {
|
||||
.ppcp-r-vertical-text-control {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@include vertical-layout-event-gap(24px);
|
||||
align-items: flex-start;
|
||||
|
||||
input[type='text'] {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&--troubleshooting {
|
||||
> .ppcp-r-settings-block__content > *:not(:last-child) {
|
||||
padding-bottom: 32px;
|
||||
margin-bottom: 32px;
|
||||
border-bottom: 1px solid $color-gray-500;
|
||||
}
|
||||
}
|
||||
|
||||
&--settings{
|
||||
> .ppcp-r-settings-block__content > *:not(:last-child){
|
||||
padding-bottom: 32px;
|
||||
margin-bottom: 32px;
|
||||
border-bottom: 1px solid $color-gray-500;
|
||||
}
|
||||
}
|
||||
|
||||
// Fields
|
||||
input[type='text'] {
|
||||
border-color: $color-gray-700;
|
||||
width: 282px;
|
||||
max-width: 100%;
|
||||
color: $color-gray-800;
|
||||
}
|
||||
|
||||
input[type='text'] {
|
||||
&::placeholder {
|
||||
color: $color-gray-700;
|
||||
}
|
||||
}
|
||||
|
||||
.ppcp-r {
|
||||
&__radio-wrapper {
|
||||
align-items: flex-start;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
&__radio-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
|
||||
label {
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
&__radio-content-additional {
|
||||
padding-left: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
// MultiSelect control
|
||||
.ppcp-r {
|
||||
&__control {
|
||||
border-radius: 2px;
|
||||
border-color: $color-gray-700;
|
||||
width: 282px;
|
||||
min-height: auto;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&__input-container {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&__value-container {
|
||||
padding: 0 0 0 7px;
|
||||
}
|
||||
|
||||
&__indicator {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
&__indicator-separator {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&__value-container--has-value {
|
||||
.ppcp-r__single-value {
|
||||
color: $color-gray-800;
|
||||
}
|
||||
}
|
||||
|
||||
&__placeholde, &__single-value {
|
||||
@include font(13, 20, 400);
|
||||
}
|
||||
|
||||
&__option {
|
||||
&--is-selected {
|
||||
background-color: $color-gray-200;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Special settings styles
|
||||
|
||||
// Hooks table
|
||||
.ppcp-r-table {
|
||||
&__hooks-url {
|
||||
width: 70%;
|
||||
padding-right: 20%;
|
||||
text-align: left;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
&__hooks-events {
|
||||
vertical-align: top;
|
||||
text-align: left;
|
||||
width: 40%;
|
||||
|
||||
span {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
td.ppcp-r-table__hooks-url, td.ppcp-r-table__hooks-events {
|
||||
padding-top: 12px;
|
||||
color: $color-gray-800;
|
||||
@include font(14, 20, 400);
|
||||
|
||||
span {
|
||||
color: inherit;
|
||||
@include font(14, 20, 400);
|
||||
}
|
||||
}
|
||||
|
||||
th.ppcp-r-table__hooks-url, th.ppcp-r-table__hooks-events {
|
||||
@include font(14, 20, 700);
|
||||
color: $color-gray-800;
|
||||
border-bottom: 1px solid $color-gray-600;
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
// Common settings have 48px margin&padding bottom between blocks
|
||||
.ppcp-r-settings-card--common-settings .ppcp-r-settings-card__content {
|
||||
> .ppcp-r-settings-block {
|
||||
&:not(:last-child) {
|
||||
padding-bottom: 48px;
|
||||
margin-bottom: 48px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Expert settings have 32px margin&padding bottom between blocks
|
||||
.ppcp-r-settings-card--expert-settings .ppcp-r-settings-card__content {
|
||||
> .ppcp-r-settings-block {
|
||||
&:not(:last-child) {
|
||||
padding-bottom: 32px;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Order intent block has 32px gap and no lines in between
|
||||
// Save payment methods block has 32px gap and no lines in between
|
||||
.ppcp-r-settings-block {
|
||||
&--order-intent, &--save-payment-methods {
|
||||
@include vertical-layout-event-gap(32px);
|
||||
|
||||
> .ppcp-r-settings-block__content {
|
||||
@include vertical-layout-event-gap(32px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Most primary settings block in the expert settings have 32px space after description
|
||||
.ppcp-r-settings-block--toggle-content {
|
||||
.ppcp-r-settings-block__content {
|
||||
margin-top: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
// Common settings have actions aligned top with the text, Expert settings have actions alligned middle with the text
|
||||
.ppcp-r-settings-card--expert-settings {
|
||||
.ppcp-r-settings-block__header {
|
||||
align-items: center;
|
||||
}
|
||||
}
|
|
@ -32,8 +32,7 @@
|
|||
margin: 0 0 24px 0;
|
||||
}
|
||||
.ppcp-r-toggle-block__toggled-content > button{
|
||||
padding: 6px 12px;
|
||||
@include font(13, 20, 500);
|
||||
@include small-button;
|
||||
color: $color-white;
|
||||
border: none;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
@import './components/reusable-components/onboarding-header';
|
||||
@import './components/reusable-components/button';
|
||||
@import './components/reusable-components/settings-toggle-block';
|
||||
@import './components/reusable-components/text-control';
|
||||
@import './components/reusable-components/separator';
|
||||
@import './components/reusable-components/payment-method-icons';
|
||||
@import "./components/reusable-components/payment-method-item";
|
||||
|
@ -23,6 +22,7 @@
|
|||
@import './components/screens/onboarding';
|
||||
@import './components/screens/dashboard/tab-dashboard';
|
||||
@import './components/screens/dashboard/tab-payment-methods';
|
||||
@import 'components/screens/dashboard/tab-settings';
|
||||
}
|
||||
|
||||
@import './components/reusable-components/payment-method-modal';
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
import { __ } from '@wordpress/i18n';
|
||||
import data from '../../utils/data';
|
||||
import { useState } from '@wordpress/element';
|
||||
|
||||
const ConnectionInfo = ( { connectionStatusDataDefault } ) => {
|
||||
const [ connectionData, setConnectionData ] = useState( {
|
||||
...connectionStatusDataDefault,
|
||||
} );
|
||||
|
||||
const showAllData = () => {
|
||||
setConnectionData( {
|
||||
...connectionData,
|
||||
showAllData: ! connectionData.showAllData,
|
||||
} );
|
||||
};
|
||||
|
||||
const toggleStatusClassName = [ 'ppcp-r-connection-status__status-toggle' ];
|
||||
|
||||
if ( connectionData.showAllData ) {
|
||||
toggleStatusClassName.push(
|
||||
'ppcp-r-connection-status__status-toggle--toggled'
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="ppcp-r-connection-status__data">
|
||||
<div
|
||||
className="ppcp-r-connection-status__status-row ppcp-r-connection-status__status-row--first"
|
||||
onClick={ () => showAllData() }
|
||||
>
|
||||
<strong>
|
||||
{ __( 'Email address:', 'woocommerce-paypal-payments' ) }
|
||||
</strong>
|
||||
<span>{ connectionData.email }</span>
|
||||
<span className={ toggleStatusClassName.join( ' ' ) }>
|
||||
{ data().getImage(
|
||||
'icon-arrow-down.svg',
|
||||
'ppcp-r-connection-status__show-all-data'
|
||||
) }
|
||||
</span>
|
||||
</div>
|
||||
{ connectionData.showAllData && (
|
||||
<>
|
||||
<div className="ppcp-r-connection-status__status-row">
|
||||
<strong>
|
||||
{ __(
|
||||
'Merchant ID:',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
</strong>
|
||||
<span>{ connectionData.merchantId }</span>
|
||||
</div>
|
||||
<div className="ppcp-r-connection-status__status-row">
|
||||
<strong>
|
||||
{ __(
|
||||
'Client ID:',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
</strong>
|
||||
<span>{ connectionData.clientId }</span>
|
||||
</div>
|
||||
</>
|
||||
) }
|
||||
</div>
|
||||
);
|
||||
};
|
||||
export default ConnectionInfo;
|
||||
|
||||
export const connectionStatusDataDefault = {
|
||||
connectionStatus: true,
|
||||
showAllData: false,
|
||||
email: 'bt_us@woocommerce.com',
|
||||
merchantId: 'AT45V2DGMKLRY',
|
||||
clientId: 'BAARTJLxtUNN4d2GMB6Eut3suMDYad72xQA-FntdIFuJ6FmFJITxAY8',
|
||||
};
|
|
@ -24,7 +24,7 @@ export const PayPalRdb = ( props ) => {
|
|||
return (
|
||||
<div className="ppcp-r__radio">
|
||||
<input
|
||||
id={ props?.id ? props.id : null }
|
||||
id={ props?.id }
|
||||
className="ppcp-r__radio-value"
|
||||
type="radio"
|
||||
checked={ props.value === props.currentValue }
|
||||
|
@ -37,6 +37,40 @@ export const PayPalRdb = ( props ) => {
|
|||
);
|
||||
};
|
||||
|
||||
export const PayPalRdbWithContent = ( props ) => {
|
||||
const className = [ 'ppcp-r__radio-wrapper' ];
|
||||
|
||||
if ( props?.className ) {
|
||||
className.push( props.className );
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="ppcp-r__radio-outer-wrapper">
|
||||
<div className={ className }>
|
||||
<PayPalRdb { ...props } />
|
||||
<div className="ppcp-r__radio-content">
|
||||
<label htmlFor={ props?.id }>{ props.label }</label>
|
||||
{ props.description && (
|
||||
<p
|
||||
className="ppcp-r__radio-description"
|
||||
dangerouslySetInnerHTML={ {
|
||||
__html: props.description,
|
||||
} }
|
||||
/>
|
||||
) }
|
||||
</div>
|
||||
</div>
|
||||
{ props?.toggleAdditionalContent &&
|
||||
props.children &&
|
||||
props.value === props.currentValue && (
|
||||
<div className="ppcp-r__radio-content-additional">
|
||||
{ props.children }
|
||||
</div>
|
||||
) }
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const handleCheckboxState = ( checked, props ) => {
|
||||
let newValue = null;
|
||||
if ( checked ) {
|
||||
|
|
|
@ -0,0 +1,146 @@
|
|||
import { Button, ToggleControl, TextControl } from '@wordpress/components';
|
||||
import data from '../../utils/data';
|
||||
import { useState } from '@wordpress/element';
|
||||
import Select, { components } from 'react-select';
|
||||
|
||||
export const SETTINGS_BLOCK_TYPE_EMPTY = 'empty';
|
||||
export const SETTINGS_BLOCK_TYPE_TOGGLE = 'toggle';
|
||||
export const SETTINGS_BLOCK_TYPE_TOGGLE_CONTENT = 'toggle-content';
|
||||
export const SETTINGS_BLOCK_TYPE_INPUT = 'input';
|
||||
export const SETTINGS_BLOCK_TYPE_BUTTON = 'button';
|
||||
export const SETTINGS_BLOCK_TYPE_SELECT = 'select';
|
||||
|
||||
export const SETTINGS_BLOCK_STYLING_TYPE_PRIMARY = 'primary';
|
||||
export const SETTINGS_BLOCK_STYLING_TYPE_SECONDARY = 'secondary';
|
||||
export const SETTINGS_BLOCK_STYLING_TYPE_TERTIARY = 'tertiary';
|
||||
|
||||
const SettingsBlock = ( {
|
||||
className,
|
||||
title,
|
||||
description,
|
||||
children,
|
||||
style,
|
||||
actionProps,
|
||||
tag,
|
||||
} ) => {
|
||||
const [ toggleContentVisible, setToggleContentVisible ] = useState(
|
||||
actionProps?.type !== SETTINGS_BLOCK_TYPE_TOGGLE_CONTENT
|
||||
);
|
||||
|
||||
const toggleContent = () => {
|
||||
if ( actionProps?.type !== SETTINGS_BLOCK_TYPE_TOGGLE_CONTENT ) {
|
||||
return;
|
||||
}
|
||||
setToggleContentVisible( ! toggleContentVisible );
|
||||
};
|
||||
|
||||
const blockClassName = [ 'ppcp-r-settings-block' ];
|
||||
|
||||
blockClassName.push( 'ppcp-r-settings-block--' + style );
|
||||
blockClassName.push( 'ppcp-r-settings-block--' + actionProps?.type );
|
||||
|
||||
if ( className ) {
|
||||
blockClassName.push( className );
|
||||
}
|
||||
|
||||
if (
|
||||
toggleContentVisible &&
|
||||
actionProps?.type === SETTINGS_BLOCK_TYPE_TOGGLE_CONTENT
|
||||
) {
|
||||
blockClassName.push( 'ppcp-r-settings-block--content-visible' );
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={ blockClassName.join( ' ' ) }>
|
||||
<div
|
||||
className="ppcp-r-settings-block__header"
|
||||
onClick={ () => toggleContent() }
|
||||
>
|
||||
<div className="ppcp-r-settings-block__header-inner">
|
||||
<span className="ppcp-r-settings-block__title">
|
||||
{ title }
|
||||
{ tag && tag }
|
||||
</span>
|
||||
<p
|
||||
className="ppcp-r-settings-block__description"
|
||||
dangerouslySetInnerHTML={ { __html: description } }
|
||||
/>
|
||||
</div>
|
||||
{ actionProps?.type !== SETTINGS_BLOCK_TYPE_EMPTY && (
|
||||
<div className="ppcp-r-settings-block__action">
|
||||
{ actionProps?.type === SETTINGS_BLOCK_TYPE_TOGGLE && (
|
||||
<ToggleControl
|
||||
className="ppcp-r-settings-block__toggle"
|
||||
__nextHasNoMarginBottom={ true }
|
||||
checked={ actionProps?.value }
|
||||
onChange={ ( newValue ) =>
|
||||
actionProps?.callback(
|
||||
actionProps?.key,
|
||||
newValue
|
||||
)
|
||||
}
|
||||
/>
|
||||
) }
|
||||
{ actionProps?.type === SETTINGS_BLOCK_TYPE_INPUT && (
|
||||
<>
|
||||
<TextControl
|
||||
className="ppcp-r-vertical-text-control"
|
||||
placeholder={ actionProps?.placeholder }
|
||||
value={ actionProps?.value }
|
||||
onChange={ ( newValue ) =>
|
||||
actionProps?.callback(
|
||||
actionProps?.key,
|
||||
newValue
|
||||
)
|
||||
}
|
||||
/>
|
||||
</>
|
||||
) }
|
||||
{ actionProps?.type === SETTINGS_BLOCK_TYPE_BUTTON && (
|
||||
<Button
|
||||
variant={ actionProps.buttonType }
|
||||
onClick={
|
||||
actionProps?.callback
|
||||
? () => actionProps.callback()
|
||||
: undefined
|
||||
}
|
||||
>
|
||||
{ actionProps.value }
|
||||
</Button>
|
||||
) }
|
||||
{ actionProps?.type ===
|
||||
SETTINGS_BLOCK_TYPE_TOGGLE_CONTENT && (
|
||||
<div className="ppcp-r-settings-block__toggle-content">
|
||||
{ data().getImage( 'icon-arrow-down.svg' ) }
|
||||
</div>
|
||||
) }
|
||||
{ actionProps?.type === SETTINGS_BLOCK_TYPE_SELECT && (
|
||||
<Select
|
||||
className="ppcp-r-multiselect"
|
||||
classNamePrefix="ppcp-r"
|
||||
isMulti={ actionProps?.isMulti }
|
||||
options={ actionProps?.options }
|
||||
components={ { DropdownIndicator } }
|
||||
/>
|
||||
) }
|
||||
</div>
|
||||
) }
|
||||
</div>
|
||||
{ children && toggleContentVisible && (
|
||||
<div className="ppcp-r-settings-block__content">
|
||||
{ children }
|
||||
</div>
|
||||
) }
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const DropdownIndicator = ( props ) => {
|
||||
return (
|
||||
<components.DropdownIndicator { ...props }>
|
||||
{ data().getImage( 'icon-arrow-down.svg' ) }
|
||||
</components.DropdownIndicator>
|
||||
);
|
||||
};
|
||||
|
||||
export default SettingsBlock;
|
|
@ -1,7 +1,10 @@
|
|||
import PaymentMethodModal from '../../../ReusableComponents/PaymentMethodModal';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { Button } from '@wordpress/components';
|
||||
import { PayPalRdb } from '../../../ReusableComponents/Fields';
|
||||
import {
|
||||
PayPalRdb,
|
||||
PayPalRdbWithContent,
|
||||
} from '../../../ReusableComponents/Fields';
|
||||
import { useState } from '@wordpress/element';
|
||||
|
||||
const THREED_SECURE_GROUP_NAME = 'threed-secure';
|
||||
|
@ -27,48 +30,40 @@ const ModalAcdc = ( { setModalIsVisible } ) => {
|
|||
) }
|
||||
</p>
|
||||
<div className="ppcp-r-modal__field-rows ppcp-r-modal__field-rows--acdc">
|
||||
<div className="ppcp-r-modal__field-rdb">
|
||||
<PayPalRdb
|
||||
<PayPalRdbWithContent
|
||||
id="no-3d-secure"
|
||||
name={ THREED_SECURE_GROUP_NAME }
|
||||
value="no-3d-secure"
|
||||
currentValue={ threeDSecure }
|
||||
handleRdbState={ setThreeDSecure }
|
||||
label={ __(
|
||||
'No 3D Secure',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
/>
|
||||
<label htmlFor="no-3d-secure">
|
||||
{ __( 'No 3D Secure', 'woocommerce-paypal-payments' ) }
|
||||
</label>
|
||||
</div>
|
||||
<div className="ppcp-r-modal__field-rdb">
|
||||
<PayPalRdb
|
||||
<PayPalRdbWithContent
|
||||
id="only-required-3d-secure"
|
||||
name={ THREED_SECURE_GROUP_NAME }
|
||||
value="only-required-3d-secure"
|
||||
currentValue={ threeDSecure }
|
||||
handleRdbState={ setThreeDSecure }
|
||||
/>
|
||||
<label htmlFor="only-required-3d-secure">
|
||||
{ __(
|
||||
label={ __(
|
||||
'Only when required',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
</label>
|
||||
</div>
|
||||
<div className="ppcp-r-modal__field-rdb">
|
||||
<PayPalRdb
|
||||
/>
|
||||
|
||||
<PayPalRdbWithContent
|
||||
id="always-3d-secure"
|
||||
name={ THREED_SECURE_GROUP_NAME }
|
||||
value="always-3d-secure"
|
||||
currentValue={ threeDSecure }
|
||||
handleRdbState={ setThreeDSecure }
|
||||
/>
|
||||
<label htmlFor="always-3d-secure">
|
||||
{ __(
|
||||
label={ __(
|
||||
'Always require 3D Secure',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
</label>
|
||||
</div>
|
||||
/>
|
||||
</div>
|
||||
<div className="ppcp-r-modal__field-rows">
|
||||
<div className="ppcp-r-modal__field-row ppcp-r-modal__field-row--save">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import PaymentMethodModal from '../../../ReusableComponents/PaymentMethodModal';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { ToggleControl, Button } from '@wordpress/components';
|
||||
import { ToggleControl, Button, TextControl } from '@wordpress/components';
|
||||
import { useState } from '@wordpress/element';
|
||||
|
||||
const ModalPayPal = ( { setModalIsVisible } ) => {
|
||||
|
@ -23,39 +23,30 @@ const ModalPayPal = ( { setModalIsVisible } ) => {
|
|||
>
|
||||
<div className="ppcp-r-modal__field-rows">
|
||||
<div className="ppcp-r-modal__field-row">
|
||||
<label htmlFor="ppcp-r-paypal-settings-checkout-title">
|
||||
{ __(
|
||||
<TextControl
|
||||
className="ppcp-r-vertical-text-control"
|
||||
label={ __(
|
||||
'Checkout page title',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="ppcp-r-paypal-settings-checkout-title"
|
||||
value={ paypalSettings.checkoutPageTitle }
|
||||
onInput={ ( e ) =>
|
||||
updateFormValue(
|
||||
'checkoutPageTitle',
|
||||
e.target.value
|
||||
)
|
||||
onChange={ ( newValue ) =>
|
||||
updateFormValue( 'checkoutPageTitle', newValue )
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div className="ppcp-r-modal__field-row">
|
||||
<label htmlFor="ppcp-r-paypal-settings-checkout-page-description">
|
||||
{ __(
|
||||
<TextControl
|
||||
className="ppcp-r-vertical-text-control"
|
||||
label={ __(
|
||||
'Checkout page description',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="ppcp-r-paypal-settings-checkout-page-description"
|
||||
value={ paypalSettings.checkoutPageDescription }
|
||||
onInput={ ( e ) =>
|
||||
onChange={ ( newValue ) =>
|
||||
updateFormValue(
|
||||
'checkoutPageDescription',
|
||||
e.target.value
|
||||
newValue
|
||||
)
|
||||
}
|
||||
/>
|
||||
|
|
|
@ -11,21 +11,13 @@ import TitleBadge, {
|
|||
TITLE_BADGE_NEGATIVE,
|
||||
TITLE_BADGE_POSITIVE,
|
||||
} from '../../ReusableComponents/TitleBadge';
|
||||
import ConnectionInfo, {
|
||||
connectionStatusDataDefault,
|
||||
} from '../../ReusableComponents/ConnectionInfo';
|
||||
|
||||
const TabDashboard = () => {
|
||||
const [ todos, setTodos ] = useState( [] );
|
||||
const [ todosData, setTodosData ] = useState( todosDataDefault );
|
||||
const [ connectionData, setConnectionData ] = useState( {
|
||||
connectionStatus: true,
|
||||
showAllData: false,
|
||||
email: 'bt_us@woocommerce.com',
|
||||
merchantId: 'AT45V2DGMKLRY',
|
||||
clientId: 'BAARTJLxtUNN4d2GMB6Eut3suMDYad72xQA-FntdIFuJ6FmFJITxAY8',
|
||||
} );
|
||||
|
||||
const showAllData = () => {
|
||||
setConnectionData( { ...connectionData, showAllData: true } );
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="ppcp-r-tab-dashboard">
|
||||
|
@ -68,8 +60,7 @@ const TabDashboard = () => {
|
|||
) }
|
||||
>
|
||||
<ConnectionStatus
|
||||
connectionData={ connectionData }
|
||||
showAllData={ showAllData }
|
||||
connectionData={ connectionStatusDataDefault }
|
||||
/>
|
||||
<FeaturesRefresh />
|
||||
{ featuresDefault.map( ( feature ) => {
|
||||
|
@ -82,7 +73,7 @@ const TabDashboard = () => {
|
|||
);
|
||||
};
|
||||
|
||||
const ConnectionStatus = ( { connectionData, showAllData } ) => {
|
||||
const ConnectionStatus = ( { connectionData } ) => {
|
||||
return (
|
||||
<div className="ppcp-r-connection-status">
|
||||
<div className="ppcp-r-connection-status__status">
|
||||
|
@ -118,47 +109,9 @@ const ConnectionStatus = ( { connectionData, showAllData } ) => {
|
|||
</div>
|
||||
</div>
|
||||
{ connectionData.connectionStatus && (
|
||||
<div className="ppcp-r-connection-status__data">
|
||||
<div className="ppcp-r-connection-status__status-row">
|
||||
<strong>
|
||||
{ __(
|
||||
'Email address:',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
</strong>
|
||||
<span>{ connectionData.email }</span>
|
||||
{ ! connectionData.showAllData && (
|
||||
<span onClick={ () => showAllData() }>
|
||||
{ data().getImage(
|
||||
'icon-arrow-down.svg',
|
||||
'ppcp-r-connection-status__show-all-data'
|
||||
) }
|
||||
</span>
|
||||
) }
|
||||
</div>
|
||||
{ connectionData.showAllData && (
|
||||
<>
|
||||
<div className="ppcp-r-connection-status__status-row">
|
||||
<strong>
|
||||
{ __(
|
||||
'Merchant ID:',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
</strong>
|
||||
<span>{ connectionData.merchantId }</span>
|
||||
</div>
|
||||
<div className="ppcp-r-connection-status__status-row">
|
||||
<strong>
|
||||
{ __(
|
||||
'Client ID:',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
</strong>
|
||||
<span>{ connectionData.clientId }</span>
|
||||
</div>
|
||||
</>
|
||||
) }
|
||||
</div>
|
||||
<ConnectionInfo
|
||||
connectionStatusDataDefault={ connectionStatusDataDefault }
|
||||
/>
|
||||
) }
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,5 +1,47 @@
|
|||
import { useState } from '@wordpress/element';
|
||||
import CommonSettings from './TabSettingsElements/CommonSettings';
|
||||
import ExpertSettings from './TabSettingsElements/ExpertSettings';
|
||||
|
||||
const TabSettings = () => {
|
||||
return <div>Settings tab</div>;
|
||||
const [ settings, setSettings ] = useState( {
|
||||
invoicePrefix: '',
|
||||
authorizeOnly: false,
|
||||
captureVirtualOnlyOrders: false,
|
||||
savePaypalAndVenmo: false,
|
||||
saveCreditCardAndDebitCard: false,
|
||||
payNowExperience: false,
|
||||
sandboxAccountCredentials: false,
|
||||
sandboxMode: null,
|
||||
sandboxEnabled: false,
|
||||
sandboxClientId: '',
|
||||
sandboxSecretKey: '',
|
||||
sandboxConnected: false,
|
||||
logging: false,
|
||||
subtotalMismatchFallback: null,
|
||||
brandName: '',
|
||||
softDescriptor: '',
|
||||
paypalLandingPage: null,
|
||||
buttonLanguage: '',
|
||||
} );
|
||||
const updateFormValue = ( key, value ) => {
|
||||
console.log( key, value );
|
||||
setSettings( { ...settings, [ key ]: value } );
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="ppcp-r-settings">
|
||||
<CommonSettings
|
||||
settings={ settings }
|
||||
updateFormValue={ updateFormValue }
|
||||
/>
|
||||
<ExpertSettings
|
||||
settings={ settings }
|
||||
updateFormValue={ updateFormValue }
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default TabSettings;
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
import { __ } from '@wordpress/i18n';
|
||||
import SettingsBlock, {
|
||||
SETTINGS_BLOCK_STYLING_TYPE_PRIMARY,
|
||||
SETTINGS_BLOCK_STYLING_TYPE_SECONDARY,
|
||||
SETTINGS_BLOCK_TYPE_EMPTY,
|
||||
SETTINGS_BLOCK_TYPE_TOGGLE,
|
||||
} from '../../../../ReusableComponents/SettingsBlock';
|
||||
|
||||
const OrderIntent = ( { updateFormValue, settings } ) => {
|
||||
return (
|
||||
<SettingsBlock
|
||||
title={ __( 'Order Intent', 'woocommerce-paypal-payments' ) }
|
||||
description={ __(
|
||||
'Choose between immediate capture or authorization-only, with manual capture in the Orders section.',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
style={ SETTINGS_BLOCK_STYLING_TYPE_PRIMARY }
|
||||
className="ppcp-r-settings-block--order-intent"
|
||||
actionProps={ {
|
||||
type: SETTINGS_BLOCK_TYPE_EMPTY,
|
||||
} }
|
||||
>
|
||||
<SettingsBlock
|
||||
title={ __( 'Authorize Only', 'woocommerce-paypal-payments' ) }
|
||||
description={ __(
|
||||
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc pellentesque libero vitae mattis tempor.',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
style={ SETTINGS_BLOCK_STYLING_TYPE_SECONDARY }
|
||||
actionProps={ {
|
||||
type: SETTINGS_BLOCK_TYPE_TOGGLE,
|
||||
callback: updateFormValue,
|
||||
key: 'authorizeOnly',
|
||||
value: settings.authorizeOnly,
|
||||
} }
|
||||
/>
|
||||
|
||||
<SettingsBlock
|
||||
title={ __(
|
||||
'Capture Virtual-Only Orders',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
description={ __(
|
||||
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc pellentesque libero vitae mattis tempor.',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
style={ SETTINGS_BLOCK_STYLING_TYPE_SECONDARY }
|
||||
actionProps={ {
|
||||
type: SETTINGS_BLOCK_TYPE_TOGGLE,
|
||||
callback: updateFormValue,
|
||||
key: 'captureVirtualOnlyOrders',
|
||||
value: settings.captureVirtualOnlyOrders,
|
||||
} }
|
||||
/>
|
||||
</SettingsBlock>
|
||||
);
|
||||
};
|
||||
|
||||
export default OrderIntent;
|
|
@ -0,0 +1,66 @@
|
|||
import SettingsBlock, {
|
||||
SETTINGS_BLOCK_STYLING_TYPE_PRIMARY,
|
||||
SETTINGS_BLOCK_STYLING_TYPE_SECONDARY,
|
||||
SETTINGS_BLOCK_TYPE_SELECT,
|
||||
SETTINGS_BLOCK_TYPE_TOGGLE_CONTENT,
|
||||
} from '../../../../ReusableComponents/SettingsBlock';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
|
||||
const OtherSettings = ( { settings, updateFormValue } ) => {
|
||||
return (
|
||||
<SettingsBlock
|
||||
title={ __(
|
||||
'Other payment method settings',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
description={ __(
|
||||
'Modify the checkout experience for alternative payment methods, credit cards, and digital wallets',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
style={ SETTINGS_BLOCK_STYLING_TYPE_PRIMARY }
|
||||
actionProps={ {
|
||||
type: SETTINGS_BLOCK_TYPE_TOGGLE_CONTENT,
|
||||
} }
|
||||
>
|
||||
<SettingsBlock
|
||||
title={ __(
|
||||
'Disable specific credit cards',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
description={ __(
|
||||
'If left blank, PayPal and other buttons will present in the user’s detected language. Enter a language here to force all buttons to display in that language.',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
style={ SETTINGS_BLOCK_STYLING_TYPE_SECONDARY }
|
||||
actionProps={ {
|
||||
type: SETTINGS_BLOCK_TYPE_SELECT,
|
||||
options: creditCardExamples,
|
||||
value: settings.buttonLanguage,
|
||||
callback: updateFormValue,
|
||||
key: 'buttonLanguage',
|
||||
isMulti: true,
|
||||
} }
|
||||
/>
|
||||
</SettingsBlock>
|
||||
);
|
||||
};
|
||||
|
||||
const creditCardExamples = [
|
||||
{ value: '', label: __( 'Select', 'woocommerce-paypal-payments' ) },
|
||||
{
|
||||
value: 'mastercard',
|
||||
label: __( 'Mastercard', 'woocommerce-paypal-payments' ),
|
||||
},
|
||||
{ value: 'visa', label: __( 'Visa', 'woocommerce-paypal-payments' ) },
|
||||
{
|
||||
value: 'amex',
|
||||
label: __( 'American Express', 'woocommerce-paypal-payments' ),
|
||||
},
|
||||
{ value: 'jcb', label: __( 'JCB', 'woocommerce-paypal-payments' ) },
|
||||
{
|
||||
value: 'diners-club',
|
||||
label: __( 'Diners Club', 'woocommerce-paypal-payments' ),
|
||||
},
|
||||
];
|
||||
|
||||
export default OtherSettings;
|
|
@ -0,0 +1,238 @@
|
|||
import { __ } from '@wordpress/i18n';
|
||||
import SettingsBlock, {
|
||||
SETTINGS_BLOCK_STYLING_TYPE_PRIMARY,
|
||||
SETTINGS_BLOCK_STYLING_TYPE_SECONDARY,
|
||||
SETTINGS_BLOCK_TYPE_EMPTY,
|
||||
SETTINGS_BLOCK_TYPE_INPUT,
|
||||
SETTINGS_BLOCK_TYPE_SELECT,
|
||||
SETTINGS_BLOCK_TYPE_TOGGLE,
|
||||
SETTINGS_BLOCK_TYPE_TOGGLE_CONTENT,
|
||||
} from '../../../../ReusableComponents/SettingsBlock';
|
||||
import { PayPalRdbWithContent } from '../../../../ReusableComponents/Fields';
|
||||
|
||||
const PaypalSettings = ( { updateFormValue, settings } ) => {
|
||||
return (
|
||||
<SettingsBlock
|
||||
className="ppcp-r-settings-block--settings"
|
||||
title={ __( 'PayPal Settings', 'woocommerce-paypal-payments' ) }
|
||||
description={ __(
|
||||
'Modify the PayPal checkout experience',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
style={ SETTINGS_BLOCK_STYLING_TYPE_PRIMARY }
|
||||
actionProps={ {
|
||||
callback: updateFormValue,
|
||||
type: SETTINGS_BLOCK_TYPE_TOGGLE_CONTENT,
|
||||
key: 'payNowExperience',
|
||||
value: settings.payNowExperience,
|
||||
} }
|
||||
>
|
||||
<SettingsBlock
|
||||
title={ __(
|
||||
'Subtotal mismatch fallback',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
description={ __(
|
||||
'Due to differences in how WooCommerce and PayPal calculates taxes, some transactions may fail due to a rounding error. This settings determines the fallback behavior.',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
style={ SETTINGS_BLOCK_STYLING_TYPE_SECONDARY }
|
||||
actionProps={ {
|
||||
type: SETTINGS_BLOCK_TYPE_EMPTY,
|
||||
} }
|
||||
>
|
||||
<div className="ppcp-r-settings-block--mismatch-wrapper ppcp-r-settings-block--expert-rdb">
|
||||
<PayPalRdbWithContent
|
||||
id="add_a_correction"
|
||||
name="paypal_settings_mismatch"
|
||||
value="add_a_correction"
|
||||
currentValue={ settings.subtotalMismatchFallback }
|
||||
handleRdbState={ ( newValue ) =>
|
||||
updateFormValue(
|
||||
'subtotalMismatchFallback',
|
||||
newValue
|
||||
)
|
||||
}
|
||||
label={ __(
|
||||
'Add a correction',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
description={ __(
|
||||
'Adds an additional line item with the missing amount.',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
/>
|
||||
<PayPalRdbWithContent
|
||||
id="do_not_send_line_items"
|
||||
name="paypal_settings_mismatch"
|
||||
value="do_not_send_line_items"
|
||||
currentValue={ settings.subtotalMismatchFallback }
|
||||
handleRdbState={ ( newValue ) =>
|
||||
updateFormValue(
|
||||
'subtotalMismatchFallback',
|
||||
newValue
|
||||
)
|
||||
}
|
||||
label={ __(
|
||||
'Do not send line items',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
description={ __(
|
||||
'Resubmit the transaction without line item details',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
/>
|
||||
</div>
|
||||
</SettingsBlock>
|
||||
|
||||
<SettingsBlock
|
||||
title={ __(
|
||||
'Instant payments only',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
description={ __(
|
||||
'If enabled, PayPal will not allow buyers to use funding sources that take additional time to complete, such as eChecks.',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
style={ SETTINGS_BLOCK_STYLING_TYPE_SECONDARY }
|
||||
actionProps={ {
|
||||
type: SETTINGS_BLOCK_TYPE_TOGGLE,
|
||||
value: settings.savePaypalAndVenmo,
|
||||
callback: updateFormValue,
|
||||
key: 'savePaypalAndVenmo',
|
||||
} }
|
||||
/>
|
||||
<SettingsBlock
|
||||
title={ __( 'Brand name', 'woocommerce-paypal-payments' ) }
|
||||
description={ __(
|
||||
'What business name to show to your buyers during checkout and on receipts.',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
style={ SETTINGS_BLOCK_STYLING_TYPE_SECONDARY }
|
||||
actionProps={ {
|
||||
type: SETTINGS_BLOCK_TYPE_INPUT,
|
||||
value: settings.brandName,
|
||||
callback: updateFormValue,
|
||||
key: 'brandName',
|
||||
placeholder: __(
|
||||
'Brand name',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
} }
|
||||
/>
|
||||
<SettingsBlock
|
||||
title={ __( 'Soft Descriptor', 'woocommerce-paypal-payments' ) }
|
||||
description={ __(
|
||||
"The dynamic text used to construct the statement descriptor that appears on a payer's card statement. Applies to PayPal and Credit Card transactions. Max value of 22 characters.",
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
style={ SETTINGS_BLOCK_STYLING_TYPE_SECONDARY }
|
||||
actionProps={ {
|
||||
type: SETTINGS_BLOCK_TYPE_INPUT,
|
||||
value: settings.softDescriptor,
|
||||
callback: updateFormValue,
|
||||
key: 'softDescriptor',
|
||||
placeholder: __(
|
||||
'Soft Descriptor',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
} }
|
||||
/>
|
||||
<SettingsBlock
|
||||
title={ __(
|
||||
'PayPal landing page',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
description={ __(
|
||||
'Determine which experience a buyer sees when they click the PayPal button.',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
style={ SETTINGS_BLOCK_STYLING_TYPE_SECONDARY }
|
||||
actionProps={ {
|
||||
type: SETTINGS_BLOCK_TYPE_EMPTY,
|
||||
} }
|
||||
>
|
||||
<div className="ppcp-r-settings-block--landing ppcp-r-settings-block--expert-rdb">
|
||||
<PayPalRdbWithContent
|
||||
id="no_perference"
|
||||
name="paypal_settings_landing"
|
||||
value="no_reference"
|
||||
currentValue={ settings.paypalLandingPage }
|
||||
handleRdbState={ ( newValue ) =>
|
||||
updateFormValue( 'paypalLandingPage', newValue )
|
||||
}
|
||||
label={ __(
|
||||
'No preference',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
description={ __(
|
||||
'Shows the buyer the PayPal login for a recognized PayPal buyer.',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
/>
|
||||
<PayPalRdbWithContent
|
||||
id="login_page"
|
||||
name="paypal_settings_landing"
|
||||
value="login_page"
|
||||
currentValue={ settings.paypalLandingPage }
|
||||
handleRdbState={ ( newValue ) =>
|
||||
updateFormValue( 'paypalLandingPage', newValue )
|
||||
}
|
||||
label={ __(
|
||||
'Login page',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
description={ __(
|
||||
'Always show the buyer the PayPal login screen.',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
/>
|
||||
<PayPalRdbWithContent
|
||||
id="guest_checkout_page"
|
||||
name="paypal_settings_landing"
|
||||
value="guest_checkout_page"
|
||||
currentValue={ settings.paypalLandingPage }
|
||||
handleRdbState={ ( newValue ) =>
|
||||
updateFormValue( 'paypalLandingPage', newValue )
|
||||
}
|
||||
label={ __(
|
||||
'Guest checkout page',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
description={ __(
|
||||
'Always show the buyer the guest checkout fields first.',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
/>
|
||||
</div>
|
||||
</SettingsBlock>
|
||||
<SettingsBlock
|
||||
title={ __( 'Button Language', 'woocommerce-paypal-payments' ) }
|
||||
description={ __(
|
||||
'If left blank, PayPal and other buttons will present in the user’s detected language. Enter a language here to force all buttons to display in that language.',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
style={ SETTINGS_BLOCK_STYLING_TYPE_SECONDARY }
|
||||
actionProps={ {
|
||||
type: SETTINGS_BLOCK_TYPE_SELECT,
|
||||
value: settings.buttonLanguage,
|
||||
callback: updateFormValue,
|
||||
options: languagesExample,
|
||||
key: 'buttonLanguage',
|
||||
placeholder: __(
|
||||
'Browser language',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
} }
|
||||
/>
|
||||
</SettingsBlock>
|
||||
);
|
||||
};
|
||||
|
||||
const languagesExample = [
|
||||
{ value: 'en', label: 'English' },
|
||||
{ value: 'de', label: 'German' },
|
||||
{ value: 'es', label: 'Spanish' },
|
||||
{ value: 'it', label: 'Italian' },
|
||||
];
|
||||
export default PaypalSettings;
|
|
@ -0,0 +1,197 @@
|
|||
import { __, sprintf } from '@wordpress/i18n';
|
||||
import SettingsBlock, {
|
||||
SETTINGS_BLOCK_STYLING_TYPE_PRIMARY,
|
||||
SETTINGS_BLOCK_STYLING_TYPE_SECONDARY,
|
||||
SETTINGS_BLOCK_STYLING_TYPE_TERTIARY,
|
||||
SETTINGS_BLOCK_TYPE_EMPTY,
|
||||
SETTINGS_BLOCK_TYPE_TOGGLE,
|
||||
SETTINGS_BLOCK_TYPE_TOGGLE_CONTENT,
|
||||
} from '../../../../ReusableComponents/SettingsBlock';
|
||||
import TitleBadge, {
|
||||
TITLE_BADGE_POSITIVE,
|
||||
} from '../../../../ReusableComponents/TitleBadge';
|
||||
import ConnectionInfo, {
|
||||
connectionStatusDataDefault,
|
||||
} from '../../../../ReusableComponents/ConnectionInfo';
|
||||
import { Button, TextControl } from '@wordpress/components';
|
||||
import { PayPalRdbWithContent } from '../../../../ReusableComponents/Fields';
|
||||
|
||||
const Sandbox = ( { settings, updateFormValue } ) => {
|
||||
const className = settings.sandboxConnected
|
||||
? 'ppcp-r-settings-block--sandbox-connected'
|
||||
: 'ppcp-r-settings-block--sandbox-disconnected';
|
||||
return (
|
||||
<SettingsBlock
|
||||
title={ __( 'Sandbox', 'woocommerce-paypal-payments' ) }
|
||||
className={ className }
|
||||
description={ __(
|
||||
"Test your site in PayPal's Sandbox environment.<br /><strong>Note</strong>: No real payments/money movement occur in Sandbox mode. Do not ship orders made in this mode.",
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
style={ SETTINGS_BLOCK_STYLING_TYPE_PRIMARY }
|
||||
actionProps={ {
|
||||
type: SETTINGS_BLOCK_TYPE_TOGGLE_CONTENT,
|
||||
callback: updateFormValue,
|
||||
key: 'payNowExperience',
|
||||
value: settings.payNowExperience,
|
||||
} }
|
||||
>
|
||||
{ settings.sandboxConnected && (
|
||||
<SettingsBlock
|
||||
title={ __(
|
||||
'Sandbox account credentials',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
description={ __(
|
||||
'Your account is connected to sandbox, no real charging takes place. To accept live payments, turn off sandbox mode and connect your live PayPal account.',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
tag={
|
||||
<TitleBadge
|
||||
type={ TITLE_BADGE_POSITIVE }
|
||||
text={ __(
|
||||
'Connected',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
/>
|
||||
}
|
||||
style={ SETTINGS_BLOCK_STYLING_TYPE_SECONDARY }
|
||||
actionProps={ {
|
||||
type: SETTINGS_BLOCK_TYPE_EMPTY,
|
||||
callback: updateFormValue,
|
||||
key: 'sandboxAccountCredentials',
|
||||
value: settings.sandboxAccountCredentials,
|
||||
} }
|
||||
>
|
||||
<div className="ppcp-r-settings-block--sandbox">
|
||||
<SettingsBlock
|
||||
title={ __(
|
||||
'Enable sandbox mode',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
style={ SETTINGS_BLOCK_STYLING_TYPE_TERTIARY }
|
||||
actionProps={ {
|
||||
type: SETTINGS_BLOCK_TYPE_TOGGLE,
|
||||
callback: updateFormValue,
|
||||
key: 'sandboxEnabled',
|
||||
value: settings.sandboxEnabled,
|
||||
} }
|
||||
/>
|
||||
<ConnectionInfo
|
||||
connectionStatusDataDefault={
|
||||
connectionStatusDataDefault
|
||||
}
|
||||
/>
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={ () =>
|
||||
updateFormValue( 'sandboxConnected', false )
|
||||
}
|
||||
>
|
||||
{ __(
|
||||
'Disconnect Sandbox',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
</Button>
|
||||
</div>
|
||||
</SettingsBlock>
|
||||
) }
|
||||
{ ! settings.sandboxConnected && (
|
||||
<SettingsBlock
|
||||
title={ __(
|
||||
'Connect Sandbox Account',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
description={ __(
|
||||
'Connect a PayPal Sandbox account in order to test your website. Transactions made will not result in actual money movement. Do not fulfil orders completed in Sandbox mode.',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
style={ SETTINGS_BLOCK_STYLING_TYPE_SECONDARY }
|
||||
actionProps={ {
|
||||
type: SETTINGS_BLOCK_TYPE_EMPTY,
|
||||
callback: updateFormValue,
|
||||
key: 'sandboxAccountCredentials',
|
||||
value: settings.sandboxAccountCredentials,
|
||||
} }
|
||||
>
|
||||
<div className="ppcp-r-settings-block--connect-sandbox ppcp-r-settings-block--expert-rdb">
|
||||
<PayPalRdbWithContent
|
||||
id="sandbox_mode"
|
||||
name="paypal_connect_sandbox"
|
||||
value="sandbox_mode"
|
||||
currentValue={ settings.sandboxMode }
|
||||
toggleAdditionalContent={ true }
|
||||
handleRdbState={ ( newValue ) =>
|
||||
updateFormValue( 'sandboxMode', newValue )
|
||||
}
|
||||
label={ __(
|
||||
'Sandbox Mode',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
description={ __(
|
||||
'Activate Sandbox mode to safely test PayPal with sample data. Once your store is ready to go live, you can easily switch to your production account.',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
>
|
||||
<Button
|
||||
variant="primary"
|
||||
onClick={ () =>
|
||||
updateFormValue( 'sandboxConnected', true )
|
||||
}
|
||||
>
|
||||
{ __(
|
||||
'Connect Sandbox Account',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
</Button>
|
||||
</PayPalRdbWithContent>
|
||||
<PayPalRdbWithContent
|
||||
id="manual_connect"
|
||||
name="paypal_connect_sandbox"
|
||||
value="manual_connect"
|
||||
currentValue={ settings.sandboxMode }
|
||||
toggleAdditionalContent={ true }
|
||||
handleRdbState={ ( newValue ) =>
|
||||
updateFormValue( 'sandboxMode', newValue )
|
||||
}
|
||||
label={ __(
|
||||
'Manual Connect',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
description={ sprintf(
|
||||
// translators: %s: Link to creating PayPal REST application
|
||||
__(
|
||||
'For advanced users: Connect a custom PayPal REST app for full control over your integration. For more information on creating a PayPal REST application, <a target="_blank" href="%s">click here</a>.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
'#'
|
||||
) }
|
||||
>
|
||||
<TextControl
|
||||
className="ppcp-r-vertical-text-control"
|
||||
label={ __(
|
||||
'Sandbox Client ID',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
/>
|
||||
<TextControl
|
||||
className="ppcp-r-vertical-text-control"
|
||||
label={ __(
|
||||
'Sandbox Secrey Key',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
/>
|
||||
<Button variant="primary">
|
||||
{ __(
|
||||
'Connect Account',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
</Button>
|
||||
</PayPalRdbWithContent>
|
||||
</div>
|
||||
</SettingsBlock>
|
||||
) }
|
||||
</SettingsBlock>
|
||||
);
|
||||
};
|
||||
export default Sandbox;
|
|
@ -0,0 +1,75 @@
|
|||
import SettingsBlock, {
|
||||
SETTINGS_BLOCK_STYLING_TYPE_PRIMARY,
|
||||
SETTINGS_BLOCK_STYLING_TYPE_SECONDARY,
|
||||
SETTINGS_BLOCK_TYPE_EMPTY,
|
||||
SETTINGS_BLOCK_TYPE_TOGGLE,
|
||||
} from '../../../../ReusableComponents/SettingsBlock';
|
||||
import { __, sprintf } from '@wordpress/i18n';
|
||||
|
||||
const SavePaymentMethods = ( { updateFormValue, settings } ) => {
|
||||
return (
|
||||
<SettingsBlock
|
||||
className="ppcp-r-settings-block--save-payment-methods"
|
||||
title={ __(
|
||||
'Save Payment Methods',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
description={ sprintf(
|
||||
// translators: first %s: Link to Future payments, second %s: Link to subscriptions
|
||||
__(
|
||||
'Securely store customers payment methods for <a target="_blank" href="%1$s">future payments[MISSING_LINK]</a> and <a target="_blank" href="%2$s">subscriptions[MISSING_LINK]</a>, simplifying checkout and enabling recurring transactions.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
'#',
|
||||
'#'
|
||||
) }
|
||||
type={ SETTINGS_BLOCK_STYLING_TYPE_PRIMARY }
|
||||
style={ SETTINGS_BLOCK_STYLING_TYPE_PRIMARY }
|
||||
actionProps={ {
|
||||
type: SETTINGS_BLOCK_TYPE_EMPTY,
|
||||
} }
|
||||
>
|
||||
<SettingsBlock
|
||||
title={ __(
|
||||
'Save PayPal and Venmo',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
description={ sprintf(
|
||||
// translators: first %s: Link to Pay Later, second %s: Link to Alternative Payment Methods
|
||||
__(
|
||||
'Securely store your customers’ PayPal accounts for a seamless checkout experience. <br />This will disable all <a target="_blank" href="%1$s">Pay Later</a> features and <a target="_blank" href="%2$s">Alternative Payment Methods</a> on your site.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
'https://woocommerce.com/document/woocommerce-paypal-payments/#pay-later',
|
||||
'https://woocommerce.com/document/woocommerce-paypal-payments/#alternative-payment-methods'
|
||||
) }
|
||||
style={ SETTINGS_BLOCK_STYLING_TYPE_SECONDARY }
|
||||
value={ settings.savePaypalAndVenmo }
|
||||
actionProps={ {
|
||||
type: SETTINGS_BLOCK_TYPE_TOGGLE,
|
||||
value: settings.savePaypalAndVenmo,
|
||||
callback: updateFormValue,
|
||||
key: 'savePaypalAndVenmo',
|
||||
} }
|
||||
/>
|
||||
<SettingsBlock
|
||||
title={ __(
|
||||
'Save Credit and Debit Cards',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
description={ __(
|
||||
"Securely store your customer's credit card.",
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
style={ SETTINGS_BLOCK_STYLING_TYPE_SECONDARY }
|
||||
actionProps={ {
|
||||
type: { SETTINGS_BLOCK_TYPE_TOGGLE },
|
||||
callback: updateFormValue,
|
||||
key: 'saveCreditCardAndDebitCard',
|
||||
value: settings.saveCreditCardAndDebitCard,
|
||||
} }
|
||||
/>
|
||||
</SettingsBlock>
|
||||
);
|
||||
};
|
||||
export default SavePaymentMethods;
|
|
@ -0,0 +1,169 @@
|
|||
import SettingsBlock, {
|
||||
SETTINGS_BLOCK_STYLING_TYPE_PRIMARY,
|
||||
SETTINGS_BLOCK_STYLING_TYPE_SECONDARY,
|
||||
SETTINGS_BLOCK_TYPE_BUTTON,
|
||||
SETTINGS_BLOCK_TYPE_EMPTY,
|
||||
SETTINGS_BLOCK_TYPE_TOGGLE,
|
||||
SETTINGS_BLOCK_TYPE_TOGGLE_CONTENT,
|
||||
} from '../../../../ReusableComponents/SettingsBlock';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
|
||||
const Troubleshooting = ( { updateFormValue, settings } ) => {
|
||||
return (
|
||||
<SettingsBlock
|
||||
className="ppcp-r-settings-block--troubleshooting"
|
||||
title={ __( 'Troubleshooting', 'woocommerce-paypal-payments' ) }
|
||||
description={ __(
|
||||
'Access tools to help debug and resolve issues.',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
style={ SETTINGS_BLOCK_STYLING_TYPE_PRIMARY }
|
||||
actionProps={ {
|
||||
type: SETTINGS_BLOCK_TYPE_TOGGLE_CONTENT,
|
||||
callback: updateFormValue,
|
||||
key: 'payNowExperience',
|
||||
value: settings.payNowExperience,
|
||||
} }
|
||||
>
|
||||
<SettingsBlock
|
||||
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'
|
||||
) }
|
||||
style={ SETTINGS_BLOCK_STYLING_TYPE_SECONDARY }
|
||||
actionProps={ {
|
||||
type: SETTINGS_BLOCK_TYPE_TOGGLE,
|
||||
callback: updateFormValue,
|
||||
key: 'logging',
|
||||
value: settings.logging,
|
||||
} }
|
||||
/>
|
||||
<SettingsBlock
|
||||
title={ __(
|
||||
'Subscribed PayPal webhooks',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
description={ __(
|
||||
'The following PayPal webhooks are subscribed. More information about the webhooks is available in the Webhook Status documentation.',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
style={ SETTINGS_BLOCK_STYLING_TYPE_SECONDARY }
|
||||
actionProps={ {
|
||||
type: SETTINGS_BLOCK_TYPE_EMPTY,
|
||||
callback: updateFormValue,
|
||||
key: 'logging',
|
||||
value: settings.logging,
|
||||
} }
|
||||
>
|
||||
<HooksTable data={ hooksExampleData() } />
|
||||
</SettingsBlock>
|
||||
|
||||
<SettingsBlock
|
||||
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'
|
||||
) }
|
||||
style={ SETTINGS_BLOCK_STYLING_TYPE_SECONDARY }
|
||||
actionProps={ {
|
||||
type: SETTINGS_BLOCK_TYPE_BUTTON,
|
||||
buttonType: 'secondary',
|
||||
callback: () =>
|
||||
console.log(
|
||||
'Resubscribe webhooks',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
value: __(
|
||||
'Resubscribe webhooks',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
} }
|
||||
/>
|
||||
<SettingsBlock
|
||||
title={ __(
|
||||
'Simulate webhooks',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
style={ SETTINGS_BLOCK_STYLING_TYPE_SECONDARY }
|
||||
actionProps={ {
|
||||
type: SETTINGS_BLOCK_TYPE_BUTTON,
|
||||
buttonType: 'secondary',
|
||||
callback: () =>
|
||||
console.log(
|
||||
'Simulate webhooks',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
value: __(
|
||||
'Simulate webhooks',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
} }
|
||||
/>
|
||||
</SettingsBlock>
|
||||
);
|
||||
};
|
||||
|
||||
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,67 @@
|
|||
import { __ } from '@wordpress/i18n';
|
||||
import SettingsBlock, {
|
||||
SETTINGS_BLOCK_STYLING_TYPE_PRIMARY,
|
||||
SETTINGS_BLOCK_STYLING_TYPE_SECONDARY,
|
||||
SETTINGS_BLOCK_TYPE_INPUT,
|
||||
SETTINGS_BLOCK_TYPE_TOGGLE,
|
||||
} from '../../../ReusableComponents/SettingsBlock';
|
||||
import SettingsCard from '../../../ReusableComponents/SettingsCard';
|
||||
import OrderIntent from './Blocks/OrderIntent';
|
||||
import SavePaymentMethods from './Blocks/SavePaymentMethods';
|
||||
|
||||
const CommonSettings = ( { updateFormValue, settings } ) => {
|
||||
return (
|
||||
<SettingsCard
|
||||
icon="icon-settings-common.svg"
|
||||
title={ __( 'Common Settings', 'woocommerce-paypal-payments' ) }
|
||||
className="ppcp-r-settings-card ppcp-r-settings-card--common-settings"
|
||||
description={ __(
|
||||
'Customize key features to tailor your PayPal experience.',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
>
|
||||
<SettingsBlock
|
||||
title="Invoice Prefix"
|
||||
description="Add a unique prefix to invoice numbers for site-specific tracking (recommended)."
|
||||
style={ SETTINGS_BLOCK_STYLING_TYPE_PRIMARY }
|
||||
actionProps={ {
|
||||
type: SETTINGS_BLOCK_TYPE_INPUT,
|
||||
callback: updateFormValue,
|
||||
key: 'invoicePrefix',
|
||||
value: settings.invoicePrefix,
|
||||
placeholder: __(
|
||||
'Input prefix',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
} }
|
||||
/>
|
||||
<OrderIntent
|
||||
settings={ settings }
|
||||
updateFormValue={ updateFormValue }
|
||||
/>
|
||||
<SavePaymentMethods
|
||||
updateFormValue={ updateFormValue }
|
||||
settings={ settings }
|
||||
/>
|
||||
<SettingsBlock
|
||||
title={ __(
|
||||
'Pay Now Experience',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
description={ __(
|
||||
'Let PayPal customers skip the Order Review page by selecting shipping options directly within PayPal.',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
style={ SETTINGS_BLOCK_STYLING_TYPE_SECONDARY }
|
||||
actionProps={ {
|
||||
type: SETTINGS_BLOCK_TYPE_TOGGLE,
|
||||
callback: updateFormValue,
|
||||
key: 'payNowExperience',
|
||||
value: settings.payNowExperience,
|
||||
} }
|
||||
/>
|
||||
</SettingsCard>
|
||||
);
|
||||
};
|
||||
|
||||
export default CommonSettings;
|
|
@ -0,0 +1,51 @@
|
|||
import { __ } from '@wordpress/i18n';
|
||||
import SettingsBlock, {
|
||||
SETTINGS_BLOCK_STYLING_TYPE_PRIMARY,
|
||||
SETTINGS_BLOCK_STYLING_TYPE_SECONDARY,
|
||||
SETTINGS_BLOCK_TYPE_SELECT,
|
||||
SETTINGS_BLOCK_TYPE_TOGGLE_CONTENT,
|
||||
} from '../../../ReusableComponents/SettingsBlock';
|
||||
import SettingsCard from '../../../ReusableComponents/SettingsCard';
|
||||
import Sandbox from './Blocks/Sandbox';
|
||||
import Troubleshooting from './Blocks/Troubleshooting';
|
||||
import PaypalSettings from './Blocks/PaypalSettings';
|
||||
import OtherSettings from './Blocks/OtherSettings';
|
||||
|
||||
const ExpertSettings = ( { updateFormValue, settings } ) => {
|
||||
return (
|
||||
<SettingsCard
|
||||
icon="icon-settings-expert.svg"
|
||||
className="ppcp-r-settings-card ppcp-r-settings-card--expert-settings"
|
||||
title={ __( 'Expert Settings', 'woocommerce-paypal-payments' ) }
|
||||
description={ __(
|
||||
'Fine-tune your PayPal experience with advanced options.',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
actionProps={ {
|
||||
callback: updateFormValue,
|
||||
key: 'payNowExperience',
|
||||
} }
|
||||
>
|
||||
<Sandbox
|
||||
updateFormValue={ updateFormValue }
|
||||
settings={ settings }
|
||||
/>
|
||||
|
||||
<Troubleshooting
|
||||
updateFormValue={ updateFormValue }
|
||||
settings={ settings }
|
||||
/>
|
||||
|
||||
<PaypalSettings
|
||||
updateFormValue={ updateFormValue }
|
||||
settings={ settings }
|
||||
/>
|
||||
<OtherSettings
|
||||
updateFormValue={ updateFormValue }
|
||||
settings={ settings }
|
||||
/>
|
||||
</SettingsCard>
|
||||
);
|
||||
};
|
||||
|
||||
export default ExpertSettings;
|
|
@ -48,7 +48,9 @@ const StepCompleteSetup = ( {
|
|||
<Button
|
||||
variant="primary"
|
||||
icon={ ButtonIcon }
|
||||
onClick={ () => {} }
|
||||
onClick={ () => {
|
||||
setCompleted( true );
|
||||
} }
|
||||
>
|
||||
{ __(
|
||||
'Connect to PayPal',
|
||||
|
|
|
@ -44,11 +44,11 @@ const StepWelcome = ( { setStep, currentStep, setCompleted } ) => {
|
|||
</div>
|
||||
<Separator className="ppcp-r-page-welcome-mode-separator" />
|
||||
<WelcomeDocs
|
||||
useAcdc = { true }
|
||||
isFastlane = { true }
|
||||
isPayLater = { true }
|
||||
storeCountry = { 'us' }
|
||||
storeCurrency = { 'usd' }
|
||||
useAcdc={ true }
|
||||
isFastlane={ true }
|
||||
isPayLater={ true }
|
||||
storeCountry={ 'us' }
|
||||
storeCurrency={ 'usd' }
|
||||
/>
|
||||
<Separator text={ __( 'or', 'woocommerce-paypal-payments' ) } />
|
||||
<AccordionSection
|
||||
|
@ -95,219 +95,4 @@ const WelcomeFeatures = () => {
|
|||
</div>
|
||||
);
|
||||
};
|
||||
const WelcomeDocs = () => {
|
||||
const pricesBasedDescription = sprintf(
|
||||
// translators: %s: Link to PayPal REST application guide
|
||||
__(
|
||||
'<sup>1</sup>Prices based on domestic transactions as of October 25th, 2024. <a target="_blank" href="%s">Click here</a> for full pricing details.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
'https://woocommerce.com/document/woocommerce-paypal-payments/#manual-credential-input '
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="ppcp-r-welcome-docs">
|
||||
<h2 className="ppcp-r-welcome-docs__title">
|
||||
{ __(
|
||||
`Want to know more about PayPal Payments?`,
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
</h2>
|
||||
<div className="ppcp-r-welcome-docs__wrapper">
|
||||
<div className="ppcp-r-welcome-docs__col">
|
||||
<BadgeBox
|
||||
title={ __(
|
||||
'PayPal Checkout',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
titleType={ BADGE_BOX_TITLE_BIG }
|
||||
textBadge={ __(
|
||||
'from 3.49% + $0.49 USD<sup>1</sup>',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
description={ __(
|
||||
'Our all-in-one checkout solution lets you offer PayPal, Venmo, Pay Later options, and more to help maximise conversion',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
/>
|
||||
<BadgeBox
|
||||
title={ __(
|
||||
'Included in PayPal Checkout',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
titleType={ BADGE_BOX_TITLE_BIG }
|
||||
/>
|
||||
<BadgeBox
|
||||
title={ __(
|
||||
'Pay with PayPal',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
imageBadge={ [ 'icon-button-paypal.svg' ] }
|
||||
description={ sprintf(
|
||||
// translators: %s: Link to PayPal REST application guide
|
||||
__(
|
||||
'Our brand recognition helps give customers the confidence to buy. <a target="_blank" href="%s">Learn more</a>',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
'https://woocommerce.com/document/woocommerce-paypal-payments/#manual-credential-input '
|
||||
) }
|
||||
/>
|
||||
<Separator className="ppcp-r-page-welcome-mode-separator" />
|
||||
<BadgeBox
|
||||
title={ __(
|
||||
'Pay Later',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
imageBadge={ [
|
||||
'icon-payment-method-paypal-small.svg',
|
||||
] }
|
||||
description={ sprintf(
|
||||
// translators: %s: Link to PayPal REST application guide
|
||||
__(
|
||||
'Offer installment payment options and get paid upfront - at no extra cost to you. <a target="_blank" href="%s">Learn more</a>',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
'https://woocommerce.com/document/woocommerce-paypal-payments/#manual-credential-input '
|
||||
) }
|
||||
/>
|
||||
<Separator className="ppcp-r-page-welcome-mode-separator" />
|
||||
<BadgeBox
|
||||
title={ __( 'Venmo', 'woocommerce-paypal-payments' ) }
|
||||
imageBadge={ [ 'icon-button-venmo.svg' ] }
|
||||
description={ sprintf(
|
||||
// translators: %s: Link to PayPal REST application guide
|
||||
__(
|
||||
'Automatically offer Venmo checkout to millions of active users. <a target="_blank" href="%s">Learn more</a>',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
'https://woocommerce.com/document/woocommerce-paypal-payments/#manual-credential-input '
|
||||
) }
|
||||
/>
|
||||
<Separator className="ppcp-r-page-welcome-mode-separator" />
|
||||
<BadgeBox
|
||||
title={ __( 'Crypto', 'woocommerce-paypal-payments' ) }
|
||||
imageBadge={ [ 'icon-payment-method-crypto.svg' ] }
|
||||
description={ sprintf(
|
||||
// translators: %s: Link to PayPal REST application guide
|
||||
__(
|
||||
'Let customers checkout with Crypto while you get paid in cash. <a target="_blank" href="%s">Learn more</a>',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
'https://woocommerce.com/document/woocommerce-paypal-payments/#manual-credential-input '
|
||||
) }
|
||||
/>
|
||||
</div>
|
||||
<div className="ppcp-r-welcome-docs__col">
|
||||
<BadgeBox
|
||||
title={ __(
|
||||
'Optional payment methods',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
titleType={ BADGE_BOX_TITLE_BIG }
|
||||
description={ __(
|
||||
'with additional application',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
/>
|
||||
<BadgeBox
|
||||
title={ __(
|
||||
'Custom Card Fields',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
imageBadge={ [
|
||||
'icon-button-visa.svg',
|
||||
'icon-button-mastercard.svg',
|
||||
'icon-button-amex.svg',
|
||||
'icon-button-discover.svg',
|
||||
] }
|
||||
textBadge={ __(
|
||||
'from 2.59% + $0.49 USD<sup>1</sup>',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
description={ sprintf(
|
||||
// translators: %s: Link to PayPal REST application guide
|
||||
__(
|
||||
'Style the credit card fields to match your own style. Includes advanced processing with risk management, 3D Secure, fraud protection options, and chargeback protection. <a target="_blank" href="%s">Learn more</a>',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
'https://woocommerce.com/document/woocommerce-paypal-payments/#manual-credential-input '
|
||||
) }
|
||||
/>
|
||||
<Separator className="ppcp-r-page-welcome-mode-separator" />
|
||||
<BadgeBox
|
||||
title={ __(
|
||||
'Digital Wallets',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
imageBadge={ [
|
||||
'icon-button-apple-pay.svg',
|
||||
'icon-button-google-pay.svg',
|
||||
] }
|
||||
textBadge={ __(
|
||||
'from 2.59% + $0.49 USD<sup>1</sup>',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
description={ sprintf(
|
||||
// translators: %s: Link to PayPal REST application guide
|
||||
__(
|
||||
'Accept Apple Pay on eligible devices and Google Pay through mobile and web. <a target="_blank" href="%s">Learn more</a>',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
'https://woocommerce.com/document/woocommerce-paypal-payments/#manual-credential-input '
|
||||
) }
|
||||
/>
|
||||
<Separator className="ppcp-r-page-welcome-mode-separator" />
|
||||
<BadgeBox
|
||||
title={ __(
|
||||
'Alternative Payment Methods',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
imageBadge={ [
|
||||
'icon-button-sepa.svg',
|
||||
'icon-button-ideal.svg',
|
||||
'icon-button-blik.svg',
|
||||
'icon-button-bancontact.svg',
|
||||
] }
|
||||
textBadge={ __(
|
||||
'from 3.49% + $0.49 USD<sup>1</sup>',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
description={ sprintf(
|
||||
// translators: %s: Link to PayPal REST application guide
|
||||
__(
|
||||
'Seamless payments for customers across the globe using their preferred payment methods. <a target="_blank" href="%s">Learn more</a>',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
'https://woocommerce.com/document/woocommerce-paypal-payments/#manual-credential-input '
|
||||
) }
|
||||
/>
|
||||
<Separator className="ppcp-r-page-welcome-mode-separator" />
|
||||
<BadgeBox
|
||||
title={ __( '', 'woocommerce-paypal-payments' ) }
|
||||
imageBadge={ [
|
||||
'icon-payment-method-fastlane-small.svg',
|
||||
] }
|
||||
textBadge={ __(
|
||||
'from 2.59% + $0.49 USD<sup>1</sup>',
|
||||
'woocommerce-paypal-payments'
|
||||
) }
|
||||
description={ sprintf(
|
||||
// translators: %s: Link to PayPal REST application guide
|
||||
__(
|
||||
'Speed up guest checkout with Fatslane. Link a customer\'s email address to their payment details. <a target="_blank" href="%s">Learn more</a>',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
'https://woocommerce.com/document/woocommerce-paypal-payments/#manual-credential-input '
|
||||
) }
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<p
|
||||
className="ppcp-r-welcome-docs__description"
|
||||
dangerouslySetInnerHTML={ { __html: pricesBasedDescription } }
|
||||
></p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default StepWelcome;
|
||||
|
|
|
@ -1132,7 +1132,7 @@
|
|||
dependencies:
|
||||
regenerator-runtime "^0.14.0"
|
||||
|
||||
"@babel/runtime@^7.12.5", "@babel/runtime@^7.14.8", "@babel/runtime@^7.16.0", "@babel/runtime@^7.18.3", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
|
||||
"@babel/runtime@^7.12.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.8", "@babel/runtime@^7.16.0", "@babel/runtime@^7.18.3", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
|
||||
version "7.26.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.0.tgz#8600c2f595f277c60815256418b85356a65173c1"
|
||||
integrity sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==
|
||||
|
@ -1221,7 +1221,7 @@
|
|||
source-map "^0.5.7"
|
||||
stylis "4.2.0"
|
||||
|
||||
"@emotion/cache@^11.13.0", "@emotion/cache@^11.7.1":
|
||||
"@emotion/cache@^11.13.0", "@emotion/cache@^11.4.0", "@emotion/cache@^11.7.1":
|
||||
version "11.13.1"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.13.1.tgz#fecfc54d51810beebf05bf2a161271a1a91895d7"
|
||||
integrity sha512-iqouYkuEblRcXmylXIwwOodiEK5Ifl7JcX7o6V4jI3iW4mLXX3dmt5xwBtIkJiQEXFAI+pC8X0i67yiPkH9Ucw==
|
||||
|
@ -1272,7 +1272,7 @@
|
|||
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.9.0.tgz#745969d649977776b43fc7648c556aaa462b4102"
|
||||
integrity sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==
|
||||
|
||||
"@emotion/react@^11.7.1":
|
||||
"@emotion/react@^11.7.1", "@emotion/react@^11.8.1":
|
||||
version "11.13.3"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.13.3.tgz#a69d0de2a23f5b48e0acf210416638010e4bd2e4"
|
||||
integrity sha512-lIsdU6JNrmYfJ5EbUCf4xW1ovy5wKQ2CkPRM4xogziOxH1nXxBSjpC9YqbFAP7circxMfYp+6x676BqWcEiixg==
|
||||
|
@ -1385,6 +1385,13 @@
|
|||
resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-0.6.2.tgz#f2813f0e5f3d5ed7af5029e1a082203dadf02b7d"
|
||||
integrity sha512-jktYRmZwmau63adUG3GKOAVCofBXkk55S/zQ94XOorAHhwqFIOFAy1rSp2N0Wp6/tGbe9V3u/ExlGZypyY17rg==
|
||||
|
||||
"@floating-ui/core@^1.6.0":
|
||||
version "1.6.8"
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.6.8.tgz#aa43561be075815879305965020f492cdb43da12"
|
||||
integrity sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==
|
||||
dependencies:
|
||||
"@floating-ui/utils" "^0.2.8"
|
||||
|
||||
"@floating-ui/dom@^0.4.5":
|
||||
version "0.4.5"
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-0.4.5.tgz#2e88d16646119cc67d44683f75ee99840475bbfa"
|
||||
|
@ -1392,6 +1399,14 @@
|
|||
dependencies:
|
||||
"@floating-ui/core" "^0.6.2"
|
||||
|
||||
"@floating-ui/dom@^1.0.1":
|
||||
version "1.6.12"
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.6.12.tgz#6333dcb5a8ead3b2bf82f33d6bc410e95f54e556"
|
||||
integrity sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w==
|
||||
dependencies:
|
||||
"@floating-ui/core" "^1.6.0"
|
||||
"@floating-ui/utils" "^0.2.8"
|
||||
|
||||
"@floating-ui/react-dom@0.6.3":
|
||||
version "0.6.3"
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-0.6.3.tgz#7b64cfd4fd12e4a0515dbf1b2be16e48c9a06c5a"
|
||||
|
@ -1400,6 +1415,11 @@
|
|||
"@floating-ui/dom" "^0.4.5"
|
||||
use-isomorphic-layout-effect "^1.1.1"
|
||||
|
||||
"@floating-ui/utils@^0.2.8":
|
||||
version "0.2.8"
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.8.tgz#21a907684723bbbaa5f0974cf7730bd797eb8e62"
|
||||
integrity sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==
|
||||
|
||||
"@hapi/hoek@^9.0.0", "@hapi/hoek@^9.3.0":
|
||||
version "9.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.3.0.tgz#8368869dcb735be2e7f5cb7647de78e167a251fb"
|
||||
|
@ -2428,6 +2448,13 @@
|
|||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-transition-group@^4.4.0":
|
||||
version "4.4.11"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.11.tgz#d963253a611d757de01ebb241143b1017d5d63d5"
|
||||
integrity sha512-RM05tAniPZ5DZPzzNFP+DmrcOdD0efDUxMy3145oljWSl3x9ZV5vhme98gTxFrj2lhXvmGNnUiuDyJgY9IKkNA==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react@*", "@types/react@^18.2.79":
|
||||
version "18.3.12"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.12.tgz#99419f182ccd69151813b7ee24b792fe08774f60"
|
||||
|
@ -5209,6 +5236,14 @@ document.contains@^1.0.1:
|
|||
dependencies:
|
||||
define-properties "^1.1.3"
|
||||
|
||||
dom-helpers@^5.0.1:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902"
|
||||
integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.8.7"
|
||||
csstype "^3.0.2"
|
||||
|
||||
dom-scroll-into-view@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/dom-scroll-into-view/-/dom-scroll-into-view-1.2.1.tgz#e8f36732dd089b0201a88d7815dc3f88e6d66c7e"
|
||||
|
@ -8223,6 +8258,11 @@ memize@^2.1.0:
|
|||
resolved "https://registry.yarnpkg.com/memize/-/memize-2.1.0.tgz#6ddd4717887d94825748149ece00d04cf868ce0d"
|
||||
integrity sha512-yywVJy8ctVlN5lNPxsep5urnZ6TTclwPEyigM9M3Bi8vseJBOfqNrGWN/r8NzuIt3PovM323W04blJfGQfQSVg==
|
||||
|
||||
memoize-one@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-6.0.0.tgz#b2591b871ed82948aee4727dc6abceeeac8c1045"
|
||||
integrity sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==
|
||||
|
||||
meow@^13.2.0:
|
||||
version "13.2.0"
|
||||
resolved "https://registry.yarnpkg.com/meow/-/meow-13.2.0.tgz#6b7d63f913f984063b3cc261b6e8800c4cd3474f"
|
||||
|
@ -9345,7 +9385,7 @@ prop-types-exact@^1.2.0:
|
|||
object.assign "^4.1.5"
|
||||
reflect.ownkeys "^1.1.4"
|
||||
|
||||
prop-types@^15.5.8, prop-types@^15.7.2, prop-types@^15.8.1:
|
||||
prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
|
||||
version "15.8.1"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
|
||||
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
|
||||
|
@ -9603,6 +9643,31 @@ react-refresh@^0.14.0:
|
|||
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.2.tgz#3833da01ce32da470f1f936b9d477da5c7028bf9"
|
||||
integrity sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==
|
||||
|
||||
react-select@^5.8.3:
|
||||
version "5.8.3"
|
||||
resolved "https://registry.yarnpkg.com/react-select/-/react-select-5.8.3.tgz#64e89ad20a846348b18c6fbb395b939d0153ed74"
|
||||
integrity sha512-lVswnIq8/iTj1db7XCG74M/3fbGB6ZaluCzvwPGT5ZOjCdL/k0CLWhEK0vCBLuU5bHTEf6Gj8jtSvi+3v+tO1w==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.12.0"
|
||||
"@emotion/cache" "^11.4.0"
|
||||
"@emotion/react" "^11.8.1"
|
||||
"@floating-ui/dom" "^1.0.1"
|
||||
"@types/react-transition-group" "^4.4.0"
|
||||
memoize-one "^6.0.0"
|
||||
prop-types "^15.6.0"
|
||||
react-transition-group "^4.3.0"
|
||||
use-isomorphic-layout-effect "^1.1.2"
|
||||
|
||||
react-transition-group@^4.3.0:
|
||||
version "4.4.5"
|
||||
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.5.tgz#e53d4e3f3344da8521489fbef8f2581d42becdd1"
|
||||
integrity sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.5.5"
|
||||
dom-helpers "^5.0.1"
|
||||
loose-envify "^1.4.0"
|
||||
prop-types "^15.6.2"
|
||||
|
||||
react-with-direction@^1.3.1:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/react-with-direction/-/react-with-direction-1.4.0.tgz#ebdf64d685d0650ce966e872e6431ad5a2485444"
|
||||
|
@ -11279,7 +11344,7 @@ urlpattern-polyfill@10.0.0:
|
|||
resolved "https://registry.yarnpkg.com/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz#f0a03a97bfb03cdf33553e5e79a2aadd22cac8ec"
|
||||
integrity sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==
|
||||
|
||||
use-isomorphic-layout-effect@^1.1.1:
|
||||
use-isomorphic-layout-effect@^1.1.1, use-isomorphic-layout-effect@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz#497cefb13d863d687b08477d9e5a164ad8c1a6fb"
|
||||
integrity sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue