Stripe | Financial Infrastructure to Grow Your Revenue

Stripe | Financial Infrastructure to Grow Your Revenue

4466 articles

Build an integration with an embedded form


Public preview

Build an integration with an embedded form Public preview

The following guide describes how to use the embedded form with Checkout Sessions.

You can also build and preview your embedded Checkout form through Checkout studio, which provides a centralized Dashboard page for configuring and monitoring your Checkout integrations.

Set up Stripe Server-side

First, create a Stripe account or sign in.

Use our official libraries to access the Stripe API from your application:

Command Line

Select a language

Ruby

Python

PHP

Java

Node.js

Go

.NET

No results

# Available as a gem
sudo gem install stripe

Gemfile

Select a language

Ruby

Python

PHP

Java

Node.js

Go

.NET

No results

# If you use bundler, you can add this line to your Gemfile
gem 'stripe'

Enable payment methods

By default, Stripe uses your payment methods settings to determine which payment methods the embedded form presents. You can also configure specific payment methods on your Checkout Session using the payment_method_types attribute.

Create a Checkout Session Server-side

Create a Checkout Session on your server to control the payment flow. The Checkout Session defines your line items, shipping options, and other settings for the payment.

Command Line

Select a language

cURL

Stripe CLI

Ruby

Python

PHP

Java

Node.js

Go

.NET

No results

Set ui_mode to form to integrate with the embedded form. The returned CheckoutSession object includes a client secret, which the client uses to securely display the checkout interface.

The Checkout Sessions API supports an optional integration_identifier parameter you can set when creating a session. Use it to label this form integration with a recognizable name and measure its conversion independently from other Checkout integrations you run.

You can also configure the following options on the CheckoutSession:

  • automatic_tax : Enable automatic tax calculation
  • automatic_tax[address_collection_precision] : Control billing address collection in embedded forms for tax calculation when automatic tax is enabled
  • billing_address_collection : Collect billing addresses
  • customer_email : Prefill the customer’s email address
  • customer : Prefill customer data from an existing Customer object
  • name_collection : Collect your customers’ business name, individual name, or both
  • shipping_address_collection : Collect shipping addresses
  • shipping_options : Provide shipping rate options
  • submit_type : Specify the type of transaction being performed
  • phone_number_collection : Collect your customer’s phone number
  • tax_id_collection : Collect tax IDs
  • allow_promotion_codes : Allow customer-redeemable promotion codes

Unsupported CheckoutSession parameters

The embedded form doesn’t support consent_collection.

Set up Stripe Elements Client-side

The embedded form is available as a feature of Stripe.js. Install React Stripe.js and the Stripe.js loader from the npm public registry.

Command Line

npm install --save @stripe/react-stripe-js @stripe/stripe-js

Create clientSecret as a Promise<string> | string containing the client secret returned by your server. Wrap your application with the CheckoutFormProvider component, passing in clientSecret and the stripe instance.

App.jsx

Create and mount Client-side

The embedded form contains an iframe that securely sends the payment information to Stripe over an HTTPS connection.

The CheckoutForm component is already rendered inside CheckoutFormProvider in the previous step. No additional mounting is required for React.

You can specify the layout to render the embedded form as a single-step or multi-step embedded form.

Prefill customer email

You can prefill the customer’s email address using one of two approaches, depending on whether you want the email to be editable.

Set the email on the Checkout Session (non-editable)

Pass customer_email when creating the Checkout Session on your server. The email is displayed in the embedded form but the customer can’t change it. You can also pass a Customer ID to the customer field to prefill the email stored on the Customer.

Set a default email on the client (editable)

Pass defaultValues.email when initializing the SDK to prefill an editable email. The customer can modify this value in the embedded form.

App.jsx

<CheckoutFormProvider
 stripe={stripePromise}
 options={{
 clientSecret,
 defaultValues: {
 email: 'customer@example.com',
 },
 }}
>
 <CheckoutForm />
</CheckoutFormProvider>

Finalize payment Client-side

The Checkout Session you created on the server automatically determines the line items, total amount, and available payment methods. The embedded form uses this information to display the appropriate interface.

