---
title: Use Bolder checkout with your own cart
description: Keep your own cart and backend, create the order through the API and use only Bolder's checkout, embedded or as a redirect.
---

Goal: your site already has a cart (or no cart at all, like a booking flow). Your backend creates the order in Bolder and the customer pays in Bolder's checkout. Nothing else of the Storefront SDK is needed.

## 1. Create the order on your server

Follow [Create an order and take payment](/guides/create-an-order) and return the order's `checkout_url` to the browser. Never call the API from the browser with your token.

```js
// e.g. POST /api/orders on your server
const order = await bolder.client.post('/orders', {
  shop_id: 1234,
  external_id: cart.id,
  contact: { name, email },
  line_items: cart.items.map((i) => ({ variant_sku: i.sku, units: i.quantity }))
})
res.json({ checkout_url: order.checkout_url })
```

## 2. Open the checkout

```bash
npm install bolder-checkout
# or the script tag: https://assets.bolder.run/checkout.umd.cjs
```

**Embedded**

The checkout opens in a slide-out panel over your page:

```js
import { openCheckout } from 'bolder-checkout'

const { checkout_url } = await fetch('/api/orders', { method: 'POST' }).then((r) => r.json())

const session = openCheckout({ checkoutUrl: checkout_url })
session.on('success', () => showConfirmation())
session.on('closed', () => console.log('checkout closed'))
```

When a gateway needs a redirect (PayPal, Webpay, Khipu), the SDK navigates the whole window and the customer comes back to your page afterwards (see step 3).

**Redirect**

The customer goes to Bolder's checkout page and comes back to `returnUrl` (the current page by default):

```js
import { redirectToCheckout } from 'bolder-checkout'

redirectToCheckout({ checkoutUrl: checkout_url, returnUrl: 'https://mysite.com/thanks' })
```

The return URL's host must be the shop's domain or an allowed embed origin.

## 3. Detect the return

Load `bolder-checkout` on the page the customer returns to. It reads and removes the `checkout_session` and `checkout_status` parameters when it loads and fires an event:

```js
document.addEventListener('bolder:checkout:return', (e) => {
  const { sessionCode, status } = e.detail // 'success' | 'cancelled'
  if (status === 'success') showConfirmation(sessionCode)
})
```

Components that mount later can call `getLastReturn()` instead.

## 4. Confirm on your server

The browser event is for the UI. To update your own records, subscribe to order events: see [Receive order webhooks](/guides/receive-webhooks).

## Next

- [Checkout reference](/frontend/sdk/checkout)
- [Agentic checkout (UCP)](/frontend/sdk/ucp) for AI agents that buy on a customer's behalf.
