Try to fix Google Pay in the editor

This commit is contained in:
Daniel Dudzic 2024-10-09 16:38:11 +02:00
parent be6b8a39ec
commit 3171e943ba
No known key found for this signature in database
GPG key ID: 31B40D33E3465483
12 changed files with 487 additions and 97 deletions

View file

@ -0,0 +1,31 @@
import { useState, useEffect } from '@wordpress/element';
import useGooglepayApiToGenerateButton from '../hooks/useGooglepayApiToGenerateButton';
const GooglepayButton = ( {
namespace,
buttonConfig,
ppcpConfig,
googlepayConfig,
} ) => {
const [ buttonHtml, setButtonHtml ] = useState( '' );
const googlepayButton = useGooglepayApiToGenerateButton(
namespace,
buttonConfig,
ppcpConfig,
googlepayConfig
);
useEffect( () => {
if ( googlepayButton ) {
setButtonHtml( googlepayButton.outerHTML );
}
}, [ googlepayButton ] );
if ( ! buttonHtml ) {
return null;
}
return <div dangerouslySetInnerHTML={ { __html: buttonHtml } } />;
};
export default GooglepayButton;

View file

@ -0,0 +1,19 @@
import { useMemo } from '@wordpress/element';
import { combineStyles } from '../../../../../ppcp-button/resources/js/modules/Helper/PaymentButtonHelpers';
const useButtonStyles = ( buttonConfig, ppcpConfig ) => {
return useMemo( () => {
const styles = combineStyles(
ppcpConfig?.button || {},
buttonConfig?.button || {}
);
if ( styles.MiniCart && styles.MiniCart.type === 'buy' ) {
styles.MiniCart.type = 'pay';
}
return styles;
}, [ buttonConfig, ppcpConfig ] );
};
export default useButtonStyles;

View file

@ -0,0 +1,62 @@
import { useEffect, useState } from '@wordpress/element';
import useButtonStyles from './useButtonStyles';
const useGooglepayApiToGenerateButton = (
namespace,
buttonConfig,
ppcpConfig,
googlepayConfig
) => {
const [ googlepayButton, setGooglepayButton ] = useState( null );
const buttonStyles = useButtonStyles( buttonConfig, ppcpConfig );
useEffect( () => {
if (
! buttonConfig ||
! googlepayConfig ||
! window.google ||
! window.google.payments ||
! window.google.payments.api
) {
return;
}
const paymentsClient = new window.google.payments.api.PaymentsClient( {
environment: 'TEST',
} );
console.log( 'paymentsClient', paymentsClient );
console.log( 'googlepayConfig', googlepayConfig );
console.log( 'buttonStyles?.Default', buttonStyles?.Default );
const button = paymentsClient.createButton( {
onClick: () => {
console.log( 'Google Pay button clicked' );
},
allowedPaymentMethods: googlepayConfig.allowedPaymentMethods,
buttonColor: buttonConfig.buttonColor || 'black',
buttonType: buttonConfig.buttonType || 'pay',
buttonLocale: buttonConfig.buttonLocale || 'en',
buttonSizeMode: 'fill',
} );
console.log( {
allowedPaymentMethods: googlepayConfig.allowedPaymentMethods,
buttonColor: buttonConfig.buttonColor || 'black',
buttonType: buttonConfig.buttonType || 'pay',
buttonLocale: buttonConfig.buttonLocale || 'en',
buttonSizeMode: 'fill',
} );
setGooglepayButton( button );
return () => {
setGooglepayButton( null );
};
}, [ namespace, buttonConfig, ppcpConfig, googlepayConfig, buttonStyles ] );
return googlepayButton;
};
export default useGooglepayApiToGenerateButton;

View file

