'use client'; import { JSX, useEffect, useRef, useState, useCallback } from 'react'; import { useAppSelector } from '@akinon/next/redux/hooks'; import { RootState } from '@theme/redux/store'; import Script from 'next/script'; import useGooglePay from '../hooks/use-google-pay'; declare global { interface Window { google: any; } } export interface GooglePayProps { customUIRender?: (props: { handlePaymentRequest: () => void; paymentErrors?: string | null; }) => JSX.Element | null; className?: string; } export const GooglePay = ({ customUIRender, className }: GooglePayProps) => { const { walletPaymentData } = useAppSelector( (state: RootState) => state.checkout ); const { handleGooglePaySuccess, paymentErrors } = useGooglePay(); const buttonContainerRef = useRef(null); const [isScriptLoaded, setIsScriptLoaded] = useState(false); const [canMakePayment, setCanMakePayment] = useState(false); const [isProcessing, setIsProcessing] = useState(false); const paymentsClientRef = useRef(null); useEffect(() => { if (window.google?.payments) { setIsScriptLoaded(true); } }, []); const getPaymentsClient = useCallback(() => { if (!walletPaymentData?.data || !window.google?.payments) return null; if (!paymentsClientRef.current) { paymentsClientRef.current = new window.google.payments.api.PaymentsClient( { environment: walletPaymentData.data.environment } ); } return paymentsClientRef.current; }, [walletPaymentData]); const handlePaymentRequest = useCallback(() => { if (!walletPaymentData?.data || isProcessing) return; setIsProcessing(true); const client = getPaymentsClient(); const { apiVersion, apiVersionMinor, allowedPaymentMethods, transactionInfo, merchantInfo } = walletPaymentData.data; const paymentDataRequest = { apiVersion, apiVersionMinor, allowedPaymentMethods, transactionInfo, ...(merchantInfo && { merchantInfo }) }; client .loadPaymentData(paymentDataRequest) .then((paymentData: any) => { handleGooglePaySuccess(paymentData); }) .catch((err: any) => { console.error('Err', err); }) .finally(() => { setIsProcessing(false); }); }, [ walletPaymentData, getPaymentsClient, handleGooglePaySuccess, isProcessing ]); const addGooglePayButton = () => { if (customUIRender) return; const client = getPaymentsClient(); const button = client.createButton({ onClick: handlePaymentRequest, buttonColor: 'black', buttonType: 'buy' }); if (buttonContainerRef.current) { buttonContainerRef.current.innerHTML = ''; buttonContainerRef.current.appendChild(button); } }; useEffect(() => { if (isScriptLoaded && walletPaymentData?.data) { const client = getPaymentsClient(); if (!client) return; const { apiVersion, apiVersionMinor, allowedPaymentMethods } = walletPaymentData.data; client .isReadyToPay({ apiVersion, apiVersionMinor, allowedPaymentMethods }) .then((response: any) => { if (response.result) setCanMakePayment(true); }) .catch((err: any) => console.error('Error:', err)); } }, [isScriptLoaded, walletPaymentData, getPaymentsClient]); useEffect(() => { if ( canMakePayment && !customUIRender && buttonContainerRef.current && paymentsClientRef.current ) { addGooglePayButton(); } }, [canMakePayment, customUIRender, handlePaymentRequest]); if (!walletPaymentData) return null; return (