CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-stripe--react-stripe-js

React components and hooks for Stripe.js and Elements payment processing integration

Pending
Overview
Eval results
Files

checkout-components.mddocs/

Checkout Flow Components

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 Path

import {
  CheckoutProvider,
  useCheckout,
  BillingAddressElement,
  ShippingAddressElement,
  CurrencySelectorElement,
  PaymentElement,
  ExpressCheckoutElement,
  TaxIdElement
} from "@stripe/react-stripe-js/checkout";

Capabilities

CheckoutProvider

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;
}

useCheckout Hook

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>
  );
};

BillingAddressElement

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;
  };
}

ShippingAddressElement

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>
  );
};

CurrencySelectorElement

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;
}

Checkout-Optimized PaymentElement

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[];
}

Checkout-Optimized ExpressCheckoutElement

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;
  };
}

Checkout-Optimized TaxIdElement

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;

Error Handling in Checkout Flows

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

docs

address-elements.md

bank-elements.md

card-elements.md

checkout-components.md

core-providers-hooks.md

embedded-checkout.md

index.md

message-elements.md

payment-elements.md

tile.json