KashuDocs

Checkout sessions

A checkout session is one amount for a buyer to pay through Kashu's card form. Your server makes the session, your page shows the form with the session's client secret, and the form takes the card and pays. You never handle the card.

Make a session

curl https://api.kashupay.com/v1/checkout_sessions \
  -H "Authorization: Bearer $KASHU_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount":4999,"currency":"USD","success_url":"https://shop.example.com/thanks?order=1001","customer":"cu_...","metadata":{"order":"1001"}}'

The answer holds the session's id, which starts cs_, and its client_secret. The client secret appears only in this response. Keep it with the order while the buyer pays, and hand it to your page.

Show the form

Mount the card form with the client secret, as Card form and Kashu.js shows. The form reads the session, shows the amount, and pays it with the buyer's card.

Fulfil the order on the webhook

Fulfil the order when your server receives checkout.session.completed, not on a browser event: anything running on the page could fake one. A session completes once, when its payment succeeds, or is authorized when the session captures manually.

if (event.type === "checkout.session.completed") {
  const session = event.data.object;
  fulfil(session.metadata.order, session.payment);
}

If a card is declined, the session stays open and the buyer can try another card. A session can never be paid twice.

Read a session's state

Field Meaning
status open while it can take payment, complete once paid, expired once it can no longer be paid.
payment_status unpaid, processing while the card network answers, authorized when held for capture, paid once captured.
payment The latest payment made for the session.

GET /v1/checkout_sessions/{id} reads one session. GET /v1/checkout_sessions lists them, newest first, and takes status and customer filters.

Expire a session

Expire a session you no longer want paid with POST /v1/checkout_sessions/{id}/expire. A session whose payment is in flight or made cannot be expired, and answers 400 checkout_session_unexpected_state. Kashu also expires an open session once its expires_at passes with no payment in flight. Either way, Kashu sends checkout.session.expired.