import { Stripe } from '@stripe/stripe-js' import { FormikHelpers } from 'formik' import _identity from 'lodash/identity' import { useEffect } from 'react' import { handlePaymentMiddleWare } from '../../paymentContainer/handlePayment' interface PaymentContext { attributes: any isFreeTickets: boolean updatedOrderData: any eventId: string values: any formikHelpers: FormikHelpers checkoutResponse: any checkoutUpdateResponse: any timestamp: number } interface UsePaymentRedirectProps { stripeRef: React.MutableRefObject setError: (error: string | null) => void setLoading: (loading: boolean) => void removeReferralKey: () => void removeAdditionalConfigs: () => void handleSubmit: ( values: any, formikHelpers: FormikHelpers, eventId: any, checkoutResponse: any, checkoutUpdateResponse: any, paymentResponse: any ) => void isBrowser: boolean } export const usePaymentRedirect = ({ stripeRef, setError, setLoading, removeReferralKey, removeAdditionalConfigs, handleSubmit, isBrowser, }: UsePaymentRedirectProps) => { useEffect(() => { const handlePaymentReturn = async () => { const urlParams = new URLSearchParams(window.location.search) const isPaymentReturn = urlParams.get('payment_return') const clientSecret = urlParams.get('payment_intent_client_secret') if (isPaymentReturn && clientSecret && stripeRef.current) { setLoading(true) try { // Get stored payment context const storedContext = localStorage.getItem('stripe_payment_context') if (!storedContext) { setError('Payment context not found') setLoading(false) return } const paymentContext: PaymentContext = JSON.parse(storedContext) const { paymentIntent } = await stripeRef.current.retrievePaymentIntent( clientSecret ) if (paymentIntent?.status === 'succeeded') { // Clean up stored context localStorage.removeItem('stripe_payment_context') // Continue with the success flow using stored context let paymentResponse = null await handlePaymentMiddleWare( null, {}, { reviewData: paymentContext.attributes, isFreeTickets: paymentContext.isFreeTickets, paymentPlanIsAvailable: false, showPaymentPlanSection: false, handlePayment: (data: any) => { paymentResponse = data }, setPaymentIsLoading: _identity, setError: _identity, orderData: paymentContext.updatedOrderData, eventId: paymentContext.eventId, isBrowser, onPaymentError: (error: any) => { throw error }, } ) // Complete the flow with cleanup and handleSubmit removeReferralKey() removeAdditionalConfigs() handleSubmit( paymentContext.values, paymentContext.formikHelpers, paymentContext.eventId, paymentContext.checkoutResponse, paymentContext.checkoutUpdateResponse, paymentResponse ) // Clean URL parameters window.history.replaceState({}, document.title, window.location.pathname) } else if (paymentIntent?.status === 'requires_action') { setError('Payment requires additional action') // Clean up stored context and URL to prevent infinite loop localStorage.removeItem('stripe_payment_context') window.history.replaceState({}, document.title, window.location.pathname) } else { setError(`Payment failed or was cancelled.`) // Clean up stored context and URL to prevent infinite loop localStorage.removeItem('stripe_payment_context') window.history.replaceState({}, document.title, window.location.pathname) } } catch (error) { console.error('Error handling payment return:', error) setError('Error processing payment return') // Clean up stored context and URL to prevent infinite loop localStorage.removeItem('stripe_payment_context') window.history.replaceState({}, document.title, window.location.pathname) } finally { setLoading(false) } } } handlePaymentReturn() }, [ stripeRef.current, setError, setLoading, removeReferralKey, removeAdditionalConfigs, handleSubmit, isBrowser, ]) }