Ask for an invitation
Menu

Endpoint

Create a checkout session

POST/v1/checkout_sessions

Creates the session and, unless order is given, its order. With a publishable key only payment_link, quantity, amount (open-amount links), client_reference_id and customer_email are accepted, and the link must have allow_publishable_key: true.

Scope a restricted key needs
checkout_sessions:write
Publishable key
Allowed
Idempotency-Key
Recommended. It makes a retry safe.

Parameters

Parameters of Create a checkout session
ParameterType and placeMeaning
Orrerie-VersionstringheaderAPI version date. Default: the version the key was created with. Example 2026-10-11.
Idempotency-KeystringheaderMakes a retry safe. Kept 24 hours. 1 to 255 characters.

Request body

A JSON object. The body is required. A field the call does not list is refused with parameter_unknown.

Request body of Create a checkout session
FieldTypeMeaning
orderstringAn existing open order to pay. If absent, give amount + currency or line_items and an order is created.
amountstringThe price. Up to 2 decimals for fiat, up to the asset's decimals for a crypto pricing currency. Minimum the equivalent of US$1.00. Pattern ^\d+(\.\d+)?$.
currencystringPricing currency: ISO 4217 code (USD) or asset id (bitcoin:btc). Required with amount.
line_itemsarray of valuesUp to 100 items, each {price, quantity} or {name, unit_amount, quantity}. The order amount is their sum. Not allowed together with amount.
descriptionstringShown to the payer above the amount. Up to 500 characters.
referencestringYour order number. Up to 200 characters.
customerstringA cus_ id. It is kept with that customer.
customer_emailstringKept, encrypted, and returned as customer_email. No receipt is emailed in this release.
success_urlstringHTTPS URL the payer is sent to after payment. May contain {CHECKOUT_SESSION_ID} and {ORDER_ID}. Required unless payment_link is given (the session then takes the link's).
cancel_urlstringHTTPS URL behind the "Back to shop" link.
client_reference_idstringEchoed back on the session and in events. Up to 200 characters.
collectobjectemail, name, shipping_address: each required, optional or hidden. Default email required, others hidden.
localestringauto (default) or en.
expires_inintegerSeconds the order stays payable: 900 to 604,800 (15 minutes to 7 days). Default the merchant setting (3,600).
fee_bearerstringOverrides the merchant default for this order. One of payer, merchant.
rails_allowedarray of valuesSubset of orrerie_app, relay, direct. Default: all the merchant has on.
acceptarray of valuesLimit what the payer may pay with: asset ids and/or orrerie_app. Each must be switched on for the merchant (asset_not_enabled). Empty or absent: everything switched on.
settlestringdefault (the merchant's settlement asset), keep (keep what was paid, no conversion), or one of the merchant's allowed settlement asset ids. Resolved to the merchant's own wallet by the server and frozen on the order; a caller can never supply an address.
modestringDefault payment. subscription needs subscription_data. One of payment, subscription.
subscription_dataobject{items: [{price, quantity}], grace_days, reminder_days}: creates the subscription when the first period is paid.
metadataobjectYour own key-value data (rules in Metadata).
payment_linkstringA plink_ id: the session takes its price, URLs and settings from the link.
quantityintegerWith payment_link: the quantity, within the link's limits.

Example request

curl

curl https://api.orrerie.com/v1/checkout_sessions \
  -H "Authorization: Bearer $ORRERIE_SECRET_KEY" \
  -H "Idempotency-Key: 8f14e45f-ceea-467f-a9d2-6f1c2b3d4e5a" \
  -H "Content-Type: application/json" \
  -d '{
  "amount": "21.99",
  "currency": "USD",
  "description": "Order #1042",
  "reference": "1042",
  "customer_email": "jane@example.com",
  "success_url": "https://acme.example/thanks?session={CHECKOUT_SESSION_ID}",
  "cancel_url": "https://acme.example/cart",
  "client_reference_id": "1042",
  "metadata": {
    "cart_id": "c_7781"
  }
}'

JavaScript

const response = await fetch("https://api.orrerie.com/v1/checkout_sessions", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.ORRERIE_SECRET_KEY}`,
    "Idempotency-Key": "8f14e45f-ceea-467f-a9d2-6f1c2b3d4e5a",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "amount": "21.99",
    "currency": "USD",
    "description": "Order #1042",
    "reference": "1042",
    "customer_email": "jane@example.com",
    "success_url": "https://acme.example/thanks?session={CHECKOUT_SESSION_ID}",
    "cancel_url": "https://acme.example/cart",
    "client_reference_id": "1042",
    "metadata": {
      "cart_id": "c_7781"
    }
  }),
});
const result = await response.json();
if (!response.ok) throw new Error(`${result.error.code}: ${result.error.message}`);
console.log(result);

Python

import os
import requests

response = requests.post(
    "https://api.orrerie.com/v1/checkout_sessions",
    headers={"Authorization": f"Bearer {os.environ['ORRERIE_SECRET_KEY']}", "Idempotency-Key": "8f14e45f-ceea-467f-a9d2-6f1c2b3d4e5a"},
    json={
        "amount": "21.99",
        "currency": "USD",
        "description": "Order #1042",
        "reference": "1042",
        "customer_email": "jane@example.com",
        "success_url": "https://acme.example/thanks?session={CHECKOUT_SESSION_ID}",
        "cancel_url": "https://acme.example/cart",
        "client_reference_id": "1042",
        "metadata": {
            "cart_id": "c_7781",
        },
    },
    timeout=30,
)
result = response.json()
if not response.ok:
    raise RuntimeError(f"{result['error']['code']}: {result['error']['message']}")
print(result)

PHP

<?php
$request = curl_init('https://api.orrerie.com/v1/checkout_sessions');
curl_setopt_array($request, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('ORRERIE_SECRET_KEY'),
        'Idempotency-Key: 8f14e45f-ceea-467f-a9d2-6f1c2b3d4e5a',
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'amount' => '21.99',
        'currency' => 'USD',
        'description' => 'Order #1042',
        'reference' => '1042',
        'customer_email' => 'jane@example.com',
        'success_url' => 'https://acme.example/thanks?session={CHECKOUT_SESSION_ID}',
        'cancel_url' => 'https://acme.example/cart',
        'client_reference_id' => '1042',
        'metadata' => [
            'cart_id' => 'c_7781',
        ],
    ]),
]);
$body = curl_exec($request);
if ($body === false) {
    throw new RuntimeException(curl_error($request));
}
$result = json_decode($body, true);
if (curl_getinfo($request, CURLINFO_HTTP_CODE) >= 400) {
    throw new RuntimeException($result['error']['code'] . ': ' . $result['error']['message']);
}
print_r($result);

Responses

201 Created

The answer is the checkout_session object. Headers: Orrerie-Request-Id.

Example response, 201

{
  "id": "cs_z7ek5wj68fyz80j7bz1eq4e0",
  "object": "checkout_session",
  "livemode": true,
  "created": "2026-10-11T14:03:22.418Z",
  "status": "open",
  "mode": "payment",
  "order": "ord_0zymngngvf12b8b2cra7tb8e",
  "url": "https://pay.orrerie.com/c/cs_z7ek5wj68fyz80j7bz1eq4e0",
  "app_url": "https://pay.orrerie.com/o/cs_z7ek5wj68fyz80j7bz1eq4e0",
  "success_url": "https://acme.example/thanks?session={CHECKOUT_SESSION_ID}",
  "cancel_url": "https://acme.example/cart",
  "customer": "cus_8ea07c40qsvv19f7rgmeb8ha",
  "customer_email": "jane@example.com",
  "client_reference_id": "1042",
  "collect": {
    "email": "required",
    "name": "optional",
    "shipping_address": "hidden"
  },
  "collected": {
    "email": null,
    "name": null,
    "shipping_address": null
  },
  "locale": "auto",
  "subscription": null,
  "expires_at": "2026-10-11T15:03:22.418Z",
  "completed_at": null,
  "metadata": {
    "cart_id": "c_7781"
  }
}

Any other status: an error

A status of 400 or above answers with the error object. Branch on its code, never on its message.

Errors

Beside the errors every call can answer with (a bad key, a missing scope, the rate limit), this call answers with:

Errors of Create a checkout session
CodeHTTPMeaning
parameter_missing400A required parameter is absent; error.param names it.
amount_below_minimum400Below the minimum: US$1.00 for an order payable on the relay rail, the network dust limit on the direct rail or for a payout.
tier_order_limit403error.limit is single_order: over the tier's single-order maximum (US$1,000 Unverified, US$50,000 Verified). Or first_orders: an Unverified merchant's first three paid orders may be at most US$250 each ("Your first three orders can be up to US$250 each.").
tier_open_orders_limit40350 (Unverified) or 2,000 (Verified) unpaid orders are open. Cancel or let some expire.
tier_volume_limit403error.window is 30_days: paid orders and unmatched payments you kept in the last 30 days, plus this one, would pass the tier limit (US$5,000 / US$250,000). Or lifetime: an Unverified merchant passed US$20,000 of such takings in total and must verify to create new orders. A reverted payment is taken back out.
currency_unsupported400Not a pricing currency the platform has a rate for.
price_unavailable503No fresh price for the asset or currency. A stale price is never used for a quote.
asset_not_enabled400The asset exists but is not switched on for this merchant.
settlement_invalid400settle names something that cannot be a settlement asset for this merchant.
url_invalid400Not https, has credentials, is over 2,048 characters, or (webhooks) resolves to a private address.
merchant_restricted403The merchant is restricted: new orders, payouts to others and conversions are off. Reads and withdrawals to saved addresses work.
order_not_open409The order is not open (or underpaid, for a top-up instruction).
support_email_required409The business has no support email yet, and no order can be created without one, in test mode too. A member adds it in the dashboard under Settings, Business profile, Support email; then retry.
merchant_closing403The business is closing: new orders, payment links and invoices are off, and money goes out only to its own saved addresses. Reads, exports and withdrawals to saved addresses work until it closes.
link_open_orders_limit409The payment link has 32 unpaid orders open, or has taken 240 orders in 24 hours, the most allowed. Open orders expire by themselves; retry later.