mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-08-30 05:00:51 +08:00
Add ButtonOptions support for the Google Pay button
This commit is contained in:
parent
7832f853ff
commit
b117ff9b7c
9 changed files with 305 additions and 93 deletions
|
@ -170,6 +170,11 @@ export default class PaymentButton {
|
||||||
*/
|
*/
|
||||||
#contextHandler;
|
#contextHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Button attributes.
|
||||||
|
*/
|
||||||
|
#buttonAttributes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the current browser/website support the payment method.
|
* Whether the current browser/website support the payment method.
|
||||||
*
|
*
|
||||||
|
@ -195,11 +200,12 @@ export default class PaymentButton {
|
||||||
/**
|
/**
|
||||||
* Factory method to create a new PaymentButton while limiting a single instance per context.
|
* Factory method to create a new PaymentButton while limiting a single instance per context.
|
||||||
*
|
*
|
||||||
* @param {string} context - Button context name.
|
* @param {string} context - Button context name.
|
||||||
* @param {unknown} externalHandler - Handler object.
|
* @param {unknown} externalHandler - Handler object.
|
||||||
* @param {Object} buttonConfig - Payment button specific configuration.
|
* @param {Object} buttonConfig - Payment button specific configuration.
|
||||||
* @param {Object} ppcpConfig - Plugin wide configuration object.
|
* @param {Object} ppcpConfig - Plugin wide configuration object.
|
||||||
* @param {unknown} contextHandler - Handler object.
|
* @param {unknown} contextHandler - Handler object.
|
||||||
|
* @param {Object} buttonAttributes - Button attributes.
|
||||||
* @return {PaymentButton} The button instance.
|
* @return {PaymentButton} The button instance.
|
||||||
*/
|
*/
|
||||||
static createButton(
|
static createButton(
|
||||||
|
@ -207,7 +213,8 @@ export default class PaymentButton {
|
||||||
externalHandler,
|
externalHandler,
|
||||||
buttonConfig,
|
buttonConfig,
|
||||||
ppcpConfig,
|
ppcpConfig,
|
||||||
contextHandler
|
contextHandler,
|
||||||
|
buttonAttributes
|
||||||
) {
|
) {
|
||||||
const buttonInstances = getInstances();
|
const buttonInstances = getInstances();
|
||||||
const instanceKey = `${ this.methodId }.${ context }`;
|
const instanceKey = `${ this.methodId }.${ context }`;
|
||||||
|
@ -218,7 +225,8 @@ export default class PaymentButton {
|
||||||
externalHandler,
|
externalHandler,
|
||||||
buttonConfig,
|
buttonConfig,
|
||||||
ppcpConfig,
|
ppcpConfig,
|
||||||
contextHandler
|
contextHandler,
|
||||||
|
buttonAttributes
|
||||||
);
|
);
|
||||||
|
|
||||||
buttonInstances.set( instanceKey, button );
|
buttonInstances.set( instanceKey, button );
|
||||||
|
@ -262,18 +270,20 @@ export default class PaymentButton {
|
||||||
* to avoid multiple button instances handling the same context.
|
* to avoid multiple button instances handling the same context.
|
||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
* @param {string} context - Button context name.
|
* @param {string} context - Button context name.
|
||||||
* @param {Object} externalHandler - Handler object.
|
* @param {Object} externalHandler - Handler object.
|
||||||
* @param {Object} buttonConfig - Payment button specific configuration.
|
* @param {Object} buttonConfig - Payment button specific configuration.
|
||||||
* @param {Object} ppcpConfig - Plugin wide configuration object.
|
* @param {Object} ppcpConfig - Plugin wide configuration object.
|
||||||
* @param {Object} contextHandler - Handler object.
|
* @param {Object} contextHandler - Handler object.
|
||||||
|
* @param {Object} buttonAttributes - Button attributes.
|
||||||
*/
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
context,
|
context,
|
||||||
externalHandler = null,
|
externalHandler = null,
|
||||||
buttonConfig = {},
|
buttonConfig = {},
|
||||||
ppcpConfig = {},
|
ppcpConfig = {},
|
||||||
contextHandler = null
|
contextHandler = null,
|
||||||
|
buttonAttributes = {}
|
||||||
) {
|
) {
|
||||||
if ( this.methodId === PaymentButton.methodId ) {
|
if ( this.methodId === PaymentButton.methodId ) {
|
||||||
throw new Error( 'Cannot initialize the PaymentButton base class' );
|
throw new Error( 'Cannot initialize the PaymentButton base class' );
|
||||||
|
@ -291,6 +301,7 @@ export default class PaymentButton {
|
||||||
this.#ppcpConfig = ppcpConfig;
|
this.#ppcpConfig = ppcpConfig;
|
||||||
this.#externalHandler = externalHandler;
|
this.#externalHandler = externalHandler;
|
||||||
this.#contextHandler = contextHandler;
|
this.#contextHandler = contextHandler;
|
||||||
|
this.#buttonAttributes = buttonAttributes;
|
||||||
|
|
||||||
this.#logger = new ConsoleLogger( methodName, context );
|
this.#logger = new ConsoleLogger( methodName, context );
|
||||||
|
|
||||||
|
@ -763,15 +774,20 @@ export default class PaymentButton {
|
||||||
|
|
||||||
const styleSelector = `style[data-hide-gateway="${ this.methodId }"]`;
|
const styleSelector = `style[data-hide-gateway="${ this.methodId }"]`;
|
||||||
const wrapperSelector = `#${ this.wrappers.Default }`;
|
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
|
document
|
||||||
.querySelectorAll( styleSelector )
|
.querySelectorAll( styleSelector )
|
||||||
.forEach( ( el ) => el.remove() );
|
.forEach( ( el ) => el.remove() );
|
||||||
|
|
||||||
if (paymentMethodLi.style.display === 'none' || paymentMethodLi.style.display === '') {
|
if (
|
||||||
paymentMethodLi.style.display = 'block';
|
paymentMethodLi.style.display === 'none' ||
|
||||||
}
|
paymentMethodLi.style.display === ''
|
||||||
|
) {
|
||||||
|
paymentMethodLi.style.display = 'block';
|
||||||
|
}
|
||||||
|
|
||||||
document
|
document
|
||||||
.querySelectorAll( wrapperSelector )
|
.querySelectorAll( wrapperSelector )
|
||||||
|
@ -843,7 +859,7 @@ export default class PaymentButton {
|
||||||
this.removeButton();
|
this.removeButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.log( 'addButton', button );
|
this.log( 'insertButton', button );
|
||||||
|
|
||||||
this.#button = button;
|
this.#button = button;
|
||||||
wrapper.appendChild( this.#button );
|
wrapper.appendChild( this.#button );
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
/* Front end display */
|
/* Front end display */
|
||||||
.ppcp-button-apm .gpay-card-info-container-fill .gpay-card-info-container {
|
.ppcp-button-apm .gpay-card-info-container-fill .gpay-card-info-container {
|
||||||
outline-offset: -1px;
|
outline-offset: -1px;
|
||||||
border-radius: var(--apm-button-border-radius);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Admin preview */
|
/* Admin preview */
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
import { useState, useEffect } from '@wordpress/element';
|
import { useState } from '@wordpress/element';
|
||||||
import useGooglepayApiToGenerateButton from '../hooks/useGooglepayApiToGenerateButton';
|
import useGooglepayApiToGenerateButton from '../hooks/useGooglepayApiToGenerateButton';
|
||||||
import usePayPalScript from '../hooks/usePayPalScript';
|
import usePayPalScript from '../hooks/usePayPalScript';
|
||||||
import useGooglepayScript from '../hooks/useGooglepayScript';
|
import useGooglepayScript from '../hooks/useGooglepayScript';
|
||||||
import useGooglepayConfig from '../hooks/useGooglepayConfig';
|
import useGooglepayConfig from '../hooks/useGooglepayConfig';
|
||||||
|
|
||||||
const GooglepayButton = ( { namespace, buttonConfig, ppcpConfig } ) => {
|
const GooglepayButton = ( {
|
||||||
const [ buttonHtml, setButtonHtml ] = useState( '' );
|
namespace,
|
||||||
const [ buttonElement, setButtonElement ] = useState( null );
|
buttonConfig,
|
||||||
|
ppcpConfig,
|
||||||
|
buttonAttributes,
|
||||||
|
} ) => {
|
||||||
const [ componentFrame, setComponentFrame ] = useState( null );
|
const [ componentFrame, setComponentFrame ] = useState( null );
|
||||||
const isPayPalLoaded = usePayPalScript( namespace, ppcpConfig );
|
const isPayPalLoaded = usePayPalScript( namespace, ppcpConfig );
|
||||||
|
|
||||||
|
@ -18,35 +21,45 @@ const GooglepayButton = ( { namespace, buttonConfig, ppcpConfig } ) => {
|
||||||
|
|
||||||
const googlepayConfig = useGooglepayConfig( namespace, isGooglepayLoaded );
|
const googlepayConfig = useGooglepayConfig( namespace, isGooglepayLoaded );
|
||||||
|
|
||||||
useEffect( () => {
|
const { button, containerStyles } = useGooglepayApiToGenerateButton(
|
||||||
if ( ! buttonElement ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setComponentFrame( buttonElement.ownerDocument );
|
|
||||||
}, [ buttonElement ] );
|
|
||||||
|
|
||||||
const googlepayButton = useGooglepayApiToGenerateButton(
|
|
||||||
componentFrame,
|
componentFrame,
|
||||||
namespace,
|
namespace,
|
||||||
buttonConfig,
|
buttonConfig,
|
||||||
ppcpConfig,
|
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 (
|
return (
|
||||||
<div
|
<>
|
||||||
ref={ setButtonElement }
|
<div
|
||||||
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 { useMemo } from '@wordpress/element';
|
||||||
import { combineStyles } from '../../../../../ppcp-button/resources/js/modules/Helper/PaymentButtonHelpers';
|
import { combineStyles } from '../../../../../ppcp-button/resources/js/modules/Helper/PaymentButtonHelpers';
|
||||||
|
|
||||||
const useButtonStyles = ( buttonConfig, ppcpConfig ) => {
|
const useButtonStyles = ( buttonConfig, ppcpConfig, buttonAttributes ) => {
|
||||||
return useMemo( () => {
|
return useMemo( () => {
|
||||||
const styles = combineStyles(
|
const styles = combineStyles(
|
||||||
ppcpConfig?.button || {},
|
ppcpConfig?.button || {},
|
||||||
buttonConfig?.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';
|
styles.MiniCart.type = 'pay';
|
||||||
}
|
}
|
||||||
|
|
||||||
return styles;
|
return styles;
|
||||||
}, [ buttonConfig, ppcpConfig ] );
|
}, [ buttonConfig, ppcpConfig, buttonAttributes ] );
|
||||||
};
|
};
|
||||||
|
|
||||||
export default useButtonStyles;
|
export default useButtonStyles;
|
||||||
|
|
|
@ -6,10 +6,16 @@ const useGooglepayApiToGenerateButton = (
|
||||||
namespace,
|
namespace,
|
||||||
buttonConfig,
|
buttonConfig,
|
||||||
ppcpConfig,
|
ppcpConfig,
|
||||||
googlepayConfig
|
googlepayConfig,
|
||||||
|
buttonAttributes
|
||||||
) => {
|
) => {
|
||||||
const [ googlepayButton, setGooglepayButton ] = useState( null );
|
const [ googlepayButton, setGooglepayButton ] = useState( null );
|
||||||
const buttonStyles = useButtonStyles( buttonConfig, ppcpConfig );
|
|
||||||
|
const buttonStyles = useButtonStyles(
|
||||||
|
buttonConfig,
|
||||||
|
ppcpConfig,
|
||||||
|
buttonAttributes
|
||||||
|
);
|
||||||
|
|
||||||
useEffect( () => {
|
useEffect( () => {
|
||||||
if (
|
if (
|
||||||
|
@ -35,14 +41,13 @@ const useGooglepayApiToGenerateButton = (
|
||||||
buttonType: buttonConfig.buttonType || 'pay',
|
buttonType: buttonConfig.buttonType || 'pay',
|
||||||
buttonLocale: buttonConfig.buttonLocale || 'en',
|
buttonLocale: buttonConfig.buttonLocale || 'en',
|
||||||
buttonSizeMode: 'fill',
|
buttonSizeMode: 'fill',
|
||||||
};
|
buttonRadius: parseInt( buttonStyles?.Default?.borderRadius ),
|
||||||
|
|
||||||
const button = paymentsClient.createButton( {
|
|
||||||
...googlePayButtonOptions,
|
|
||||||
onClick: ( event ) => {
|
onClick: ( event ) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
},
|
},
|
||||||
} );
|
};
|
||||||
|
|
||||||
|
const button = paymentsClient.createButton( googlePayButtonOptions );
|
||||||
|
|
||||||
setGooglepayButton( button );
|
setGooglepayButton( button );
|
||||||
|
|
||||||
|
@ -51,7 +56,15 @@ const useGooglepayApiToGenerateButton = (
|
||||||
};
|
};
|
||||||
}, [ namespace, buttonConfig, ppcpConfig, googlepayConfig, buttonStyles ] );
|
}, [ 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;
|
export default useGooglepayApiToGenerateButton;
|
||||||
|
|
|
@ -106,8 +106,40 @@ class GooglepayButton extends PaymentButton {
|
||||||
*/
|
*/
|
||||||
#transactionInfo = null;
|
#transactionInfo = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The currently visible payment button.
|
||||||
|
*
|
||||||
|
* @type {HTMLElement|null}
|
||||||
|
*/
|
||||||
|
#button = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Google Pay configuration object.
|
||||||
|
*
|
||||||
|
* @type {Object|null}
|
||||||
|
*/
|
||||||
googlePayConfig = 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
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
|
@ -142,7 +174,8 @@ class GooglepayButton extends PaymentButton {
|
||||||
externalHandler,
|
externalHandler,
|
||||||
buttonConfig,
|
buttonConfig,
|
||||||
ppcpConfig,
|
ppcpConfig,
|
||||||
contextHandler
|
contextHandler,
|
||||||
|
buttonAttributes
|
||||||
) {
|
) {
|
||||||
// Disable debug output in the browser console:
|
// Disable debug output in the browser console:
|
||||||
// buttonConfig.is_debug = false;
|
// buttonConfig.is_debug = false;
|
||||||
|
@ -152,7 +185,8 @@ class GooglepayButton extends PaymentButton {
|
||||||
externalHandler,
|
externalHandler,
|
||||||
buttonConfig,
|
buttonConfig,
|
||||||
ppcpConfig,
|
ppcpConfig,
|
||||||
contextHandler
|
contextHandler,
|
||||||
|
buttonAttributes
|
||||||
);
|
);
|
||||||
|
|
||||||
this.init = this.init.bind( this );
|
this.init = this.init.bind( this );
|
||||||
|
@ -249,6 +283,22 @@ class GooglepayButton extends PaymentButton {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add buttonAttributes validation
|
||||||
|
if ( this.buttonAttributes ) {
|
||||||
|
if (
|
||||||
|
this.buttonAttributes.height &&
|
||||||
|
isNaN( parseInt( this.buttonAttributes.height ) )
|
||||||
|
) {
|
||||||
|
return isInvalid( 'Invalid height in buttonAttributes' );
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
this.buttonAttributes.borderRadius &&
|
||||||
|
isNaN( parseInt( this.buttonAttributes.borderRadius ) )
|
||||||
|
) {
|
||||||
|
return isInvalid( 'Invalid borderRadius in buttonAttributes' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( ! typeof this.contextHandler?.validateContext() ) {
|
if ( ! typeof this.contextHandler?.validateContext() ) {
|
||||||
return isInvalid( 'Invalid context handler.', this.contextHandler );
|
return isInvalid( 'Invalid context handler.', this.contextHandler );
|
||||||
}
|
}
|
||||||
|
@ -259,24 +309,74 @@ class GooglepayButton extends PaymentButton {
|
||||||
/**
|
/**
|
||||||
* Configures the button instance. Must be called before the initial `init()`.
|
* Configures the button instance. Must be called before the initial `init()`.
|
||||||
*
|
*
|
||||||
* @param {Object} apiConfig - API configuration.
|
* @param {Object} apiConfig - API configuration.
|
||||||
* @param {Object} transactionInfo - Transaction details; required before "init" call.
|
* @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.googlePayConfig = apiConfig;
|
||||||
this.#transactionInfo = transactionInfo;
|
this.#transactionInfo = transactionInfo;
|
||||||
|
this.buttonAttributes = attributes;
|
||||||
this.allowedPaymentMethods = this.googlePayConfig.allowedPaymentMethods;
|
this.allowedPaymentMethods = this.googlePayConfig.allowedPaymentMethods;
|
||||||
this.baseCardPaymentMethod = this.allowedPaymentMethods[ 0 ];
|
this.baseCardPaymentMethod = this.allowedPaymentMethods[ 0 ];
|
||||||
|
this.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
// Use `reinit()` to force a full refresh of an initialized button.
|
// Skip if already initialized
|
||||||
if ( this.isInitialized ) {
|
if ( this.isInitialized ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop, if configuration is invalid.
|
// Validate configuration
|
||||||
if ( ! this.validateConfiguration() ) {
|
if ( ! this.validateConfiguration() ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -284,16 +384,6 @@ class GooglepayButton extends PaymentButton {
|
||||||
super.init();
|
super.init();
|
||||||
this.#paymentsClient = this.createPaymentsClient();
|
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
|
this.paymentsClient
|
||||||
.isReadyToPay(
|
.isReadyToPay(
|
||||||
this.buildReadyToPayRequest(
|
this.buildReadyToPayRequest(
|
||||||
|
@ -371,30 +461,86 @@ class GooglepayButton extends PaymentButton {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the payment button and calls `this.insertButton()` to make the button visible in the
|
* Creates the payment button and calls `super.insertButton()` to make the button visible in the correct wrapper.
|
||||||
* correct wrapper.
|
|
||||||
*/
|
*/
|
||||||
addButton() {
|
addButton() {
|
||||||
if ( ! this.paymentsClient ) {
|
if ( ! this.paymentsClient ) {
|
||||||
return;
|
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 baseCardPaymentMethod = this.baseCardPaymentMethod;
|
||||||
const { color, type, language } = this.style;
|
const { color, type, language } = this.style;
|
||||||
|
|
||||||
/**
|
const buttonOptions = {
|
||||||
* @see https://developers.google.com/pay/api/web/reference/client#createButton
|
buttonColor: color || 'black',
|
||||||
*/
|
buttonSizeMode: 'fill',
|
||||||
const button = this.paymentsClient.createButton( {
|
buttonLocale: language || 'en',
|
||||||
|
buttonType: type || 'pay',
|
||||||
|
buttonRadius: parseInt( this.buttonAttributes?.borderRadius, 10 ),
|
||||||
onClick: this.onButtonClick,
|
onClick: this.onButtonClick,
|
||||||
allowedPaymentMethods: [ baseCardPaymentMethod ],
|
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';
|
import ContextHandlerFactory from './Context/ContextHandlerFactory';
|
||||||
|
|
||||||
class GooglepayManager {
|
class GooglepayManager {
|
||||||
constructor( namespace, buttonConfig, ppcpConfig ) {
|
constructor( namespace, buttonConfig, ppcpConfig, buttonAttributes = {} ) {
|
||||||
this.namespace = namespace;
|
this.namespace = namespace;
|
||||||
this.buttonConfig = buttonConfig;
|
this.buttonConfig = buttonConfig;
|
||||||
this.ppcpConfig = ppcpConfig;
|
this.ppcpConfig = ppcpConfig;
|
||||||
|
this.buttonAttributes = buttonAttributes;
|
||||||
this.googlePayConfig = null;
|
this.googlePayConfig = null;
|
||||||
this.transactionInfo = null;
|
this.transactionInfo = null;
|
||||||
this.contextHandler = null;
|
this.contextHandler = null;
|
||||||
|
@ -26,13 +27,18 @@ class GooglepayManager {
|
||||||
bootstrap.handler,
|
bootstrap.handler,
|
||||||
buttonConfig,
|
buttonConfig,
|
||||||
ppcpConfig,
|
ppcpConfig,
|
||||||
this.contextHandler
|
this.contextHandler,
|
||||||
|
this.buttonAttributes
|
||||||
);
|
);
|
||||||
|
|
||||||
this.buttons.push( button );
|
this.buttons.push( button );
|
||||||
|
|
||||||
const initButton = () => {
|
const initButton = () => {
|
||||||
button.configure( this.googlePayConfig, this.transactionInfo );
|
button.configure(
|
||||||
|
this.googlePayConfig,
|
||||||
|
this.transactionInfo,
|
||||||
|
this.buttonAttributes
|
||||||
|
);
|
||||||
button.init();
|
button.init();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -70,7 +76,8 @@ class GooglepayManager {
|
||||||
for ( const button of this.buttons ) {
|
for ( const button of this.buttons ) {
|
||||||
button.configure(
|
button.configure(
|
||||||
this.googlePayConfig,
|
this.googlePayConfig,
|
||||||
this.transactionInfo
|
this.transactionInfo,
|
||||||
|
this.buttonAttributes
|
||||||
);
|
);
|
||||||
button.init();
|
button.init();
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,13 @@ const GooglepayManagerBlockEditor = ( {
|
||||||
namespace,
|
namespace,
|
||||||
buttonConfig,
|
buttonConfig,
|
||||||
ppcpConfig,
|
ppcpConfig,
|
||||||
|
buttonAttributes,
|
||||||
} ) => (
|
} ) => (
|
||||||
<GooglepayButton
|
<GooglepayButton
|
||||||
namespace={ namespace }
|
namespace={ namespace }
|
||||||
buttonConfig={ buttonConfig }
|
buttonConfig={ buttonConfig }
|
||||||
ppcpConfig={ ppcpConfig }
|
ppcpConfig={ ppcpConfig }
|
||||||
|
buttonAttributes={ buttonAttributes }
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ if ( typeof window.PayPalCommerceGateway === 'undefined' ) {
|
||||||
window.PayPalCommerceGateway = ppcpConfig;
|
window.PayPalCommerceGateway = ppcpConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
const GooglePayComponent = ( { isEditing } ) => {
|
const GooglePayComponent = ( { isEditing, buttonAttributes } ) => {
|
||||||
const [ paypalLoaded, setPaypalLoaded ] = useState( false );
|
const [ paypalLoaded, setPaypalLoaded ] = useState( false );
|
||||||
const [ googlePayLoaded, setGooglePayLoaded ] = useState( false );
|
const [ googlePayLoaded, setGooglePayLoaded ] = useState( false );
|
||||||
const [ manager, setManager ] = useState( null );
|
const [ manager, setManager ] = useState( null );
|
||||||
|
@ -48,11 +48,18 @@ const GooglePayComponent = ( { isEditing } ) => {
|
||||||
const newManager = new GooglepayManager(
|
const newManager = new GooglepayManager(
|
||||||
namespace,
|
namespace,
|
||||||
buttonConfig,
|
buttonConfig,
|
||||||
ppcpConfig
|
ppcpConfig,
|
||||||
|
buttonAttributes
|
||||||
);
|
);
|
||||||
setManager( newManager );
|
setManager( newManager );
|
||||||
}
|
}
|
||||||
}, [ paypalLoaded, googlePayLoaded, isEditing, manager ] );
|
}, [
|
||||||
|
paypalLoaded,
|
||||||
|
googlePayLoaded,
|
||||||
|
isEditing,
|
||||||
|
manager,
|
||||||
|
buttonAttributes,
|
||||||
|
] );
|
||||||
|
|
||||||
if ( isEditing ) {
|
if ( isEditing ) {
|
||||||
return (
|
return (
|
||||||
|
@ -60,6 +67,7 @@ const GooglePayComponent = ( { isEditing } ) => {
|
||||||
namespace={ namespace }
|
namespace={ namespace }
|
||||||
buttonConfig={ buttonConfig }
|
buttonConfig={ buttonConfig }
|
||||||
ppcpConfig={ ppcpConfig }
|
ppcpConfig={ ppcpConfig }
|
||||||
|
buttonAttributes={ buttonAttributes }
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -89,5 +97,6 @@ registerExpressPaymentMethod( {
|
||||||
canMakePayment: () => buttonData.enabled,
|
canMakePayment: () => buttonData.enabled,
|
||||||
supports: {
|
supports: {
|
||||||
features,
|
features,
|
||||||
|
style: [ 'height', 'borderRadius' ],
|
||||||
},
|
},
|
||||||
} );
|
} );
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue