# @stripe/react-connect-js ## Introduction React Connect.js is a React wrapper library for Stripe's Connect embedded components, designed to simplify the integration of Stripe Connect functionality into React applications. This library provides a comprehensive set of React components that wrap Stripe's Connect.js SDK, enabling developers to embed payment management, account onboarding, payouts, financial accounts, issuing cards, tax management, and other Connect-related features directly into their React applications with minimal configuration. The library manages the lifecycle and state of embedded components automatically, abstracting away the complexity of direct DOM manipulation and event handling. It uses React Context to provide the ConnectInstance throughout the component tree, allowing developers to declaratively render Stripe Connect UI components with props-based configuration. The library supports all major Stripe Connect embedded components including payments, payouts, account management, onboarding, disputes, issuing cards, financial accounts, tax settings, and notification banners. ## Core Setup and Context Provider ### ConnectComponentsProvider - Root Context Provider The `ConnectComponentsProvider` wraps your application and provides the ConnectInstance context to all child components. This is required before using any Connect component. ```jsx import React from 'react'; import ReactDOM from 'react-dom'; import {loadConnectAndInitialize} from '@stripe/connect-js'; import {ConnectComponentsProvider, ConnectPayments} from '@stripe/react-connect-js'; // Fetch client secret from your backend const fetchClientSecret = async () => { const response = await fetch('/api/account_session', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({account: 'acct_1234567890'}) }); const {client_secret} = await response.json(); return client_secret; }; // Initialize Connect instance with publishable key and appearance options const connectInstance = loadConnectAndInitialize({ publishableKey: 'pk_test_51ABCDEFghijklmnop', fetchClientSecret: fetchClientSecret, appearance: { variables: { colorPrimary: '#228403', colorBackground: '#ffffff', fontFamily: 'system-ui, sans-serif' } } }); // Wrap your app with the provider const App = () => ( ); ReactDOM.render(, document.getElementById('root')); ``` ## Payment Components ### ConnectPayments - Payment List Component Displays a list of payments for the connected account with filtering and pagination capabilities. ```jsx import React, {useState} from 'react'; import {ConnectPayments} from '@stripe/react-connect-js'; const PaymentsPage = () => { const [loading, setLoading] = useState(true); const [error, setError] = useState(null); return (

Payments

{error &&
Error loading payments: {error.message}
} { console.log(`${elementTagName} loading started`); setLoading(true); }} onLoadError={({error, elementTagName}) => { console.error(`${elementTagName} load error:`, error); setError(error); setLoading(false); }} />
); }; export default PaymentsPage; ``` ### ConnectPaymentDetails - Payment Detail View Shows detailed information for a specific payment, charge, or payment intent with a close callback. ```jsx import React, {useState} from 'react'; import {ConnectPaymentDetails} from '@stripe/react-connect-js'; const PaymentDetailsModal = ({paymentId, onClose}) => { return (
{ console.log('Payment details closed'); onClose(); }} onLoaderStart={({elementTagName}) => { console.log('Loading payment details...'); }} onLoadError={({error}) => { console.error('Failed to load payment:', error); alert(`Error: ${error.message}`); }} />
); }; // Usage example const App = () => { const [selectedPayment, setSelectedPayment] = useState(null); return ( <> {selectedPayment && ( setSelectedPayment(null)} /> )} ); }; export default App; ``` ### ConnectPaymentDisputes - Payment Disputes Component Displays disputes associated with a specific payment, with callbacks for dispute count tracking. ```jsx import React, {useState} from 'react'; import {ConnectPaymentDisputes} from '@stripe/react-connect-js'; const PaymentDisputesPanel = ({paymentId}) => { const [disputeCount, setDisputeCount] = useState(0); return (

Disputes {disputeCount > 0 && `(${disputeCount})`}

