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.
success_urlis where the buyer goes once the session is paid: anhttpspage, or a local page in test mode.cancel_urlis optional, for a page the buyer can go back to.- Without
customer, the form asks for the buyer's email and makes a customer for you. capture_methodmanualauthorizes the amount instead of taking it. Capture it later withPOST /v1/payments/{id}/capture.expires_at, in Unix seconds, is 30 minutes to 24 hours away. It is 24 hours when you leave it out.
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.