diff --git a/modules/ppcp-applepay/resources/js/ApplepayManagerBlockEditor.js b/modules/ppcp-applepay/resources/js/ApplepayManagerBlockEditor.js index 1c10bb997..7276abbb7 100644 --- a/modules/ppcp-applepay/resources/js/ApplepayManagerBlockEditor.js +++ b/modules/ppcp-applepay/resources/js/ApplepayManagerBlockEditor.js @@ -17,7 +17,7 @@ class ApplePayManagerBlockEditor { async config() { try { - this.applePayConfig = await paypal.Applepay().config(); + this.applePayConfig = await ppcpBlocksEditorPaypalApplepay.Applepay().config(); const button = new ApplePayButton( this.ppcpConfig.context, diff --git a/modules/ppcp-applepay/resources/js/boot-block.js b/modules/ppcp-applepay/resources/js/boot-block.js index c447cb064..ea15477b0 100644 --- a/modules/ppcp-applepay/resources/js/boot-block.js +++ b/modules/ppcp-applepay/resources/js/boot-block.js @@ -12,6 +12,7 @@ const ppcpConfig = ppcpData.scriptData; const buttonData = wc.wcSettings.getSetting( 'ppcp-applepay_data' ); const buttonConfig = buttonData.scriptData; +const dataNamespace = 'ppcpBlocksEditorPaypalApplepay'; if ( typeof window.PayPalCommerceGateway === 'undefined' ) { window.PayPalCommerceGateway = ppcpConfig; @@ -38,6 +39,10 @@ const ApplePayComponent = ( props ) => { ppcpConfig.url_params.components += ',applepay'; + if ( props.isEditing ) { + ppcpConfig.data_namespace = dataNamespace; + } + // Load PayPal loadPaypalScript( ppcpConfig, () => { setPaypalLoaded( true ); diff --git a/modules/ppcp-button/resources/js/modules/Helper/ScriptLoading.js b/modules/ppcp-button/resources/js/modules/Helper/ScriptLoading.js index 588e14cd6..38f605cc7 100644 --- a/modules/ppcp-button/resources/js/modules/Helper/ScriptLoading.js +++ b/modules/ppcp-button/resources/js/modules/Helper/ScriptLoading.js @@ -7,15 +7,25 @@ import { getCurrentPaymentMethod } from './CheckoutMethodState'; import { v4 as uuidv4 } from 'uuid'; // This component may be used by multiple modules. This assures that options are shared between all instances. -const options = ( window.ppcpWidgetBuilder = window.ppcpWidgetBuilder || { - isLoading: false, - onLoadedCallbacks: [], - onErrorCallbacks: [], -} ); +const scriptOptionsMap = {}; + +const getNamespaceOptions = ( namespace ) => { + if ( ! scriptOptionsMap[ namespace ] ) { + scriptOptionsMap[ namespace ] = { + isLoading: false, + onLoadedCallbacks: [], + onErrorCallbacks: [], + }; + } + return scriptOptionsMap[ namespace ]; +}; export const loadPaypalScript = ( config, onLoaded, onError = null ) => { - // If PayPal is already loaded call the onLoaded callback and return. - if ( typeof paypal !== 'undefined' ) { + const dataNamespace = config?.data_namespace || ''; + const options = getNamespaceOptions( dataNamespace ); + + // If PayPal is already loaded for this namespace, call the onLoaded callback and return. + if ( typeof window.paypal !== 'undefined' && ! dataNamespace ) { onLoaded(); return; } @@ -90,6 +100,11 @@ export const loadPaypalScript = ( config, onLoaded, onError = null ) => { scriptOptions[ 'data-user-id-token' ] = userIdToken; } + // Adds data-namespace to script options. + if ( dataNamespace ) { + scriptOptions.dataNamespace = dataNamespace; + } + // Load PayPal script loadScript( scriptOptions ).then( callback ).catch( errorCallback ); }; diff --git a/modules/ppcp-googlepay/resources/js/GooglepayManagerBlockEditor.js b/modules/ppcp-googlepay/resources/js/GooglepayManagerBlockEditor.js new file mode 100644 index 000000000..0fbbfbd72 --- /dev/null +++ b/modules/ppcp-googlepay/resources/js/GooglepayManagerBlockEditor.js @@ -0,0 +1,59 @@ +import GooglepayButton from './GooglepayButton'; +import ContextHandlerFactory from './Context/ContextHandlerFactory'; + +class GooglepayManagerBlockEditor { + constructor( buttonConfig, ppcpConfig ) { + this.buttonConfig = buttonConfig; + this.ppcpConfig = ppcpConfig; + this.googlePayConfig = null; + this.transactionInfo = null; + this.contextHandler = null; + } + + init() { + ( async () => { + await this.config(); + } )(); + } + + async config() { + try { + // Gets GooglePay configuration of the PayPal merchant. + this.googlePayConfig = await ppcpBlocksEditorPaypalGooglepay.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; + } + } +} + +export default GooglepayManagerBlockEditor; diff --git a/modules/ppcp-googlepay/resources/js/boot-block.js b/modules/ppcp-googlepay/resources/js/boot-block.js index 6e39350a6..3d465ac93 100644 --- a/modules/ppcp-googlepay/resources/js/boot-block.js +++ b/modules/ppcp-googlepay/resources/js/boot-block.js @@ -7,24 +7,29 @@ import { __ } from '@wordpress/i18n'; import { loadPaypalScript } from '../../../ppcp-button/resources/js/modules/Helper/ScriptLoading'; import GooglepayManager from './GooglepayManager'; import { loadCustomScript } from '@paypal/paypal-js'; +import GooglepayManagerBlockEditor from './GooglepayManagerBlockEditor'; const ppcpData = wc.wcSettings.getSetting( 'ppcp-gateway_data' ); const ppcpConfig = ppcpData.scriptData; const buttonData = wc.wcSettings.getSetting( 'ppcp-googlepay_data' ); const buttonConfig = buttonData.scriptData; +const dataNamespace = 'ppcpBlocksEditorPaypalGooglepay'; if ( typeof window.PayPalCommerceGateway === 'undefined' ) { window.PayPalCommerceGateway = ppcpConfig; } -const GooglePayComponent = () => { +const GooglePayComponent = ( props ) => { const [ bootstrapped, setBootstrapped ] = useState( false ); const [ paypalLoaded, setPaypalLoaded ] = useState( false ); const [ googlePayLoaded, setGooglePayLoaded ] = useState( false ); const bootstrap = function () { - const manager = new GooglepayManager( buttonConfig, ppcpConfig ); + const ManagerClass = props.isEditing + ? GooglepayManagerBlockEditor + : GooglepayManager; + const manager = new ManagerClass( buttonConfig, ppcpConfig ); manager.init(); }; @@ -34,6 +39,12 @@ const GooglePayComponent = () => { setGooglePayLoaded( true ); } ); + ppcpConfig.url_params.components += ',googlepay'; + + if ( props.isEditing ) { + ppcpConfig.data_namespace = dataNamespace; + } + // Load PayPal loadPaypalScript( ppcpConfig, () => { setPaypalLoaded( true );