Checkout sessions
A checkout session is a short-lived URL on `pay.cimplify.io` that hosts the full checkout for a specific cart. You create one server-side with your secret key, redirect the customer to the URL, and listen for the resulting webhook.
Endpoints
| Method | Path | Auth |
|---|---|---|
POST | /v1/checkout/sessions | Secret key (Bearer) |
GET | /v1/checkout/sessions/{session_id} | Public; used by the hosted page itself |
Creating a session
curl https://api.cimplify.io/v1/checkout/sessions \
-H "Authorization: Bearer $CIMPLIFY_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"cart_id": "crt_01J5BGM…",
"public_key": "cpk_live_…",
"order_types": ["delivery", "pickup"],
"default_order_type": "delivery",
"currency": "GHS",
"submit_label": "Pay GH₵29.99",
"success_url": "https://store.example.com/orders/thanks",
"cancel_url": "https://store.example.com/cart",
"appearance": {
"theme": "light",
"variables": { "primaryColor": "#0a2540" }
},
"metadata": { "shipping_zone": "GH-AC" }
}'Request body: CreateCheckoutSessionRequest
| Field | Type | Required | Notes |
|---|---|---|---|
cart_id | string | yes | Existing cart on the same business. |
public_key | string | no | cpk_… embedded into the hosted page. Defaults to the business's primary public key. |
order_types | string[] | no | Subset of delivery | pickup | dine_in. |
default_order_type | string | no | Pre-selected order type. |
currency | string | no | ISO 4217 override. |
success_url | string | no | Cimplify redirects here on success with ?order_id=…&session_id=…. |
cancel_url | string | no | Renders a "Return to store" button. |
appearance | object | no | ElementAppearance. |
submit_label | string | no | Override Pay button copy. |
metadata | object | no | Free-form JSON, echoed on the resulting order. |
Response: CreateCheckoutSessionResponse
{
"id": "cs_01J5BGM…",
"url": "https://pay.cimplify.io/s/cs_01J5BGM…",
"status": "open",
"expires_at": "2026-05-07T17:00:00Z"
}SDK helper
From a server context with a secret key:
const r = await fetch("https://api.cimplify.io/v1/checkout/sessions", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.CIMPLIFY_SECRET_KEY!}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
cart_id: cart.id,
success_url: `${origin}/orders/thanks`,
cancel_url: `${origin}/cart`,
}),
});
if (!r.ok) throw new Error(await r.text());
const session = await r.json();
return Response.redirect(session.url, 303);Reading a session
GET /v1/checkout/sessions/:id returns the public-safe view of the session used by the hosted page. You generally don't call this directly, but it's useful for debugging or for building a custom-host alternative to pay.cimplify.io.
{
"id": "cs_…",
"status": "open",
"business_id": "biz_…",
"cart_id": "crt_…",
"public_key": "cpk_live_…",
"business": { "name": "…", "logo_url": "https://…" },
"cart": { "items": [...], "subtotal": "29.99", "tax_amount": "0.00", "total": "29.99", "currency": "GHS" },
"order_types": ["delivery", "pickup"],
"default_order_type": "delivery",
"appearance": { "theme": "light", "variables": { "primaryColor": "#0a2540" } },
"submit_label": "Pay GH₵29.99",
"success_url": "https://store.example.com/orders/thanks",
"cancel_url": "https://store.example.com/cart",
"expires_at": "2026-05-07T17:00:00Z"
}Lifecycle
| Status | Meaning |
|---|---|
open | Created and within expires_at. URL is usable. |
completed | Customer paid. An order exists; webhook fired. |
expired | Past expires_at. Returns HTTP 410 Gone on subsequent reads. Issue a new session. |
After completion
- Cimplify redirects the customer to
success_urlwith?order_idand?session_id. order.completedwebhook fires. Treat the webhook as the source of truth; never fulfill on the redirect alone.- If
cancel_urlis set and the customer hits the "Return to store" button instead of paying, they bounce there with no params.
Errors
| Status | Code | Meaning |
|---|---|---|
| 401 | UNAUTHORIZED | Missing or invalid API key. |
| 403 | FORBIDDEN | API key doesn't belong to the cart's business. |
| 404 | CART_NOT_FOUND | cart_id doesn't exist. |
| 410 | SESSION_GONE | Session expired. Create a new one. |
| 422 | VALIDATION_ERROR | Bad input (e.g. malformed appearance JSON). |
Next
- Payment links: For paying an existing order
- Webhooks: Source of truth for completion
CheckoutElement
The unified checkout iframe. It renders contact capture, saved details, address, payment, provider authorization, and submit. Identity is handed off to Cimplify OAuth through the parent SDK.
Payment links
A payment link is a short URL on `pay.cimplify.io/:token` that takes payment for an _already-existing_ order. Use these for invoicing flows: you bill someone offline, generate a token, drop the link into a WhatsApp / email / SMS, and the customer clicks through to settle.