mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-05 08:59:14 +08:00
128 lines
3.5 KiB
JavaScript
128 lines
3.5 KiB
JavaScript
import dataClientIdAttributeHandler from '../DataClientIdAttributeHandler';
|
|
import { loadScript } from '@paypal/paypal-js';
|
|
import widgetBuilder from '../Renderer/WidgetBuilder';
|
|
import merge from 'deepmerge';
|
|
import { keysToCamelCase } from './Utils';
|
|
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 scriptOptionsMap = {};
|
|
|
|
const getNamespaceOptions = ( namespace ) => {
|
|
if ( ! scriptOptionsMap[ namespace ] ) {
|
|
scriptOptionsMap[ namespace ] = {
|
|
isLoading: false,
|
|
onLoadedCallbacks: [],
|
|
onErrorCallbacks: [],
|
|
};
|
|
}
|
|
return scriptOptionsMap[ namespace ];
|
|
};
|
|
|
|
export const loadPaypalScript = ( config, onLoaded, onError = null ) => {
|
|
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;
|
|
}
|
|
|
|
// Add the onLoaded callback to the onLoadedCallbacks stack.
|
|
options.onLoadedCallbacks.push( onLoaded );
|
|
if ( onError ) {
|
|
options.onErrorCallbacks.push( onError );
|
|
}
|
|
|
|
// Return if it's still loading.
|
|
if ( options.isLoading ) {
|
|
return;
|
|
}
|
|
options.isLoading = true;
|
|
|
|
const resetState = () => {
|
|
options.isLoading = false;
|
|
options.onLoadedCallbacks = [];
|
|
options.onErrorCallbacks = [];
|
|
};
|
|
|
|
// Callback to be called once the PayPal script is loaded.
|
|
const callback = ( paypal ) => {
|
|
widgetBuilder.setPaypal( paypal );
|
|
|
|
for ( const onLoadedCallback of options.onLoadedCallbacks ) {
|
|
onLoadedCallback();
|
|
}
|
|
|
|
resetState();
|
|
};
|
|
const errorCallback = ( err ) => {
|
|
for ( const onErrorCallback of options.onErrorCallbacks ) {
|
|
onErrorCallback( err );
|
|
}
|
|
|
|
resetState();
|
|
};
|
|
|
|
// Build the PayPal script options.
|
|
let scriptOptions = keysToCamelCase( config.url_params );
|
|
if ( config.script_attributes ) {
|
|
scriptOptions = merge( scriptOptions, config.script_attributes );
|
|
}
|
|
|
|
// Axo SDK options
|
|
const sdkClientToken = config?.axo?.sdk_client_token;
|
|
const uuid = uuidv4().replace( /-/g, '' );
|
|
if ( sdkClientToken && config?.user?.is_logged !== true ) {
|
|
scriptOptions[ 'data-sdk-client-token' ] = sdkClientToken;
|
|
scriptOptions[ 'data-client-metadata-id' ] = uuid;
|
|
}
|
|
|
|
// Load PayPal script for special case with data-client-token
|
|
if (
|
|
config.data_client_id?.set_attribute &&
|
|
config.vault_v3_enabled !== '1'
|
|
) {
|
|
dataClientIdAttributeHandler(
|
|
scriptOptions,
|
|
config.data_client_id,
|
|
callback,
|
|
errorCallback
|
|
);
|
|
return;
|
|
}
|
|
|
|
// Adds data-user-id-token to script options.
|
|
const userIdToken = config?.save_payment_methods?.id_token;
|
|
if ( userIdToken && config?.user?.is_logged === true ) {
|
|
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 );
|
|
};
|
|
|
|
export const loadPaypalScriptPromise = ( config ) => {
|
|
return new Promise( ( resolve, reject ) => {
|
|
loadPaypalScript( config, resolve, reject );
|
|
} );
|
|
};
|
|
|
|
export const loadPaypalJsScript = ( options, buttons, container ) => {
|
|
loadScript( options ).then( ( paypal ) => {
|
|
paypal.Buttons( buttons ).render( container );
|
|
} );
|
|
};
|
|
|
|
export const loadPaypalJsScriptPromise = ( options ) => {
|
|
return new Promise( ( resolve, reject ) => {
|
|
loadScript( options ).then( resolve ).catch( reject );
|
|
} );
|
|
};
|