Skip to content

API Reference

OpenCheckout provides a Checkout Sessions REST API for one-time Open Payments checkouts.

Authentication

All API requests require an API key:

Authorization: Bearer sk_YOUR_API_KEY

Manage keys from the dashboard at /dashboard/keys.

Idempotency

Pass an Idempotency-Key header to prevent duplicate session creation:

Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000

Keys expire after 24 hours.

Endpoints

POST /api/checkout/sessions

Create a new checkout session.

Request Body:

{
"mode": "payment",
"line_items": [
{
"price_data": {
"currency": "usd",
"product_data": {
"name": "Product name",
"description": "Optional description"
},
"unit_amount": 2000
},
"quantity": 1
}
],
"success_url": "https://example.com/success?session_id={CHECKOUT_SESSION_ID}",
"cancel_url": "https://example.com/cancel",
"metadata": {
"order_id": "123"
},
"expires_in_seconds": 86400
}
FieldTypeRequiredDescription
modestringYespayment
line_itemsarrayYes1–100 items
line_items[].price_data.currencystringYesThree-letter asset code; normalized to lowercase
line_items[].price_data.product_data.namestringYesProduct name (1–200 chars)
line_items[].price_data.product_data.descriptionstringNoProduct description
line_items[].price_data.unit_amountintegerYesPrice in the currency’s smallest unit
line_items[].quantityintegerNoDefault: 1
success_urlstringYesRedirect URL on success
cancel_urlstringYesRedirect URL on cancel
metadataobjectNoArbitrary key-value pairs
expires_in_secondsintegerNo300–86400 (default: 86400)

Use {CHECKOUT_SESSION_ID} in URLs — it’s replaced with the actual session ID.

Response (201):

{
"id": "cs_abc123xyz",
"object": "checkout.session",
"status": "open",
"url": "https://checkout.yourdomain.com/pay/cs_abc123xyz",
"amount_total": 2000,
"currency": "usd",
"mode": "payment",
"line_items": [{
"price_data": {
"currency": "usd",
"product_data": { "name": "Product name", "description": "Optional description" },
"unit_amount": 2000
},
"quantity": 1
}],
"metadata": {},
"success_url": "https://example.com/success?session_id=cs_abc123xyz",
"cancel_url": "https://example.com/cancel",
"customer_wallet": null,
"incoming_payment": null,
"outgoing_payment": null,
"expires_at": "2026-06-16T00:00:00Z",
"created_at": "2026-06-15T00:00:00Z",
"completed_at": null
}

GET /api/checkout/sessions/:id

Retrieve a checkout session.

Response: The public snake_case session object. Grant tokens, continuation URIs, merchant IDs, nonces, and authorization-server details are never returned.

GET /api/checkout/sessions

List sessions (paginated).

Query ParamTypeDefaultDescription
limitinteger10Max 100
cursorstring-Pagination cursor

The list response includes has_more and next_cursor. Pass next_cursor as the next request’s cursor.

POST /api/checkout/sessions/:id/expire

Expire an open or awaiting_approval session.

POST /api/checkout/sessions/:id/cancel

Cancel an open or awaiting_approval session.

Session statuses

StatusMeaning
openReady for a wallet submission
preparingIncoming payment, quote, and grant are being prepared
awaiting_approvalCustomer approval can be resumed at the wallet provider
processingApproval succeeded and payment completion is being reconciled
completedPayment instruction completed
expiredSession passed its expiry or was explicitly expired
canceledSession was canceled

Webhooks

Configure a webhook URL in your merchant settings. OpenCheckout sends POST requests with:

Headers:

Content-Type: application/json
OpenCheckout-Signature: t=1234567890,v1=abc123...

Body:

{
"id": "cs_abc123xyz",
"status": "completed",
"amount_total": 2000,
"currency": "usd",
"metadata": { "order_id": "123" },
"outgoing_payment": "https://...",
"customer_wallet": "https://..."
}

Verify the signature using HMAC-SHA256 with your webhook secret:

payload = timestamp + "." + JSON.stringify(body)
signature = HMAC-SHA256(webhook_secret, payload)

GET /api/health

Health check endpoint. Returns server status and uptime.