woocommerce-paypal-payments/modules/ppcp-googlepay/resources/js/boot-block.js
Narek Zakarian 3d14e806ec
fix(googlepay): skip registering blocked express payment method
Previously the express payment method was always registered on Block
checkout and only failed internal validation afterward, leaving an
empty placeholder in its place. Checking subscription eligibility
before registration avoids rendering anything at all when blocked.
2026-07-03 16:23:59 +04:00

148 lines
4 KiB
JavaScript

import { useEffect, useState } from '@wordpress/element';
import { loadCustomScript } from '@paypal/paypal-js';
import { registerExpressPaymentMethod } from '@woocommerce/blocks-registry';
import { __ } from '@wordpress/i18n';
import { loadPayPalScript } from '@ppcp-button/Helper/PayPalScriptLoading';
import GooglepayManager from './GooglepayManager';
import GooglepayManagerBlockEditor from './GooglepayManagerBlockEditor';
import { debounce } from '@ppcp-blocks/Helper/debounce';
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 namespace = 'ppcpBlocksPaypalGooglepay';
if ( typeof window.PayPalCommerceGateway === 'undefined' ) {
window.PayPalCommerceGateway = ppcpConfig;
}
const GooglePayComponent = ( { isEditing, buttonAttributes, onClick } ) => {
const [ paypalLoaded, setPaypalLoaded ] = useState( false );
const [ googlePayLoaded, setGooglePayLoaded ] = useState( false );
const [ manager, setManager ] = useState( null );
useEffect( () => {
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 ] );
useEffect( () => {
if ( isEditing || ! manager || ! wp.data?.subscribe ) {
return;
}
let timeoutId = null;
const checkAddressChange = () => {
const store = wp.data.select( 'wc/store/cart' );
if ( ! store ) {
return;
}
timeoutId = setTimeout( () => {
manager.buttons.forEach( ( button ) => button.addButton() );
}, 1000 );
};
const unsubscribe = wp.data.subscribe(
debounce( checkAddressChange, 300 )
);
return () => {
if ( timeoutId ) {
clearTimeout( timeoutId );
}
if ( unsubscribe ) {
unsubscribe();
}
};
}, [ isEditing, manager ] );
useEffect( () => {
if ( ! isEditing && paypalLoaded && googlePayLoaded && ! manager ) {
const newManager = new GooglepayManager(
namespace,
buttonConfig,
ppcpConfig,
buttonAttributes,
onClick
);
setManager( newManager );
}
}, [
paypalLoaded,
googlePayLoaded,
isEditing,
manager,
buttonAttributes,
] );
if ( isEditing ) {
return (
<GooglepayManagerBlockEditor
namespace={ namespace }
buttonConfig={ buttonConfig }
ppcpConfig={ ppcpConfig }
buttonAttributes={ buttonAttributes }
/>
);
}
return (
<div
id={ buttonConfig.button.wrapper.replace( '#', '' ) }
className="ppcp-button-apm ppcp-button-googlepay"
/>
);
};
/**
* Google Pay doesn't support vaulting, so the only case where it's allowed on a
* subscription is paying to manually renew an existing one. Checked here so the express
* payment method isn't registered at all (no empty placeholder) when it can't be used.
*/
const isBlockedBySubscription = () => {
const locations = ppcpConfig?.locations_with_subscription_product;
if ( locations?.payorder ) {
return ! ppcpConfig?.subscriptions_accept_manual_renewals;
}
return !! locations?.cart;
};
const features = [ 'products' ];
if ( buttonConfig?.is_enabled && ! isBlockedBySubscription() ) {
registerExpressPaymentMethod( {
name: buttonData.id,
title: `PayPal - ${ buttonData.title }`,
description: __(
'Eligible users will see the PayPal button.',
'woocommerce-paypal-payments'
),
gatewayId: 'ppcp-gateway',
paymentMethodId: 'ppcp-gateway',
label: <div dangerouslySetInnerHTML={ { __html: buttonData.title } } />,
content: <GooglePayComponent isEditing={ false } />,
edit: <GooglePayComponent isEditing={ true } />,
ariaLabel: buttonData.title,
canMakePayment: () => buttonData.enabled,
supports: {
features,
style: [ 'height', 'borderRadius' ],
},
} );
}