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:
- You register your website once, in the Swop app, while signed in. An API key can't do this.
- Your server mints a short-lived embed token for one registered website and one checkout.
- Your page frames the checkout with that token. Swop checks the token when the frame loads.
| Piece | Who does it | Where |
|---|---|---|
Register https://shop.acme.com | You, once | Swop app → Dashboard → Developer |
| Mint token | Your server, every page load | POST /embed-token with scope commerce.embed |
| Show checkout | The 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.
httpsonly.http://localhostandhttp://127.0.0.1are allowed for development.- Just the origin: no path, query string, fragment or wildcard.
- Register every exact origin you use.
https://acme.comandhttps://www.acme.comare different.
2. Mint an embed token on your server
There are two kinds of token:
scope | Frames | Needs | Lifetime |
|---|---|---|---|
intent (default) | One checkout you created with POST /checkout-intents | intentId | 10 minutes |
store | Your Swop cart page | storeHandle (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" }'{
"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}.