import React, { useState, useEffect } from 'react'; import { loadStripe, StripeElementsOptions } from '@stripe/stripe-js'; import { Elements } from '@stripe/react-stripe-js'; import StripePaymentForm from './StripePaymentForm'; import { createStripePaymentIntent, confirmStripePayment } from '../services/paymentService'; import { Loader2, AlertCircle } from 'lucide-react'; interface StripePaymentWrapperProps { bookingId: number; amount: number; currency?: string; onSuccess: () => void; onError?: (error: string) => void; } const StripePaymentWrapper: React.FC = ({ bookingId, amount, currency = 'usd', onSuccess, onError, }) => { const [stripePromise, setStripePromise] = useState | null>(null); const [clientSecret, setClientSecret] = useState(null); const [, setPublishableKey] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [paymentCompleted, setPaymentCompleted] = useState(false); useEffect(() => { if (paymentCompleted) { return; } const initializeStripe = async () => { try { setLoading(true); setError(null); const response = await createStripePaymentIntent( bookingId, amount, currency ); if (response.success && response.data) { const { publishable_key, client_secret } = response.data; console.log('Payment intent response:', { publishable_key: publishable_key ? 'present' : 'missing', client_secret: client_secret ? 'present' : 'missing' }); if (!client_secret) { throw new Error('Client secret not received from server'); } if (!publishable_key) { throw new Error('Publishable key not configured. Please configure Stripe settings in Admin Panel.'); } setPublishableKey(publishable_key); setClientSecret(client_secret); const stripePromise = loadStripe(publishable_key); setStripePromise(stripePromise); const stripe = await stripePromise; if (!stripe) { throw new Error('Failed to load Stripe'); } } else { throw new Error(response.message || 'Failed to initialize payment'); } } catch (err: any) { console.error('Error initializing Stripe:', err); const errorMessage = err.response?.data?.message || err.message || 'Failed to initialize payment'; setError(errorMessage); if (onError) { onError(errorMessage); } } finally { setLoading(false); } }; initializeStripe(); }, [bookingId, amount, currency, onError, paymentCompleted]); useEffect(() => { if (clientSecret && stripePromise) { console.log('Stripe initialized successfully', { hasClientSecret: !!clientSecret, hasStripePromise: !!stripePromise }); } else { console.log('Stripe not ready', { hasClientSecret: !!clientSecret, hasStripePromise: !!stripePromise, error }); } }, [clientSecret, stripePromise, error]); const handlePaymentSuccess = async (paymentIntentId: string) => { try { setPaymentCompleted(true); const response = await confirmStripePayment(paymentIntentId, bookingId); if (response.success) { onSuccess(); } else { setPaymentCompleted(false); throw new Error(response.message || 'Payment confirmation failed'); } } catch (err: any) { console.error('Error confirming payment:', err); setPaymentCompleted(false); const errorMessage = err.response?.data?.message || err.message || 'Payment confirmation failed'; setError(errorMessage); if (onError) { onError(errorMessage); } } }; const handlePaymentError = (errorMessage: string) => { setError(errorMessage); if (onError) { onError(errorMessage); } }; if (paymentCompleted) { return null; } if (loading) { return (
Initializing payment...
); } if (error) { return (

Payment Initialization Failed

{error || 'Unable to initialize payment. Please try again.'}

); } if (!clientSecret || !stripePromise) { return (
Loading payment form...
); } const options: StripeElementsOptions = { clientSecret, appearance: { theme: 'stripe', }, }; return ( ); }; export default StripePaymentWrapper;