diff --git a/client/prebuiltPages/react/oneTimePayment/src/components/PayPalButton.tsx b/client/prebuiltPages/react/oneTimePayment/src/components/PayPalButton.tsx index 3fbf75f..3f5edd5 100644 --- a/client/prebuiltPages/react/oneTimePayment/src/components/PayPalButton.tsx +++ b/client/prebuiltPages/react/oneTimePayment/src/components/PayPalButton.tsx @@ -12,11 +12,21 @@ const PayPalButton: React.FC = ( const paypalSession = useRef(null); useEffect(() => { - if (sdkInstance) { + if (sdkInstance && !paypalSession.current) { paypalSession.current = sdkInstance.createPayPalOneTimePaymentSession( paymentSessionOptions, ); } + + return () => { + if ( + paypalSession.current && + typeof paypalSession.current.destroy === "function" + ) { + paypalSession.current.destroy(); + paypalSession.current = null; + } + }; }, [sdkInstance, paymentSessionOptions]); const payPalOnClickHandler = async () => { diff --git a/client/prebuiltPages/react/oneTimePayment/src/components/VenmoButton.tsx b/client/prebuiltPages/react/oneTimePayment/src/components/VenmoButton.tsx index f571472..c1cc364 100644 --- a/client/prebuiltPages/react/oneTimePayment/src/components/VenmoButton.tsx +++ b/client/prebuiltPages/react/oneTimePayment/src/components/VenmoButton.tsx @@ -12,11 +12,21 @@ const VenmoButton: React.FC = ( const venmoSession = useRef(null); useEffect(() => { - if (sdkInstance) { + if (sdkInstance && !venmoSession.current) { venmoSession.current = sdkInstance.createVenmoOneTimePaymentSession( paymentSessionOptions, ); } + + return () => { + if ( + venmoSession.current && + typeof venmoSession.current.destroy === "function" + ) { + venmoSession.current.destroy(); + venmoSession.current = null; + } + }; }, [sdkInstance, paymentSessionOptions]); const venmoOnClickHandler = async () => { diff --git a/client/prebuiltPages/react/oneTimePayment/src/context/sdkContext.tsx b/client/prebuiltPages/react/oneTimePayment/src/context/sdkContext.tsx index 9c9d8ff..e40c3f3 100644 --- a/client/prebuiltPages/react/oneTimePayment/src/context/sdkContext.tsx +++ b/client/prebuiltPages/react/oneTimePayment/src/context/sdkContext.tsx @@ -78,7 +78,7 @@ export const PayPalSDKProvider: React.FC = ({ }; loadPayPalSDK(); - }); + }, [clientToken, components, pageType, sdkInstance, showBoundary]); return ( { const [modalState, setModalState] = useState(null); // Payment handlers - const handlePaymentCallbacks: PaymentSessionOptions = { - onApprove: async (data: OnApproveData) => { - console.log("Payment approved:", data); - const captureResult = await captureOrder({ orderId: data.orderId }); - console.log("Payment capture result:", captureResult); - setModalState("success"); - }, - - onCancel: () => { - console.log("Payment cancelled"); - setModalState("cancel"); - }, - - onError: (error: Error) => { - console.error("Payment error:", error); - setModalState("error"); - }, - }; + const handlePaymentCallbacks: PaymentSessionOptions = useMemo( + () => ({ + onApprove: async (data: OnApproveData) => { + console.log("Payment approved:", data); + const captureResult = await captureOrder({ orderId: data.orderId }); + console.log("Payment capture result:", captureResult); + setModalState("success"); + }, + + onCancel: () => { + console.log("Payment cancelled"); + setModalState("cancel"); + }, + + onError: (error: Error) => { + console.error("Payment error:", error); + setModalState("error"); + }, + }), + [], + ); const getModalContent = useCallback( (state: ModalType): ModalContent | null => { diff --git a/client/prebuiltPages/react/oneTimePayment/src/utils.ts b/client/prebuiltPages/react/oneTimePayment/src/utils.ts index 0d9505c..32e9dec 100644 --- a/client/prebuiltPages/react/oneTimePayment/src/utils.ts +++ b/client/prebuiltPages/react/oneTimePayment/src/utils.ts @@ -1,15 +1,13 @@ export const getBrowserSafeClientToken = async () => { - { - const response = await fetch("/paypal-api/auth/browser-safe-client-token", { - method: "GET", - headers: { - "Content-Type": "application/json", - }, - }); - const { accessToken } = await response.json(); + const response = await fetch("/paypal-api/auth/browser-safe-client-token", { + method: "GET", + headers: { + "Content-Type": "application/json", + }, + }); + const { accessToken } = await response.json(); - return accessToken; - } + return accessToken; }; export const createOrder = async () => {