@ -0,0 +1,26 @@
import { useState, useEffect } from '@wordpress/element';
const useGooglepayConfig = ( namespace, isGooglepayLoaded ) => {
const [ googlePayConfig, setGooglePayConfig ] = useState( null );
useEffect( () => {
const fetchConfig = async () => {
if ( ! isGooglepayLoaded ) {
return;
}
try {
const config = await window[ namespace ].Googlepay().config();
setGooglePayConfig( config );
} catch ( error ) {
console.error( 'Failed to fetch Google Pay config:', error );
}
};
fetchConfig();
}, [ namespace, isGooglepayLoaded ] );
return googlePayConfig;
};
export default useGooglepayConfig;

View file

@ -0,0 +1,32 @@
import { useState, useEffect } from '@wordpress/element';
import { loadCustomScript } from '@paypal/paypal-js';
const useGooglepayScript = ( buttonConfig, isPayPalLoaded ) => {
const [ isGooglepayLoaded, setIsGooglepayLoaded ] = useState( false );
useEffect( () => {
const loadGooglepayScript = async () => {
if ( ! isPayPalLoaded ) {
return;
}
if ( ! buttonConfig || ! buttonConfig.sdk_url ) {
console.error( 'Invalid buttonConfig or missing sdk_url' );
return;
}
try {
await loadCustomScript( { url: buttonConfig.sdk_url } );
setIsGooglepayLoaded( true );
} catch ( error ) {
console.error( 'Failed to load Googlepay script:', error );
}
};
loadGooglepayScript();
}, [ buttonConfig, isPayPalLoaded ] );
return isGooglepayLoaded;
};
export default useGooglepayScript;

View file

@ -0,0 +1,25 @@
import { useState, useEffect } from '@wordpress/element';
import { loadPayPalScript } from '../../../../../ppcp-button/resources/js/modules/Helper/PayPalScriptLoading';
const usePayPalScript = ( namespace, ppcpConfig ) => {
const [ isPayPalLoaded, setIsPayPalLoaded ] = useState( false );
ppcpConfig.url_params.components += ',googlepay';
useEffect( () => {
const loadScript = async () => {
try {
await loadPayPalScript( namespace, ppcpConfig );
setIsPayPalLoaded( true );
} catch ( error ) {
console.error( `Error loading PayPal script: ${ error }` );
}
};
loadScript();
}, [ namespace, ppcpConfig ] );
return isPayPalLoaded;
};
export default usePayPalScript;

View file

