Checkout Sessions
Create hosted checkout flows dynamically from your backend
Checkout sessions are API-created hosted checkout flows for an invoice. Your backend creates a session for an invoice that already exists, RevKeen returns a hosted checkout url, and you redirect the customer there. The session charges the invoice's amount due.
If the customer can open the hosted invoice page at /i/{token}, send them there instead. Use a checkout session when your backend has to control the checkout, for example to choose the allowed payment methods or to hand off to a companion device. To collect for something that is not yet an invoice, create the invoice first and finalize it.
Best For
- Backend-controlled checkout for an existing invoice
- Choosing allowed payment methods per checkout
- Card-present handoff scenarios using a companion device
Supported Create Parameters
| Field | Description |
|---|---|
invoice_id | Required. The invoice to collect. An invoice in draft is refused with 400: finalize it first. |
currency | Currency code. If you omit it, your default currency is used |
success_url | Redirect after successful payment |
cancel_url | Redirect if the customer cancels |
allowed_methods | Rails for this session: card, direct_debit, and/or in_store. Intersected with merchant capabilities. pay_by_bank is refused. |
companion_device_id | Link the session to a specific in-store companion device |
productId and amountMinor are no longer accepted. A request that sends either, or any other key not listed above, is refused with 400 that names the key.
Field names are snake_case. The camelCase spellings invoiceId, successUrl, cancelUrl, allowedMethods and companionDeviceId are still accepted for now: a request that uses one gets a Deprecation header and a Link to this page. Sending both spellings of one field with different values is a 400 that names the snake_case field. Move to the snake_case names.
TypeScript Example
const { data: invoice } = await client.invoices.create({
customer_uuid: "11111111-1111-4111-8111-111111111111",
total_minor: 2500,
currency: "GBP",
});
await client.invoices.finalize(invoice.id);
const session = await client.checkoutSessions.create({
invoice_id: invoice.id,
success_url: "https://example.com/success",
cancel_url: "https://example.com/cancel",
allowed_methods: ["card", "direct_debit"],
});
if (!session.data?.url) throw new Error("Checkout Session create returned no hosted URL");
return redirect(session.data.url);Example Response Shape
{
"data": {
"id": "cs_123",
"url": "https://pay.revkeen.com/p/rvk_cs_example",
"status": "open",
"publicToken": "rvk_cs_example",
"currency": "USD",
"allowed_methods": ["card"],
"expires_at": "2026-04-21T15:30:00Z"
}
}Notes on Session Usage
- An invoice payment-method override can narrow your enabled payment rails, but cannot re-enable a disabled rail. Disabling a rail also removes it from future sessions resolved for existing invoices. If no enabled rail can collect the invoice currency, session resolution refuses instead of selecting a disabled card rail.
- If you have no online payment method enabled and live for the session (or none that can collect the requested currency), create returns
503withcode: "NO_PAYMENT_METHODS_AVAILABLE"and no session is created. Enable a payment method in Settings โ Payments, or use a currency an enabled method supports, then retry. Retrying without changing your configuration returns the same response. - Always redirect to the
urlreturned by the API. Do not construct checkout URLs manually. - Checkout sessions are best for one purchase flow at a time.
- If you want a reusable sales URL, use a checkout link.
- If your flow depends on card-present routing or per-checkout payment-method control, checkout sessions are the correct API.
Retrieve or Expire a Session
RevKeen also supports:
GET /v2/checkout-sessions/{id}to retrieve a sessionPOST /v2/checkout-sessions/{id}/expireto expire an open session
cURL Example
curl -X POST "https://api.revkeen.com/v2/checkout-sessions" \
-H "x-api-key: $REVKEEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"invoiceId": "22222222-2222-4222-8222-222222222222",
"successUrl": "https://example.com/success",
"cancelUrl": "https://example.com/cancel",
"allowedMethods": ["card"]
}'Related
- Checkout Links -- Reusable hosted checkout URLs
- Terminal -- Card-present and in-store payment flows
Reopening a reusable link
When a completed session is rebound to a reusable payment link, payment methods
are resolved against the current configuration. If that resolution fails, the
request returns 503 RAILS_UNRESOLVED without creating a new session. If the
link strategy leaves no available methods, it returns 409 RAILS_UNAVAILABLE.
The previous session's methods are not a fallback: they may predate a rail suspension.
Owner: david ยท Reviewed 5 Sep 2026