{ console.log(`Loaded ${total} disputes`); setDisputeCount(total); if (total > 0) { // Send notification or analytics event window.analytics?.track('disputes_detected', {count: total}); } }} onLoaderStart={({elementTagName}) => { console.log('Loading disputes...'); }} onLoadError={({error}) => { console.error('Disputes load failed:', error); }} />
); }; export default PaymentDisputesPanel; ``` ### ConnectDisputesList - All Disputes List Shows a comprehensive list of all disputes for the connected account. ```jsx import React from 'react'; import {ConnectDisputesList} from '@stripe/react-connect-js'; const DisputesPage = () => { return (

Disputes

Manage and respond to payment disputes

{ console.log('Loading disputes list...'); }} onLoadError={({error}) => { console.error('Failed to load disputes:', error); // Send error to monitoring service window.Sentry?.captureException(error); }} />
); }; export default DisputesPage; ``` ## Payout Components ### ConnectPayouts - Payouts Overview Displays payout summary and management interface for the connected account. ```jsx import React, {useEffect} from 'react'; import {ConnectPayouts} from '@stripe/react-connect-js'; const PayoutsPage = () => { useEffect(() => { document.title = 'Payouts - Dashboard'; }, []); return (

Payouts

View and manage your payouts

{ console.log('Payouts component loading'); }} onLoadError={({error, elementTagName}) => { console.error('Payouts failed to load:', error); alert('Unable to load payouts. Please refresh the page.'); }} />
); }; export default PayoutsPage; ``` ### ConnectPayoutsList - Detailed Payouts List Shows a comprehensive list of all payouts with filtering and sorting capabilities. ```jsx import React from 'react'; import {ConnectPayoutsList} from '@stripe/react-connect-js'; const PayoutsListPage = () => { return (
{ console.log('Loading payouts list...'); }} onLoadError={({error}) => { console.error('Error loading payouts list:', error); }} />
); }; export default PayoutsListPage; ``` ### ConnectPayoutDetails - Payout Detail View Displays detailed information for a specific payout with a close callback. ```jsx import React, {useState} from 'react'; import {ConnectPayoutDetails} from '@stripe/react-connect-js'; const PayoutDetailsDrawer = ({payoutId, isOpen, onClose}) => { if (!isOpen) return null; return (
e.stopPropagation()}> { console.log(`Closed payout details for ${payoutId}`); onClose(); }} onLoaderStart={({elementTagName}) => { console.log('Loading payout details...'); }} onLoadError={({error}) => { console.error('Failed to load payout:', error); }} />
); }; // Usage example const App = () => { const [drawerOpen, setDrawerOpen] = useState(false); const [selectedPayout, setSelectedPayout] = useState(null); const handleViewPayout = (payoutId) => { setSelectedPayout(payoutId); setDrawerOpen(true); }; return ( <> setDrawerOpen(false)} /> ); }; export default App; ``` ### ConnectInstantPayoutsPromotion - Instant Payouts Feature Displays promotional content for instant payouts with event tracking for conversions. ```jsx import React, {useState} from 'react'; import {ConnectInstantPayoutsPromotion} from '@stripe/react-connect-js'; const InstantPayoutsPromo = () => { const [promotionVisible, setPromotionVisible] = useState(false); const [instantPayouts, setInstantPayouts] = useState([]); return (
{promotionVisible && (
New Feature Available!
)} { console.log(`Promotion shown: ${promotionShown}`); setPromotionVisible(promotionShown); if (promotionShown) { // Track promotion impression window.analytics?.track('instant_payouts_promo_shown'); } }} onInstantPayoutCreated={({payoutId}) => { console.log(`Instant payout created: ${payoutId}`); setInstantPayouts(prev => [...prev, payoutId]); // Track conversion window.analytics?.track('instant_payout_created', {payoutId}); alert('Instant payout created successfully!'); }} onLoaderStart={({elementTagName}) => { console.log('Loading instant payouts promotion...'); }} onLoadError={({error}) => { console.error('Promotion load error:', error); }} />
); }; export default InstantPayoutsPromo; ``` ## Account Management Components ### ConnectAccountOnboarding - Account Setup Flow Provides a complete onboarding flow for connected accounts with customizable terms of service and collection options. ```jsx import React, {useState} from 'react'; import {ConnectAccountOnboarding} from '@stripe/react-connect-js'; const OnboardingFlow = ({accountId, onComplete}) => { const [currentStep, setCurrentStep] = useState(''); const [isLoading, setIsLoading] = useState(true); return (
{isLoading ? 'Loading...' : `Current Step: ${currentStep}`}
{ console.log('Onboarding exited'); if (window.confirm('Are you sure you want to exit onboarding?')) { onComplete(false); } }} onStepChange={(stepChange) => { console.log('Step changed:', stepChange); setCurrentStep(stepChange.step || 'Unknown'); setIsLoading(false); // Track onboarding progress window.analytics?.track('onboarding_step_changed', { step: stepChange.step, accountId: accountId }); }} recipientTermsOfServiceUrl="https://example.com/recipient-tos" fullTermsOfServiceUrl="https://example.com/connect-tos" privacyPolicyUrl="https://example.com/privacy" skipTermsOfServiceCollection={false} collectionOptions={{ fields: 'eventually_due', futureRequirements: 'include' }} onLoaderStart={({elementTagName}) => { console.log('Onboarding component loading...'); setIsLoading(true); }} onLoadError={({error}) => { console.error('Onboarding load error:', error); setIsLoading(false); alert('Failed to load onboarding. Please try again.'); }} />
); }; export default OnboardingFlow; ``` ### ConnectAccountManagement - Account Settings Displays account management interface for updating connected account information. ```jsx import React from 'react'; import {ConnectAccountManagement} from '@stripe/react-connect-js'; const AccountSettingsPage = () => { return (

Account Settings

Update your business information and preferences

{ console.log('Loading account management...'); }} onLoadError={({error}) => { console.error('Account management load error:', error); // Send to error tracking window.Sentry?.captureException(error, { tags: {component: 'account-management'} }); }} />
); }; export default AccountSettingsPage; ``` ### ConnectNotificationBanner - Notification Display Shows important notifications and alerts for the connected account with action tracking. ```jsx import React, {useState, useEffect} from 'react'; import {ConnectNotificationBanner} from '@stripe/react-connect-js'; const NotificationSystem = () => { const [notificationCount, setNotificationCount] = useState({ total: 0, actionRequired: 0 }); useEffect(() => { // Update page title with notification count if (notificationCount.actionRequired > 0) { document.title = `(${notificationCount.actionRequired}) Notifications`; } }, [notificationCount]); return (
{notificationCount.actionRequired > 0 && ( {notificationCount.actionRequired} Action Required )}
{ console.log(`Notifications: ${total} total, ${actionRequired} require action`); setNotificationCount({total, actionRequired}); // Send notification to parent window or analytics window.parent?.postMessage({ type: 'notifications_update', data: {total, actionRequired} }, '*'); }} onLoaderStart={({elementTagName}) => { console.log('Loading notifications...'); }} onLoadError={({error}) => { console.error('Notification banner error:', error); }} />
); }; export default NotificationSystem; ``` ## Financial Components ### ConnectBalances - Account Balances Displays current balance information for the connected account across all currencies. ```jsx import React from 'react'; import {ConnectBalances} from '@stripe/react-connect-js'; const BalancesWidget = () => { return (

Available Balance

{ console.log('Loading balances...'); }} onLoadError={({error}) => { console.error('Balances load error:', error); // Show fallback UI or error message }} />
); }; export default BalancesWidget; ``` ### ConnectFinancialAccount - Financial Account Details Shows detailed information for a specific financial account including account and routing numbers. ```jsx import React from 'react'; import {ConnectFinancialAccount} from '@stripe/react-connect-js'; const FinancialAccountDetails = ({financialAccountId}) => { return (

Financial Account

Account ID: {financialAccountId}

{ console.log('Loading financial account details...'); }} onLoadError={({error}) => { console.error('Financial account load error:', error); alert('Unable to load financial account details'); }} />
); }; // Usage example const App = () => { return ( ); }; export default App; ``` ### ConnectFinancialAccountTransactions - Transaction History Displays transaction history for a specific financial account with filtering capabilities. ```jsx import React, {useState} from 'react'; import {ConnectFinancialAccountTransactions} from '@stripe/react-connect-js'; const TransactionsPage = ({financialAccountId}) => { const [loading, setLoading] = useState(true); return (

Transactions

{ console.log('Loading transactions...'); setLoading(true); }} onLoadError={({error}) => { console.error('Transactions load error:', error); setLoading(false); // Show error notification window.showNotification?.('error', 'Failed to load transactions'); }} />
); }; export default TransactionsPage; ``` ## Issuing Components ### ConnectIssuingCard - Card Display Displays a virtual or physical issuing card with spend controls and card switching capabilities. ```jsx import React from 'react'; import {ConnectIssuingCard} from '@stripe/react-connect-js'; const CardDisplay = ({defaultCardId}) => { // Function to fetch ephemeral key for secure card operations const fetchEphemeralKey = async ({issuingCard, nonce}) => { const response = await fetch('/api/issuing/ephemeral-key', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({issuingCard, nonce}) }); if (!response.ok) { throw new Error('Failed to fetch ephemeral key'); } const data = await response.json(); return { issuingCard: data.issuingCard, nonce: data.nonce, ephemeralKeySecret: data.ephemeralKeySecret }; }; return (

Your Card

{ console.log('Loading card...'); }} onLoadError={({error}) => { console.error('Card load error:', error); alert('Unable to load card. Please contact support.'); }} />
); }; // Usage example const App = () => { return ; }; export default App; ``` ### ConnectIssuingCardsList - Multiple Cards Management Shows a list of all issuing cards with filtering by program and spend control management. ```jsx import React, {useState} from 'react'; import {ConnectIssuingCardsList} from '@stripe/react-connect-js'; const CardsManagementPage = ({issuingProgramId}) => { const [error, setError] = useState(null); const fetchEphemeralKey = async ({issuingCard, nonce}) => { try { const response = await fetch('/api/issuing/ephemeral-key', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({issuingCard, nonce}) }); const data = await response.json(); return { issuingCard: data.issuingCard, nonce: data.nonce, ephemeralKeySecret: data.ephemeralKeySecret }; } catch (err) { console.error('Ephemeral key fetch error:', err); throw err; } }; return (

Manage Cards

{error &&
{error}
}
{ console.log('Loading cards list...'); setError(null); }} onLoadError={({error}) => { console.error('Cards list load error:', error); setError(error.message); }} />
); }; export default CardsManagementPage; ``` ## Tax Components ### ConnectTaxRegistrations - Tax Registration Management Manages tax registrations across different countries with lifecycle event callbacks. ```jsx import React, {useState} from 'react'; import {ConnectTaxRegistrations} from '@stripe/react-connect-js'; const TaxRegistrationsPage = () => { const [registrations, setRegistrations] = useState([]); return (

Tax Registrations

Manage your tax registrations across countries

{ console.log(`Tax registration added: ${id}`); setRegistrations(prev => [...prev, id]); // Trigger backend sync fetch('/api/tax-registrations/sync', { method: 'POST', body: JSON.stringify({registrationId: id}) }); // Show success message window.showNotification?.('success', 'Tax registration added successfully'); }} onAfterTaxRegistrationExpired={({id}) => { console.log(`Tax registration expired: ${id}`); setRegistrations(prev => prev.filter(regId => regId !== id)); // Send alert email fetch('/api/notifications/tax-expiry', { method: 'POST', body: JSON.stringify({registrationId: id}) }); alert('A tax registration has expired. Please update your information.'); }} onLoaderStart={({elementTagName}) => { console.log('Loading tax registrations...'); }} onLoadError={({error}) => { console.error('Tax registrations load error:', error); }} />
); }; export default TaxRegistrationsPage; ``` ### ConnectTaxSettings - Tax Configuration Provides tax settings configuration including product tax codes and head office location. ```jsx import React, {useState} from 'react'; import {ConnectTaxSettings} from '@stripe/react-connect-js'; const TaxSettingsPage = () => { const [lastUpdated, setLastUpdated] = useState(null); return (

Tax Settings

{lastUpdated && (

Last updated: {new Date(lastUpdated).toLocaleString()}

)}
{ console.log(`Tax settings updated: ${id}`); setLastUpdated(Date.now()); // Sync with backend systems fetch('/api/tax-settings/updated', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ settingsId: id, timestamp: Date.now() }) }); // Show confirmation window.showNotification?.('success', 'Tax settings updated successfully'); }} onLoaderStart={({elementTagName}) => { console.log('Loading tax settings...'); }} onLoadError={({error}) => { console.error('Tax settings load error:', error); alert('Failed to load tax settings. Please try again.'); }} />
); }; export default TaxSettingsPage; ``` ## Document Management ### ConnectDocuments - Document Upload and Management Provides document upload and management interface for connected accounts. ```jsx import React, {useState} from 'react'; import {ConnectDocuments} from '@stripe/react-connect-js'; const DocumentsPage = () => { const [isLoading, setIsLoading] = useState(false); return (

Documents

Upload and manage verification documents

{isLoading &&
Loading...
}
{ console.log('Loading documents component...'); setIsLoading(true); }} onLoadError={({error}) => { console.error('Documents load error:', error); setIsLoading(false); // Log error to monitoring service window.Sentry?.captureException(error, { tags: {component: 'documents'}, extra: {timestamp: Date.now()} }); }} />
); }; export default DocumentsPage; ``` ## Advanced Integration Examples ### Complete Dashboard with Multiple Components Full dashboard integration showing multiple Connect components working together. ```jsx import React, {useState} from 'react'; import {loadConnectAndInitialize} from '@stripe/connect-js'; import { ConnectComponentsProvider, ConnectBalances, ConnectPayments, ConnectPayouts, ConnectNotificationBanner, ConnectAccountManagement } from '@stripe/react-connect-js'; const Dashboard = () => { const [activeTab, setActiveTab] = useState('overview'); const [notificationCount, setNotificationCount] = useState(0); // Initialize Connect with custom appearance const fetchClientSecret = async () => { const response = await fetch('/api/account_session', { method: 'POST', headers: {'Content-Type': 'application/json'} }); const {client_secret} = await response.json(); return client_secret; }; const connectInstance = loadConnectAndInitialize({ publishableKey: process.env.REACT_APP_STRIPE_PUBLISHABLE_KEY, fetchClientSecret: fetchClientSecret, appearance: { variables: { colorPrimary: '#0066cc', colorBackground: '#f7f9fc', colorText: '#1a1a1a', colorDanger: '#cc0000', fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif', borderRadius: '8px' } } }); return (
{ setNotificationCount(actionRequired); }} onLoadError={({error}) => { console.error('Notification error:', error); }} /> {activeTab === 'overview' && (

Dashboard Overview

{ console.error('Balances error:', error); }} />
)} {activeTab === 'payments' && (

Payments

{ console.error('Payments error:', error); }} />
)} {activeTab === 'payouts' && (

Payouts

{ console.error('Payouts error:', error); }} />
)} {activeTab === 'settings' && (

Account Settings

{ console.error('Settings error:', error); }} />
)}
); }; export default Dashboard; ``` ## Custom Hooks Integration ### useCreateComponent - Core Component Hook The internal hook that powers all Connect components, useful for building custom component wrappers. ```jsx import {useCreateComponent} from '@stripe/react-connect-js'; import {useUpdateWithSetter} from '@stripe/react-connect-js'; // Example: Creating a custom wrapper component const CustomPaymentsComponent = ({filters, onError}) => { const {wrapper, component} = useCreateComponent('payments'); // Use the setter utility to update component properties useUpdateWithSetter(component, filters, (comp, val) => { comp.setDefaultFilters(val); }); useUpdateWithSetter(component, onError, (comp, val) => { comp.setOnLoadError(val); }); return (
Custom Payments View
{wrapper}
); }; // Usage const App = () => { return ( console.error(error)} /> ); }; export default App; ``` ## Error Handling and Monitoring ### Comprehensive Error Handling Pattern Best practices for handling errors across all Connect components with logging and user feedback. ```jsx import React, {useState, useCallback} from 'react'; import { ConnectComponentsProvider, ConnectPayments, ConnectAccountOnboarding } from '@stripe/react-connect-js'; import {loadConnectAndInitialize} from '@stripe/connect-js'; const ErrorBoundary = ({children}) => { const [error, setError] = useState(null); if (error) { return (