@ -1,62 +1,32 @@
import GooglepayButton from './GooglepayButton';
import ContextHandlerFactory from './Context/ContextHandlerFactory';
import GooglepayButton from './Block/components/GooglepayButton';
import usePayPalScript from './Block/hooks/usePayPalScript';
import useGooglepayScript from './Block/hooks/useGooglepayScript';
import useGooglepayConfig from './Block/hooks/useGooglepayConfig';
class GooglepayManagerBlockEditor {
constructor( namespace, buttonConfig, ppcpConfig ) {
this.namespace = namespace;
this.buttonConfig = buttonConfig;
this.ppcpConfig = ppcpConfig;
this.googlePayConfig = null;
this.transactionInfo = null;
this.contextHandler = null;
const GooglepayManagerBlockEditor = ( {
namespace,
buttonConfig,
ppcpConfig,
} ) => {
const isPayPalLoaded = usePayPalScript( namespace, ppcpConfig );
const isGooglepayLoaded = useGooglepayScript(
buttonConfig,
isPayPalLoaded
);
const googlepayConfig = useGooglepayConfig( namespace, isGooglepayLoaded );
if ( ! googlepayConfig ) {
return <div>Loading Google Pay...</div>; // Or any other loading indicator
}
init() {
( async () => {
await this.config();
} )();
}
async config() {
try {
// Gets GooglePay configuration of the PayPal merchant.
this.googlePayConfig = await window[ this.namespace ]
.Googlepay()
.config();
// Fetch transaction information.
this.transactionInfo = await this.fetchTransactionInfo();
const button = new GooglepayButton(
this.ppcpConfig.context,
null,
this.buttonConfig,
this.ppcpConfig,
this.contextHandler
);
button.init( this.googlePayConfig, this.transactionInfo );
} catch ( error ) {
console.error( 'Failed to initialize Google Pay:', error );
}
}
async fetchTransactionInfo() {
try {
if ( ! this.contextHandler ) {
this.contextHandler = ContextHandlerFactory.create(
this.ppcpConfig.context,
this.buttonConfig,
this.ppcpConfig,
null
);
}
return null;
} catch ( error ) {
console.error( 'Error fetching transaction info:', error );
throw error;
}
}
}
return (
<GooglepayButton
namespace={ namespace }
buttonConfig={ buttonConfig }
ppcpConfig={ ppcpConfig }
googlepayConfig={ googlepayConfig }
/>
);
};
export default GooglepayManagerBlockEditor;

View file

@ -1,4 +1,5 @@
import { useEffect, useState } from '@wordpress/element';
import { loadCustomScript } from '@paypal/paypal-js';
import {
registerExpressPaymentMethod,
registerPaymentMethod,
@ -6,7 +7,6 @@ import {
import { __ } from '@wordpress/i18n';
import { loadPayPalScript } from '../../../ppcp-button/resources/js/modules/Helper/PayPalScriptLoading';
import GooglepayManager from './GooglepayManager';
import { loadCustomScript } from '@paypal/paypal-js';
import GooglepayManagerBlockEditor from './GooglepayManagerBlockEditor';
const ppcpData = wc.wcSettings.getSetting( 'ppcp-gateway_data' );
@ -20,56 +20,55 @@ if ( typeof window.PayPalCommerceGateway === 'undefined' ) {
window.PayPalCommerceGateway = ppcpConfig;
}
const GooglePayComponent = ( props ) => {
const [ bootstrapped, setBootstrapped ] = useState( false );
const GooglePayComponent = ( { isEditing } ) => {
const [ paypalLoaded, setPaypalLoaded ] = useState( false );
const [ googlePayLoaded, setGooglePayLoaded ] = useState( false );
const [ manager, setManager ] = useState( null );
useEffect( () => {
// Load GooglePay SDK
loadCustomScript( { url: buttonConfig.sdk_url } ).then( () => {
setGooglePayLoaded( true );
} );
ppcpConfig.url_params.components += ',googlepay';
// Load PayPal
loadPayPalScript( namespace, ppcpConfig )
.then( () => {
setPaypalLoaded( true );
} )
.catch( ( error ) => {
console.error( 'Failed to load PayPal script: ', error );
if ( ! isEditing ) {
loadCustomScript( { url: buttonConfig.sdk_url } ).then( () => {
setGooglePayLoaded( true );
} );
}, [] );
ppcpConfig.url_params.components += ',googlepay';
loadPayPalScript( namespace, ppcpConfig )
.then( () => {
setPaypalLoaded( true );
} )
.catch( ( error ) => {
console.error( 'Failed to load PayPal script: ', error );
} );
}
}, [ isEditing, buttonConfig, ppcpConfig ] );
useEffect( () => {
if ( paypalLoaded && googlePayLoaded && ! manager ) {
const ManagerClass = props.isEditing
? GooglepayManagerBlockEditor
: GooglepayManager;
const newManager = new ManagerClass(
if ( ! isEditing && paypalLoaded && googlePayLoaded && ! manager ) {
const newManager = new GooglepayManager(
namespace,
buttonConfig,
ppcpConfig
);
setManager( newManager );
}
}, [ paypalLoaded, googlePayLoaded, props.isEditing ] );
}, [ paypalLoaded, googlePayLoaded, isEditing, manager ] );
useEffect( () => {
if ( manager && ! bootstrapped ) {
setBootstrapped( true );
manager.init();
}
}, [ manager, bootstrapped ] );
if ( isEditing ) {
return (
<GooglepayManagerBlockEditor
namespace={ namespace }
buttonConfig={ buttonConfig }
ppcpConfig={ ppcpConfig }
/>
);
}
return (
<div
id={ buttonConfig.button.wrapper.replace( '#', '' ) }
className="ppcp-button-apm ppcp-button-googlepay"
></div>
/>
);
};