HASH PAY Docs
Docs/Reference/Checkout Sessions
API reference

Checkout Sessions

When the amount isn't fixed in advance — a cart total, metered usage, a custom quote — your server creates a Checkout Session with a secret key, and the embed opens it. It's the only safe way to charge an arbitrary amount.

Fixed prices don't need this — use a Price and skip your backend entirely. Reach for Sessions only when the amount is computed at request time.

Create a session

POST/v1/checkout/sessionsBearer sk_…

Request

FieldNotes
amountCentsrequiredPositive integer, USD cents. 1575 = $15.75.
successUrloptionalWhere to send the buyer after they pay.
metadataoptionalString key/value, echoed on this payment's webhooks.
create-session.shcurl
curl https://api.hashpay.dev/v1/checkout/sessions \
  -H "Authorization: Bearer sk_live_2kfPqR…" \
  -H "Content-Type: application/json" \
  -d '{
        "amountCents": 1575,
        "successUrl": "https://shop.example.com/thanks",
        "metadata": { "cartId": "cart_9" }
      }'

Response · 201

sessionjson
{
  "sessionId": "cs_abc123…",
  "mode": "live",
  "amountCents": 1575,
  "expiresAt": "2026-06-29T12:00:00Z"
}

Both the session's mode and the store it belongs to (branding + webhook routing) come from the key — an sk_test_ key makes a test session for its store. Sessions expire 24 hours after creation.

Open it in the browser

Send the sessionId to your front-end and hand it to the embed. The buyer picks chain + token and pays the session's amount:

checkout.jsjavascript
HashPay.checkout({ sessionId: 'cs_abc123…' })

Or declaratively: <button data-hashpay-session="cs_abc123…">Pay</button>. See the Embed SDK.

Errors

CodeHTTPWhen
unauthorized401Missing or invalid secret key.
account_disabled403Account is banned.
bad_amount400amountCents not a positive integer.
bad_request400Malformed body, or metadata over the limits (≤20 keys, ≤2 KB).