# @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 (
<>
setSelectedPayment('pi_3ABC123xyz')}>
View Payment
{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 (
{
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 (
Dashboard / Payouts
{
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 (
<>
handleViewPayout('po_1ABC123xyz')}>
View Payout Details
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 (
{
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 (
{
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
window.location.reload()}>
Refresh
{
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 (
{
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 (
{
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 (
{
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 (
setActiveTab('overview')}
>
Overview
setActiveTab('payments')}
>
Payments
setActiveTab('payouts')}
>
Payouts
setActiveTab('settings')}
>
Settings
{notificationCount > 0 && (
{notificationCount}
)}
{
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}
setError(null)}>Try Again
);
}
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}
setGlobalError(null)}>Dismiss
)}
{
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.