Something went wrong

{error.message}

); } return children; }; const App = () => { const [globalError, setGlobalError] = useState(null); const [componentErrors, setComponentErrors] = useState({}); const handleLoadError = useCallback((component) => ({error, elementTagName}) => { console.error(`[${component}] Load error:`, error); // Log to monitoring service window.Sentry?.captureException(error, { tags: { component: component, elementTagName: elementTagName }, level: 'error' }); // Track in analytics window.analytics?.track('connect_component_error', { component: component, error: error.message, timestamp: Date.now() }); // Update local state setComponentErrors(prev => ({ ...prev, [component]: error.message })); // Show user-friendly message setGlobalError(`Failed to load ${component}. Please refresh the page or contact support.`); }, []); const fetchClientSecret = async () => { try { const response = await fetch('/api/account_session', { method: 'POST', headers: {'Content-Type': 'application/json'} }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const {client_secret} = await response.json(); return client_secret; } catch (error) { console.error('Failed to fetch client secret:', error); setGlobalError('Unable to initialize payment system. Please try again later.'); throw error; } }; const connectInstance = loadConnectAndInitialize({ publishableKey: process.env.REACT_APP_STRIPE_PUBLISHABLE_KEY, fetchClientSecret: fetchClientSecret, appearance: { variables: { colorPrimary: '#0066cc' } } }); return ( {globalError && (
Error: {globalError}
)}
{ console.log('Payments loading...'); // Clear previous errors setComponentErrors(prev => ({...prev, payments: null})); }} /> {componentErrors.payments && (
Error loading payments: {componentErrors.payments}
)}
); }; export default App; ``` ## Summary React Connect.js provides a declarative and type-safe way to integrate Stripe Connect embedded components into React applications. The library covers the complete spectrum of Connect functionality including payment processing, account onboarding, financial account management, issuing card operations, payout handling, tax compliance, and document management. Each component is designed to be composable and works seamlessly with React's component lifecycle and hooks system. The main integration pattern involves wrapping your application with `ConnectComponentsProvider`, initializing the Connect instance with your publishable key and a client secret fetching function, and then rendering individual Connect components as needed. All components support lifecycle callbacks for loading states and error handling, enabling robust production implementations with proper monitoring and user feedback. The library abstracts away DOM manipulation complexity while providing full access to component functionality through setter methods and event callbacks, making it ideal for building comprehensive financial dashboards, merchant onboarding flows, and payment management interfaces.