React components and hooks for Stripe.js and Elements payment processing integration
—
Specialized components and providers for optimized checkout experiences. These components are available from the /checkout entry point and provide enhanced functionality for checkout-specific workflows.
import {
CheckoutProvider,
useCheckout,
BillingAddressElement,
ShippingAddressElement,
CurrencySelectorElement,
PaymentElement,
ExpressCheckoutElement,
TaxIdElement
} from "@stripe/react-stripe-js/checkout";Specialized context provider for checkout flows that extends Elements functionality with checkout-specific state management.
/**
* React context provider for checkout flows
* @param props - Checkout provider configuration props
* @returns JSX element wrapping child components with checkout context
*/
function CheckoutProvider(props: CheckoutProviderProps): JSX.Element;
interface CheckoutProviderProps {
/** Stripe instance or Promise resolving to Stripe instance */
stripe: PromiseLike<Stripe | null> | Stripe | null;
/** Checkout configuration options - REQUIRED */
options: StripeCheckoutOptions;
/** Child components that will have access to checkout context */
children: ReactNode;
}React hook for accessing checkout state and functionality within checkout flows.
/**
* Hook to access checkout state from CheckoutProvider context
* @returns Current checkout state
*/
function useCheckout(): CheckoutState;
type CheckoutState =
| {type: 'loading'}
| {type: 'success'; checkout: CheckoutValue}
| {type: 'error'; error: {message: string}};
type CheckoutValue = StripeCheckoutActions & StripeCheckoutSession;
interface StripeCheckoutActions {
/** Confirm the checkout payment */
confirm(): Promise<{error?: StripeError}>;
/** Cancel the checkout session */
cancel(): void;
/** Redirect to the checkout URL */
redirect(): void;
}Usage Examples:
import React from 'react';
import { CheckoutProvider, useCheckout } from '@stripe/react-stripe-js/checkout';
import { loadStripe } from '@stripe/stripe-js';
const stripePromise = loadStripe('pk_test_...');
const CheckoutStatus = () => {
const checkoutState = useCheckout();
switch (checkoutState.type) {
case 'loading':
return <div>Loading checkout...</div>;
case 'success':
return (
<div className="checkout-success">
<h2>Checkout Ready</h2>
<button onClick={() => checkoutState.checkout.confirm()}>
Confirm Payment
</button>
<button onClick={() => checkoutState.checkout.cancel()}>
Cancel
</button>
</div>
);
case 'error':
return (
<div className="checkout-error">
<h2>Checkout Error</h2>
<p>{checkoutState.error.message}</p>
</div>
);
default:
return null;
}
};
const CheckoutFlow = ({ checkoutSessionId }) => {
return (
<CheckoutProvider stripe={stripePromise}>
<div className="checkout-container">
<h1>Complete Your Purchase</h1>
<CheckoutStatus />
</div>
</CheckoutProvider>
);
};Specialized address element optimized for billing address collection in checkout flows.
/**
* Billing address element for checkout flows
* @param props - Billing address element configuration props
* @returns JSX element for billing address collection
*/
function BillingAddressElement(props: BillingAddressElementProps): JSX.Element;
interface BillingAddressElementProps extends ElementProps {
/** Configuration options for billing address */
options?: StripeCheckoutAddressElementOptions;
/** Triggered when the Element is fully rendered */
onReady?: (element: StripeAddressElement) => any;
/** Triggered when the escape key is pressed */
onEscape?: () => any;
/** Triggered when the Element fails to load */
onLoadError?: (event: {elementType: 'address'; error: StripeError}) => any;
/** Triggered when the loader UI is mounted */
onLoaderStart?: (event: {elementType: 'address'}) => any;
}
interface StripeCheckoutAddressElementOptions {
/** Fields to collect */
fields?: {
phone?: 'auto' | 'always' | 'never';
};
/** Address validation options */
validation?: {
mode?: 'auto' | 'always' | 'never';
};
/** Default values */
defaultValues?: {
name?: string;
address?: {
line1?: string;
line2?: string;
city?: string;
state?: string;
postal_code?: string;
country?: string;
};
phone?: string;
};
}Specialized address element optimized for shipping address collection in checkout flows.
/**
* Shipping address element for checkout flows
* @param props - Shipping address element configuration props
* @returns JSX element for shipping address collection
*/
function ShippingAddressElement(props: ShippingAddressElementProps): JSX.Element;
interface ShippingAddressElementProps extends ElementProps {
/** Configuration options for shipping address */
options?: StripeCheckoutAddressElementOptions;
/** Triggered when the Element is fully rendered */
onReady?: (element: StripeAddressElement) => any;
/** Triggered when the escape key is pressed */
onEscape?: () => any;
/** Triggered when the Element fails to load */
onLoadError?: (event: {elementType: 'address'; error: StripeError}) => any;
/** Triggered when the loader UI is mounted */
onLoaderStart?: (event: {elementType: 'address'}) => any;
}Address Elements Usage Example:
import React, { useState } from 'react';
import {
CheckoutProvider,
BillingAddressElement,
ShippingAddressElement,
PaymentElement
} from '@stripe/react-stripe-js/checkout';
const CheckoutForm = ({ stripePromise }) => {
const [billingAddress, setBillingAddress] = useState(null);
const [shippingAddress, setShippingAddress] = useState(null);
const [sameAsShipping, setSameAsShipping] = useState(false);
const handleBillingChange = (event) => {
if (event.complete) {
setBillingAddress(event.value);
}
};
const handleShippingChange = (event) => {
if (event.complete) {
setShippingAddress(event.value);
if (sameAsShipping) {
setBillingAddress(event.value);
}
}
};
return (
<CheckoutProvider stripe={stripePromise}>
<form className="checkout-form">
<div className="address-section">
<h3>Shipping Address</h3>
<ShippingAddressElement
options={{
fields: {
phone: 'always'
},
validation: {
mode: 'auto'
}
}}
onChange={handleShippingChange}
/>
</div>
<div className="billing-section">
<label>
<input
type="checkbox"
checked={sameAsShipping}
onChange={(e) => setSameAsShipping(e.target.checked)}
/>
Same as shipping address
</label>
{!sameAsShipping && (
<>
<h3>Billing Address</h3>
<BillingAddressElement
options={{
fields: {
phone: 'never'
}
}}
onChange={handleBillingChange}
/>
</>
)}
</div>
<div className="payment-section">
<h3>Payment Information</h3>
<PaymentElement />
</div>
<button
type="submit"
disabled={!billingAddress || !shippingAddress}
>
Complete Purchase
</button>
</form>
</CheckoutProvider>
);
};Currency selection element for international checkout flows (requires beta access).
/**
* Currency selector element for international checkouts
* Requires beta access - contact Stripe support for more information
* @param props - Currency selector element configuration props
* @returns JSX element for currency selection
*/
function CurrencySelectorElement(props: CurrencySelectorElementProps): JSX.Element;
interface CurrencySelectorElementProps extends ElementProps {
/** Triggered when the Element is fully rendered */
onReady?: (element: StripeCurrencySelectorElement) => any;
/** Triggered when the escape key is pressed */
onEscape?: () => any;
/** Triggered when the Element fails to load */
onLoadError?: (event: {elementType: 'currencySelector'; error: StripeError}) => any;
/** Triggered when the loader UI is mounted */
onLoaderStart?: (event: {elementType: 'currencySelector'}) => any;
}Specialized PaymentElement optimized for checkout flows with enhanced options.
/**
* Payment element optimized for checkout flows
* @param props - Checkout payment element configuration props
* @returns JSX element for payment method collection
*/
function PaymentElement(props: CheckoutPaymentElementProps): JSX.Element;
type CheckoutPaymentElementProps = Omit<PaymentElementProps, 'options'> & {
/** Checkout-specific payment element options */
options?: StripeCheckoutPaymentElementOptions;
};
interface StripeCheckoutPaymentElementOptions extends StripePaymentElementOptions {
/** Enhanced layout options for checkout */
layout?: {
type?: 'tabs' | 'accordion' | 'auto';
defaultCollapsed?: boolean;
radios?: boolean;
spacedAccordionItems?: boolean;
};
/** Checkout-specific payment method configuration */
paymentMethodOrder?: string[];
}Express checkout element optimized for checkout flows.
/**
* Express checkout element optimized for checkout flows
* @param props - Checkout express checkout element configuration props
* @returns JSX element for express payment methods
*/
function ExpressCheckoutElement(props: CheckoutExpressCheckoutElementProps): JSX.Element;
type CheckoutExpressCheckoutElementProps = Omit<
ExpressCheckoutElementProps,
'options' | 'onClick' | 'onCancel' | 'onShippingAddressChange' | 'onShippingRateChange'
> & {
/** Checkout-specific express checkout options */
options?: StripeCheckoutExpressCheckoutElementOptions;
};
interface StripeCheckoutExpressCheckoutElementOptions {
/** Payment method types to enable */
paymentMethods?: {
applePay?: 'auto' | 'always' | 'never';
googlePay?: 'auto' | 'always' | 'never';
link?: 'auto' | 'always' | 'never';
};
/** Button theme customization */
buttonTheme?: {
applePay?: 'black' | 'white' | 'white-outline';
googlePay?: 'black' | 'white';
};
/** Layout configuration for checkout */
layout?: {
maxColumns?: number;
maxRows?: number;
};
}Tax ID element optimized for business checkout flows.
/**
* Tax ID element optimized for checkout flows
* @param props - Checkout tax ID element configuration props
* @returns JSX element for tax ID collection
*/
function TaxIdElement(props: CheckoutTaxIdElementProps): JSX.Element;
interface CheckoutTaxIdElementProps extends TaxIdElementProps {
/** Checkout-specific tax ID options */
options: StripeCheckoutTaxIdElementOptions;
}
interface StripeCheckoutTaxIdElementOptions extends StripeTaxIdElementOptions {
/** Required for checkout flows */
required?: boolean;
/** Checkout-specific tax ID types */
supportedTypes?: Array<{
type: string;
country: string;
required?: boolean;
}>;
}Complete Checkout Flow Example:
import React, { useState } from 'react';
import {
CheckoutProvider,
useCheckout,
BillingAddressElement,
ShippingAddressElement,
PaymentElement,
ExpressCheckoutElement,
CurrencySelectorElement,
TaxIdElement
} from '@stripe/react-stripe-js/checkout';
import { loadStripe } from '@stripe/stripe-js';
const stripePromise = loadStripe('pk_test_...');
const FullCheckoutFlow = () => {
const [step, setStep] = useState('shipping');
const [addresses, setAddresses] = useState({
shipping: null,
billing: null
});
const [businessCheckout, setBusinessCheckout] = useState(false);
const CheckoutSteps = () => {
const checkoutState = useCheckout();
const handleShippingComplete = (address) => {
setAddresses(prev => ({ ...prev, shipping: address }));
setStep('billing');
};
const handleBillingComplete = (address) => {
setAddresses(prev => ({ ...prev, billing: address }));
setStep('payment');
};
const handlePaymentSubmit = async () => {
if (checkoutState.type === 'success') {
try {
const result = await checkoutState.checkout.confirm();
if (result.error) {
console.error('Payment failed:', result.error);
} else {
setStep('complete');
}
} catch (error) {
console.error('Checkout error:', error);
}
}
};
return (
<div className="checkout-steps">
{step === 'shipping' && (
<div className="step">
<h2>Shipping Information</h2>
<ShippingAddressElement
options={{
fields: { phone: 'always' },
validation: { mode: 'auto' }
}}
onChange={(event) => {
if (event.complete) {
handleShippingComplete(event.value);
}
}}
/>
</div>
)}
{step === 'billing' && (
<div className="step">
<h2>Billing Information</h2>
<label>
<input
type="checkbox"
checked={businessCheckout}
onChange={(e) => setBusinessCheckout(e.target.checked)}
/>
This is a business purchase
</label>
<BillingAddressElement
options={{
fields: { phone: 'never' },
defaultValues: addresses.shipping
}}
onChange={(event) => {
if (event.complete) {
handleBillingComplete(event.value);
}
}}
/>
{businessCheckout && (
<div className="business-info">
<h3>Business Information</h3>
<TaxIdElement
options={{
required: true,
supportedTypes: [
{ type: 'us_ein', country: 'US', required: true },
{ type: 'eu_vat', country: 'DE' }
]
}}
/>
</div>
)}
</div>
)}
{step === 'payment' && (
<div className="step">
<h2>Payment Method</h2>
<div className="express-checkout">
<ExpressCheckoutElement
options={{
paymentMethods: {
applePay: 'auto',
googlePay: 'auto',
link: 'auto'
},
buttonTheme: {
applePay: 'black',
googlePay: 'black'
}
}}
/>
<div className="divider">or</div>
</div>
<PaymentElement
options={{
layout: {
type: 'tabs',
defaultCollapsed: false
},
paymentMethodOrder: ['card', 'klarna', 'afterpay_clearpay']
}}
/>
<button
onClick={handlePaymentSubmit}
disabled={checkoutState.type !== 'success'}
className="submit-payment"
>
Complete Purchase
</button>
</div>
)}
{step === 'complete' && (
<div className="step">
<h2>Order Complete!</h2>
<p>Thank you for your purchase.</p>
</div>
)}
</div>
);
};
return (
<CheckoutProvider stripe={stripePromise}>
<div className="checkout-container">
<div className="checkout-progress">
<div className={`step ${step === 'shipping' ? 'active' : ''}`}>
Shipping
</div>
<div className={`step ${step === 'billing' ? 'active' : ''}`}>
Billing
</div>
<div className={`step ${step === 'payment' ? 'active' : ''}`}>
Payment
</div>
</div>
<CheckoutSteps />
</div>
</CheckoutProvider>
);
};
export default FullCheckoutFlow;const CheckoutWithErrorHandling = () => {
const [errors, setErrors] = useState({});
const handleElementError = (elementType) => (event) => {
if (event.error) {
setErrors(prev => ({
...prev,
[elementType]: event.error.message
}));
} else {
setErrors(prev => {
const newErrors = { ...prev };
delete newErrors[elementType];
return newErrors;
});
}
};
const hasErrors = Object.keys(errors).length > 0;
return (
<CheckoutProvider stripe={stripePromise}>
<div className="checkout-with-errors">
{hasErrors && (
<div className="error-summary">
<h3>Please fix the following errors:</h3>
<ul>
{Object.entries(errors).map(([element, error]) => (
<li key={element}>
<strong>{element}:</strong> {error}
</li>
))}
</ul>
</div>
)}
<ShippingAddressElement
onChange={handleElementError('shipping')}
onLoadError={handleElementError('shipping')}
/>
<BillingAddressElement
onChange={handleElementError('billing')}
onLoadError={handleElementError('billing')}
/>
<PaymentElement
onChange={handleElementError('payment')}
onLoadError={handleElementError('payment')}
/>
<button disabled={hasErrors}>
Complete Purchase
</button>
</div>
</CheckoutProvider>
);
};Install with Tessl CLI
npx tessl i tessl/npm-stripe--react-stripe-js