> This page is for Developer.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.bigcommerce.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.bigcommerce.com/_mcp/server.

# Embedded Checkout

Embedded Checkout lets you place BigCommerce’s Optimized One-Page checkout onto an external site. This tutorial will walk you through the sequence of API calls your application should make to create a working Embedded Checkout.

This article assumes you have familiarity with the following concepts:

* Creating and managing a server-side application
* Making and receiving API calls from within your app
* Using your application to make changes to a front end

### Prerequisites

Store-level or app-level API credentials with the following scopes:

| Resource         | Permission level |
| :--------------- | :--------------- |
| Carts            | `modify`         |
| Channel Settings | `modify`         |
| Sites & Routes   | `modify`         |
| Products         | `read-only`      |

For more information, see the [Guide to API Accounts](/developer/docs/overview/api-fundamentals/api-accounts#oauth-scopes).

* The [BigCommerce Checkout JS SDK (GitHub)](https://github.com/bigcommerce/checkout-sdk-js) must be accessible in the browser.

## Creating a channel

To allow an external website to serve the BigCommerce checkout, create a new channel by sending a request to the [Create a channel](/developer/api-reference/rest/admin/management/channels/create-channel) endpoint. A successful response contains an `id` that you can use as the `channel_id` in future requests.

#### Request

**`Request: Create a channel`**

```http title="Request: Create a channel"
POST https://api.bigcommerce.com/stores/{{store_hash}}/v3/channels
X-Auth-Token: {{access_token}}
Accept: application/json
Content-Type: application/json
{
  "type": "storefront",
  "platform": "custom",
  "name": "My Custom Store"
}
```

#### Response

**`Response: Create a channel`**

```json title="Response: Create a channel"
{
  "data": {
    "id": 20266,
    "name": "My Custom Store",
    "platform": "custom",
    "type": "storefront",
    "date_created": "2019-09-18T22:28:36Z",
    "date_modified": "2019-09-18T22:28:36Z",
    "external_id": "",
    "is_enabled": true
  },
  "meta": {}
}
```

> **Note**
>
> Channels created by API are visible in the store control panel's [channel manager](https://login.bigcommerce.com/deep-links/manage/channel-manager). You can also use the [advanced search feature on the products view page](https://login.bigcommerce.com/deep-links/manage/products/search), [sort customers by channel](https://login.bigcommerce.com/deep-links/manage/customers?limit=20\&page=1\&sortField=channel), and [create custom views of orders](https://login.bigcommerce.com/deep-links/manage/orders/create-view) to group or filter those entities by channel.

## Creating a site

Next, create a site for the channel by sending a request to the [Create a channel site](/developer/api-reference/rest/admin/management/channels/site/create-channel-site) endpoint. This returns an `id` that you can use as the `site_id` in future requests. The `url` value is the base path for all other routes you define for the site.

#### Request

**`Request: Create a site`**

```http title="Request: Create a site"
POST https://api.bigcommerce.com/stores/{{store_hash}}/v3/channels/{{channel_id}}/site
X-Auth-Token: {{access_token}}
Accept: application/json
Content-Type: application/json
{
  "channel_id": 20266,
  "url": "https://store.example.com"
}
```

#### Response

**`Response: Create a site`**

```json title="Response: Create a site"
{
  "data": {
    "id": 6,
    "url": "https://store.example.com",
    "channel_id": 20266,
    "created_at": "2019-09-19T17:08:44Z",
    "updated_at": "2019-09-19T17:08:44Z"
  },
  "meta": {}
}
```

## Creating a cart

To proceed to checkout, you need an active cart. To create one, send a request to the REST Management API's [Create a cart](/developer/api-reference/rest/admin/management/carts) endpoint.

**`Example request: Create a cart`**

```http title="Example request: Create a cart" showLineNumbers={false}
POST https://api.bigcommerce.com/stores/{{store_hash}}/v3/carts
X-Auth-Token: {{access_token}}
Accept: application/json
Content-Type: application/json

{
  "channel_id": 20266,
  "line_items": [
    {
      "quantity": 1,
      "product_id": 80,
      "variant_id": 64
    }
  ]
}
```

If you are creating a cart for a specific customer, pass in the `customer_id` in the request.

```json showLineNumbers={false}
{
  "customer_id": 42,
  "line_items": [
    {
      "quantity": 5,
      "product_id": 191
    }
  ]
}
```

The response contains a cart ID you can use in subsequent requests:

**`Example response: Create a cart`**

```json title="Example response: Create a cart" showLineNumbers={false}
  {
    "data": {
      "id": "33608b81-ba34-4ff2-8bab-2771aeab3f73",
    ...
    }
  }
```

To generate a cart redirect URL, send a request to the [Create cart redirect URL](/developer/api-reference/rest/admin/management/carts/redirects/create-cart-redirect-url) endpoint. Use the cart ID returned with the [Create a cart](/developer/api-reference/rest/admin/management/carts/carts-single/create-cart) response as the cartId path parameter value.

**`Example response: Create cart redirect URLs`**

```http title="Example response: Create cart redirect URLs" showLineNumbers={false}
POST https://api.bigcommerce.com/stores/{{store_hash}}/v3/carts/{{cartId}}/redirect_urls
X-Auth-Token: {{access_token}}
Accept: application/json
Content-Type: application/json

{
  "cart_url": "https://store-id30h7ohwf.mybigcommerce.com/cart.php?action=load&id=bc218c65-7a32-4ab7-8082-68730c074d02&token=aa958e2b7922035bf3339215d95d145ebd9193deb36ae847caa780aa2e003e4b",
  "checkout_url": "https://store-id30h7ohwf.mybigcommerce.com/cart.php?action=loadInCheckout&id=bc218c65-7a32-4ab7-8082-68730c074d02&token=aa958e2b7922035bf3339215d95d145ebd9193deb36ae847caa780aa2e003e4b",
  "embedded_checkout_url": "https://store-id30h7ohwf.mybigcommerce.com/cart.php?embedded=1&action=loadInCheckout&id=bc218c65-7a32-4ab7-8082-68730c074d02&token=aa958e2b7922035bf3339215d95d145ebd9193deb36ae847caa780aa2e003e4b"
}
```

### Redirecting a signed-in customer to embedded checkout

For some use cases, you may want your customer to sign in before they can begin the checkout process.

Customers can sign in using the [Customer Login API](/developer/docs/storefront/guides/customer-authentication/customer-login). Guest shoppers do not need to be signed in. Skip to [Embedding the checkout](#embedding-the-checkout) for more information on the guest shopper flow.

To redirect a signed-in customer, use the JSON Web Token Standard to create a Customer Login JWT. Use a [JWT library (jwt.io)](https://jwt.io/#libraries-io) to accomplish this. For more information, see [Create JWT Using the Debugger Tool](/developer/docs/storefront/guides/customer-authentication/customer-login#create-jwt-using-the-debugger-tool).

Next, include the `embedded_checkout_url` as part of the request payload you send to BigCommerce.

**`Example Customer Login JWT payload`**

```js title="Example Customer Login JWT payload" showLineNumbers={false}
{
  "iss": {{client_id}},
  "iat": 1535393113,
  "jti": {{uuid}},
  "operation": "customer_login",
  "store_hash": {{store_hash}},
  "customer_id": 2,
  "channel_id": 123,
  "redirect_to": "https://store-id30h7ohwf.mybigcommerce.com/cart.php?embedded=1&action=loadInCheckout&id=bc218c65-7a32-4ab7-8082-68730c074d02&token=aa958e2b7922035bf3339215d95d145ebd9193deb36ae847caa780aa2e003e4b",
  "request_ip": "111.222.333.444"
}
```

### Data properties in the Customer Login JWT

The following table clarifies where the data properties for the embedded checkout JWT differ from the [core Customer Login JWT properties](/developer/docs/storefront/guides/customer-authentication/customer-login#customer-login-jwt-payload-reference).

| Property      | Type        | Description                                                                                                                                              |
| :------------ | :---------- | :------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `operation`   | string      | The value is always `customer_login`.                                                                                                                    |
| `customer_id` | integer     | The ID of the customer who wants to check out.                                                                                                           |
| `channel_id`  | integer     | The sales channel that the customer is signing in to. In a headless implementation, this is the storefront's channel ID. Required for embedded checkout. |
| `redirect_to` | string, URL | The cart redirect URL you generated in a previous step.                                                                                                  |

## Embedding the checkout

Use the `embedded_checkout_url` that is returned from generating redirect URLs and assemble a JSON object. It will be used by the Checkout JS SDK to determine how to render the checkout.

> **Note**
>
> When the shopper is signed in, use the `https://{{store-url}}/login/token/{{token}}` URL as the `url` option for `embedCheckout`. For unauthenticated shoppers, use the `embedded_checkout_url` as the `url` option instead.

**`JSON Object`**

```json title="JSON Object" showLineNumbers={false}
{
  "containerId": "foo-bar-checkout",
  "url": "https://store-id30h7ohwf.mybigcommerce.com/cart.php?embedded=1&action=loadInCheckout&id=bc218c65-7a32-4ab7-8082-68730c074d02&token=aa958e2b7922035bf3339215d95d145ebd9193deb36ae847caa780aa2e003e4b"
}
```

Pass the object to the `embedCheckout` method of the Checkout SDK.

**`embedCheckout method`**

```js title="embedCheckout method" showLineNumbers={false}
embedCheckout({
  "containerId": "foo-bar-checkout",
  "url": "https://store-id30h7ohwf.mybigcommerce.com/cart.php?embedded=1&action=loadInCheckout&id=bc218c65-7a32-4ab7-8082-68730c074d02&token=aa958e2b7922035bf3339215d95d145ebd9193deb36ae847caa780aa2e003e4b"
});
```

This will render the checkout to an HTML element with the `id` you chose.

**`HTML element`**

```html title="HTML element" showLineNumbers={false}
<div id="foo-bar-checkout"></div>
```

Read more about the [JSON object (GitHub)](https://github.com/bigcommerce/checkout-sdk-js/blob/master/docs/README.md#embedcheckout) and its possible corresponding [rendering options (GitHub)](https://github.com/bigcommerce/checkout-sdk-js/blob/master/docs/interfaces/EmbeddedCheckoutOptions.md).

## FAQ

### How can I work with Embedded Checkout locally?

You can use ngrok to test Embedded Checkout locally.
Steps:

1. Start the development server using your local copy of the storefront.
2. Create an [ngrok tunnel (ngrok.com)](https://ngrok.com/docs#getting-started-expose) to serve your localhost over a fully-qualified SSL connection.
3. Set your Channel Site URL to the HTTPS URL of the ngrok tunnel.
4. View your checkout using the ngrok URL.

> **Note**
>
> Note: If you don't want to use ngrok, use [https://127.0.0.1](https://127.0.0.1) as the Channel site URL.

### Are hosted payment gateways supported with Embedded Checkout?

At this time, you cannot embed a checkout that uses a hosted payment gateway. See [Available Payment Gateways (Help Center)](https://support.bigcommerce.com/s/article/Available-Payment-Gateways#all-available) to determine which type of gateway you're using.

### How do I resolve Embedded Checkout 403 "Cannot start checkout session with an empty cart" Errors?

For Embedded Checkout to work correctly for shoppers using a browser with restricted privacy settings,like Apple's Safari, your checkout page must be served from the same domain as your BigCommerce storefront. For example, if your headless storefront is `www.mystore.com`, then your BigCommerce store's domain should be `checkout.mystore.com`. For more information on making Embedded Checkout on a headless WordPress storefront compatible with Safari, see [BigCommerce for WordPress (Help Center)](https://support.bigcommerce.com/s/article/BigCommerce-for-WordPress-Checkout#safari).

### How do I make sure that authenticated shoppers who sign out from the checkout page are also signed out of the headless storefront?

To ensure you sign shoppers out of the checkout page and the headless storefront, pass the `onSignOut` option to `embedCheckout` to handle sign out events from the checkout page.

## Related resources

* [Guide to API Accounts](/developer/docs/overview/api-fundamentals/api-accounts#oauth-scopes)
* [Customer Login API](/developer/docs/storefront/guides/customer-authentication/customer-login)
* [Create JWT Using the Debugger Tool](/developer/docs/storefront/guides/customer-authentication/customer-login#create-jwt-using-the-debugger-tool).
* [REST Management API, Channels](/developer/api-reference/rest/admin/management/channels#channels)
* [REST Management API, Carts](/developer/api-reference/rest/admin/management/carts)
* [Checkout JS SDK (GitHub)](https://github.com/bigcommerce/checkout-sdk-js)

### Help Center

* [Available Payment Gateways (Help Center)](https://support.bigcommerce.com/s/article/Available-Payment-Gateways#all-available)
* [BigCommerce for WordPress (Help Center)](https://support.bigcommerce.com/s/article/BigCommerce-for-WordPress-Checkout#safari)

### Store control panel

* [Channel manager](https://login.bigcommerce.com/deep-links/manage/channel-manager)
* [Advanced search feature on the products view page](https://login.bigcommerce.com/deep-links/manage/products/search)
* [Sort customers by channel](https://login.bigcommerce.com/deep-links/manage/customers?limit=20\&page=1\&sortField=channel)
* [Create custom views of orders](https://login.bigcommerce.com/deep-links/manage/orders/create-view)

### External

* [JWT library (jwt.io)](https://jwt.io/#libraries-io)
* [ngrok (ngrok.com)](https://ngrok.com/docs#getting-started-expose)