docs
Get startedTroubleshootingPaymentsWebhooksAgent paymentsSwop MCPOviIdentity (swop.id)SwivyRPC (preview)API reference

Framed checkout

Put Swop's checkout inside an iframe on your own page, so buyers never leave your site.

Check availability before you build

Framed checkout needs a signing secret configured on Swop's side. If it isn't set, POST /embed-token returns a 400 and checkout can't be framed. Mint one test token first; if it fails with a configuration message, use headless checkout instead (it doesn't depend on framing) and contact support.

How it works

Framing is locked down so that a leaked API key can't put your checkout on someone else's website:

  1. You register your website once, in the Swop app, while signed in. An API key can't do this.
  2. Your server mints a short-lived embed token for one registered website and one checkout.
  3. Your page frames the checkout with that token. Swop checks the token when the frame loads.
PieceWho does itWhere
Register https://shop.acme.comYou, onceSwop app → Dashboard → Developer
Mint tokenYour server, every page loadPOST /embed-token with scope commerce.embed
Show checkoutThe buyer's browser<iframe src=".../checkout/<intentId>?embed_token=...">

1. Register your website

In Dashboard → Developer → Sites allowed to frame your checkout, add your origin, for example https://shop.acme.com.

  • https only. http://localhost and http://127.0.0.1 are allowed for development.
  • Just the origin: no path, query string, fragment or wildcard.
  • Register every exact origin you use. https://acme.com and https://www.acme.com are different.

2. Mint an embed token on your server

There are two kinds of token:

scopeFramesNeedsLifetime
intent (default)One checkout you created with POST /checkout-intentsintentId10 minutes
storeYour Swop cart pagestoreHandle (your Swop handle)5 minutes
curl -X POST https://apps.apiswop.co/api/v5/merchant/embed-token \
  -H "Authorization: Bearer $SWOP_MERCHANT_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "scope": "intent", "intentId": "co_7Hk2mPq9xR4s", "origin": "https://shop.acme.com" }'
Response
{
  "state": "success",
  "data": {
    "token": "eyJzYyI6ImludGVudCIs….Q2x…",
    "scope": "intent",
    "origin": "https://shop.acme.com",
    "expiresIn": 600
  }
}

If the origin isn't registered you get a 403 that names it: https://shop.acme.com is not a registered embed origin for this merchant. Add it in the Swop app first.

3. Frame it

Use the checkoutUrl returned when you created the checkout, and append the token.

<iframe
  src="https://www.swopme.app/checkout/co_7Hk2mPq9xR4s?embed_token=TOKEN"
  style="width:100%;min-height:720px;border:0">
</iframe>

<!-- or your whole Swop cart -->
<iframe src="https://www.swopme.app/sp/acme/cart?embed_token=TOKEN" style="width:100%;min-height:720px;border:0"></iframe>

Mint a fresh token for each page view. Tokens are tied to one origin and one checkout (or one store) and expire within minutes.

Store scope starts empty

The Swop cart lives in the browser's storage on swopme.app, so your site can't pre-fill it. If you want to pass your own cart into the frame, create a checkout with POST /checkout-intents and frame that intent.

Knowing when it's paid

The frame handles payment. For your systems, listen for checkout.paid or poll GET /checkout-intents/{intentId}.

On this page