Handle payment confirmation

Handle the confirm event when your customer finalizes their payment:

App.jsx

Handle errors

The embedded form automatically shows localized customer-facing error messages during client confirmation. If a problem prevents the confirm method from continuing, the confirm method can raise an exception. Catch and handle those exceptions.

App.jsx

const onConfirm = async (event) => {
 if (checkoutState.type === 'success') {
 try {
 await checkoutState.checkout.confirm({formConfirmEvent: event});
 } catch (error) {
 console.error('Payment confirmation error:', error);
 }
 }
};

Customize redirect behavior

By default, after a successful payment, the embedded form redirects your customer to the return_url that you specify when you create the Checkout Session. To prevent redirects for payment methods that don’t require a redirect, such as cards, set redirect to 'if_required' when calling confirm. To learn more, see Customize redirect behavior.

Handle post-payment events Server-side

The Checkout Session defines your line items, shipping options, and other settings for the payment. After a customer confirms payment on the client, handle the result on your server rather than relying on client-side state.

  • Webhooks Recommended : Listen for the checkout.session.completed event, which Stripe sends when the payment succeeds. This approach ensures you’re notified even if the customer closes their browser before the redirect.
  • Return page : Retrieve the Checkout Session using its ID to check the payment status and show the appropriate result to your customer on the page you set as the return _ url .

Learn how to fulfill orders after receiving a payment.

Test the integration

Before you go live, test each payment method integration. Click Pay to complete the payment, which redirects you to the specified return page.

If you see the return page, and the payment appears in the list of successful payments in the Dashboard, your integration is working.

Use Stripe’s test card numbers to test card payments. For example:

Payment succeeds

Payment requires 3DS authentication

Payment is declined

Customize the layout and appearance

You can customize the embedded form by setting its options or by using the Appearance API.

Layout

Use the layout option to control how the embedded form presents checkout steps.

  • Expanded : Use this layout for a single-step checkout. It’s ideal for traditional checkout forms that sit directly on the web page.
  • Compact Private preview : Use this layout for multi-step checkout. It’s ideal for more compact UI layouts like modals, popups, and chat UIs.

When you leave layout undefined, Stripe renders the layout it determines has the best conversion.

Request access to the compact layout

The compact layout displays the embedded form as a multi-step checkout flow. It's available by request in private preview. Enter your email address below to request access.

App.jsx

const checkoutFormOptions = {
 layout: 'expanded',
};

<CheckoutForm
 options={checkoutFormOptions}
 onConfirm={onConfirm}
/>

Embedded form options

You can configure the appearance of each express payment method button and pass saved contacts using options.

App.jsx

const checkoutFormOptions = {
 expressCheckout: {
 buttonTheme: {
 applePay: 'white-outline'
 },
 paymentMethods: {
 applePay: 'always'
 }
 }
};

<CheckoutForm
 options={checkoutFormOptions}
 onConfirm={onConfirm}
/>

The embedded form supports the following options:

expressCheckout.buttonThemeSpecify a theme per one-click payment button. See buttonTheme.
expressCheckout.paymentMethodsSpecify which one-click payment buttons show. See paymentMethods.
contactsAn array of objects representing saved addresses, each containing name, address, and phone properties. See contacts.

Appearance API

You can use the Appearance API to control the style of the embedded form by applying a theme or updating specific details. However, the embedded form doesn’t support the rules option.

For instance, choose the “flat” theme and override the primary text color.

App.jsx

const appearance = {
 theme: 'flat',
 variables: { colorPrimaryText: '#262626' }
};

<CheckoutFormProvider
 stripe={stripePromise}
 options={{
 clientSecret,
 appearance
 }}
>
 <CheckoutForm />
</CheckoutFormProvider>

Disclose Stripe to your customers

Stripe collects information on customer interactions with Elements to provide services to you, prevent fraud, and improve its services. This includes using cookies and IP addresses to identify which Elements a customer saw during a single checkout session. You’re responsible for disclosing and obtaining all rights and consents necessary for Stripe to use data in these ways. For more information, visit our privacy center.

See also

Last verified 2026-09-24

Is this helpful?