/** * Embedded Stripe Connect Onboarding Component * * Uses Stripe's Connect embedded components to provide a seamless * onboarding experience without redirecting users away from the app. */ import React, { useState, useCallback } from 'react'; import { ConnectComponentsProvider, ConnectAccountOnboarding, } from '@stripe/react-connect-js'; import { loadConnectAndInitialize } from '@stripe/connect-js'; import type { StripeConnectInstance } from '@stripe/connect-js'; import { CheckCircle, AlertCircle, Loader2, CreditCard, Wallet, Building2, } from 'lucide-react'; import { createAccountSession, refreshConnectStatus, ConnectAccountInfo } from '../api/payments'; interface ConnectOnboardingEmbedProps { connectAccount: ConnectAccountInfo | null; tier: string; onComplete?: () => void; onError?: (error: string) => void; } type LoadingState = 'idle' | 'loading' | 'ready' | 'error' | 'complete'; const ConnectOnboardingEmbed: React.FC = ({ connectAccount, tier, onComplete, onError, }) => { const [stripeConnectInstance, setStripeConnectInstance] = useState(null); const [loadingState, setLoadingState] = useState('idle'); const [errorMessage, setErrorMessage] = useState(null); const isActive = connectAccount?.status === 'active' && connectAccount?.charges_enabled; // Initialize Stripe Connect const initializeStripeConnect = useCallback(async () => { if (loadingState === 'loading' || loadingState === 'ready') return; setLoadingState('loading'); setErrorMessage(null); try { // Fetch account session from our backend const response = await createAccountSession(); const { client_secret, publishable_key } = response.data; // Initialize the Connect instance const instance = await loadConnectAndInitialize({ publishableKey: publishable_key, fetchClientSecret: async () => client_secret, appearance: { overlays: 'drawer', variables: { colorPrimary: '#635BFF', colorBackground: '#ffffff', colorText: '#1a1a1a', colorDanger: '#df1b41', fontFamily: 'system-ui, -apple-system, sans-serif', fontSizeBase: '14px', spacingUnit: '4px', borderRadius: '8px', }, }, }); setStripeConnectInstance(instance); setLoadingState('ready'); } catch (err: any) { console.error('Failed to initialize Stripe Connect:', err); const message = err.response?.data?.error || err.message || 'Failed to initialize payment setup'; setErrorMessage(message); setLoadingState('error'); onError?.(message); } }, [loadingState, onError]); // Handle onboarding completion const handleOnboardingExit = useCallback(async () => { // Refresh status from Stripe to sync the local database try { await refreshConnectStatus(); } catch (err) { console.error('Failed to refresh Connect status:', err); } setLoadingState('complete'); onComplete?.(); }, [onComplete]); // Handle errors from the Connect component const handleLoadError = useCallback((loadError: { error: { message?: string }; elementTagName: string }) => { console.error('Connect component load error:', loadError); const message = loadError.error.message || 'Failed to load payment component'; setErrorMessage(message); setLoadingState('error'); onError?.(message); }, [onError]); // Account type display const getAccountTypeLabel = () => { switch (connectAccount?.account_type) { case 'standard': return 'Standard Connect'; case 'express': return 'Express Connect'; case 'custom': return 'Custom Connect'; default: return 'Connect'; } }; // If account is already active, show status if (isActive) { return (

Stripe Connected

Your Stripe account is connected and ready to accept payments.

Account Details

Account Type: {getAccountTypeLabel()}
Status: {connectAccount.status}
Charges: Enabled
Payouts: {connectAccount.payouts_enabled ? 'Enabled' : 'Pending'}
); } // Completion state if (loadingState === 'complete') { return (

Onboarding Complete!

Your Stripe account has been set up. You can now accept payments.

); } // Error state if (loadingState === 'error') { return (

Setup Failed

{errorMessage}

); } // Idle state - show start button if (loadingState === 'idle') { return (

Set Up Payments

As a {tier} tier business, you'll use Stripe Connect to accept payments. Complete the onboarding process to start accepting payments from your customers.

  • Secure payment processing
  • Automatic payouts to your bank account
  • PCI compliance handled for you
); } // Loading state if (loadingState === 'loading') { return (

Initializing payment setup...

); } // Ready state - show embedded onboarding if (loadingState === 'ready' && stripeConnectInstance) { return (

Complete Your Account Setup

Fill out the information below to finish setting up your payment account. Your information is securely handled by Stripe.

); } return null; }; export default ConnectOnboardingEmbed;