Checkout Sessions API
Create and manage checkout sessions for one-time payments and subscriptions.
Create a Checkout Session
/api/v1/checkout-sessionsAuth: Server key required
Request Body
{
"amount": 99.99,
"currency": "USD",
"mode": "embedded",
"paymentType": "oneTime",
"successUrl": "https://yoursite.com/success?session_id={CHECKOUT_SESSION_ID}",
"cancelUrl": "https://yoursite.com/cancel",
"customer": {
"email": "[email protected]",
"name": "Jane Doe",
"phone": "+1234567890"
},
"lineItems": [
{
"name": "Pro Plan",
"quantity": 1,
"unitAmount": 99.99,
"description": "Monthly subscription"
}
],
"metadata": {
"orderId": "order_12345"
},
"expiresAt": "2025-01-16T10:30:00Z",
"allowSavedCards": true,
"enableClickToPay": true
}Response
{
"id": "cs_live_abc123",
"object": "checkout_session",
"status": "open",
"amount": 99.99,
"currency": "USD",
"mode": "embedded",
"paymentType": "oneTime",
"clientSecret": "cs_live_abc123_secret_xyz789",
"url": null,
"successUrl": "https://yoursite.com/success?session_id=cs_live_abc123",
"cancelUrl": "https://yoursite.com/cancel",
"customer": {
"email": "[email protected]",
"name": "Jane Doe"
},
"paymentStatus": "unpaid",
"expiresAt": "2025-01-16T10:30:00Z",
"createdAt": "2025-01-15T10:30:00Z"
}Return URL placeholder
Put {CHECKOUT_SESSION_ID} anywhere in successUrl or cancelUrl (as-is or percent-encoded). It is replaced with the session id when the session is created, so the hosted page redirects to, and the session reports, the final URL.
Paying an existing invoice
To collect an invoice you already issued, pass invoiceId (its numeric id) or invoiceReference (the reference code from its pay link, not the display invoice number). The session charges that invoice instead of creating one.
{
"invoiceReference": "INV-7F3K2Q",
"mode": "hosted",
"paymentType": "oneTime",
"successUrl": "https://yoursite.com/paid?session_id={CHECKOUT_SESSION_ID}"
}- Only with
paymentType: "oneTime". Sending both fields, orlineItems, is avalidation_error;descriptionis ignored. - Amount, currency and payment options come from the invoice (amount = its total due). If you also send
amount,currencyorpaymentOptionGroupId, they must match. - The invoice must be yours and in the same mode as your key; otherwise
404 invoice_not_found. - A paid, cancelled, rejected, expired, draft or zero-balance invoice is refused with
invoice_not_payable. - While a session on the invoice is still open, creating another returns that same session.
- If the session expires or is cancelled, your invoice is left as it was and can be paid later.
checkout.session.completedcarriesinvoiceIdandinvoiceReference.
Retrieve a Checkout Session
/api/v1/checkout-sessions/{id}Auth: Publishable key + client secret, the session's client secret alone (hosted page), or a server key
Response
{
"sessionId": "cs_live_abc123",
"status": "completed",
"amount": 99.99,
"currency": "USD",
"customerEmail": "[email protected]",
"allowGuestSavedCards": false,
"paymentType": "one_time",
"mode": "hosted",
"expiresAt": "2025-01-15T11:00:00Z",
"merchantName": "Yard Shop",
"merchantLogoUrl": "https://cdn.example.com/logo.png",
"allowedPaymentMethods": null,
"successUrl": "https://yoursite.com/success",
"cancelUrl": "https://yoursite.com/cancel"
}Statuses: created, payment_pending, processing, completed, expired, cancelled.
Confirm a Checkout Session
/api/v1/checkout-sessions/{id}/confirmAuth: Publishable key + client secret
Request Body
{
"paymentMethodId": "pm_card_visa_1234",
"returnUrl": "https://yoursite.com/complete"
}Response
{
"id": "cs_live_abc123",
"object": "checkout_session",
"status": "complete",
"paymentStatus": "paid",
"paymentResult": {
"id": "pay_xyz789",
"status": "succeeded",
"amount": 99.99,
"currency": "USD"
}
}Tokenize Card
/api/v1/checkout-sessions/{id}/tokenizeAuth: Publishable key + client secret
Request Body
{
"cardNumber": "4242424242424242",
"expiryMonth": 12,
"expiryYear": 2027,
"cvc": "123",
"billingDetails": {
"name": "Jane Doe",
"email": "[email protected]"
}
}Response
{
"id": "pm_card_visa_1234",
"object": "payment_method",
"type": "card",
"card": {
"brand": "visa",
"last4": "4242",
"expiryMonth": 12,
"expiryYear": 2027
},
"createdAt": "2025-01-15T10:31:00Z"
}List Saved Cards
/api/v1/checkout-sessions/{id}/saved-cardsAuth: Publishable key + client secret
Response
{
"object": "list",
"data": [
{
"id": "pm_card_visa_1234",
"card": {
"brand": "visa",
"last4": "4242",
"expiryMonth": 12,
"expiryYear": 2027
},
"isDefault": true
},
{
"id": "pm_card_mc_5678",
"card": {
"brand": "mastercard",
"last4": "8210",
"expiryMonth": 6,
"expiryYear": 2026
},
"isDefault": false
}
]
}Verify Saved Card
/api/v1/checkout-sessions/{id}/saved-cards/verifyAuth: Publishable key + client secret
Initiates OTP verification for a saved card before using it for payment.
Request Body
{
"paymentMethodId": "pm_card_visa_1234"
}Response
{
"verificationId": "ver_abc123",
"status": "otp_sent",
"maskedPhone": "+1***4567",
"expiresAt": "2025-01-15T10:35:00Z"
}Confirm Saved Card OTP
/api/v1/checkout-sessions/{id}/saved-cards/confirm-otpAuth: Publishable key + client secret
Request Body
{
"verificationId": "ver_abc123",
"otp": "123456"
}Response
{
"verified": true,
"paymentMethodId": "pm_card_visa_1234"
}Refund a Checkout Session
/api/v1/checkout-sessions/{id}/refundAuth: Server key with the checkout.session.refund scope
Refunds the payment behind a completed session. Only the merchant that owns the session, in the same mode as the key, can refund it; any other session is a 404. Only full refunds are supported: omit amount or send the full amount paid — any other amount is refused with partial_refund_not_supported. Card (MPGS) payments and wallet QR payments can be refunded until they are settled to your balance. A wallet refund the wallet has accepted but not yet finished comes back with status pending_reversal and completes on its own; the payment.refunded webhook tells you when. Repeating a refund returns alreadyRefunded: true without contacting the processor.
Request Body
{
"amount": 99.99,
"reason": "Customer returned the item"
}Response
{
"sessionId": "cs_live_abc123",
"paymentId": 4821,
"paymentReferenceNumber": "PAY-4821",
"status": "refunded",
"amount": 99.99,
"currency": "USD",
"alreadyRefunded": false
}Errors: partial_refund_not_supported (400), payment_not_refundable (400, not yet captured, already settled, or an unsupported rail), nothing_to_refund (409, the session has no payment). A payment.refunded webhook follows a successful refund.
Cancel a Checkout Session
/api/v1/checkout-sessions/{id}/cancelAuth: Server key required
Response
{
"id": "cs_live_abc123",
"object": "checkout_session",
"status": "expired",
"paymentStatus": "unpaid",
"cancelledAt": "2025-01-15T11:00:00Z"
}Withdraw a Wallet QR Code
/api/v1/checkout-sessions/{id}/withdraw-qrAuth: Publishable key + client secret, or the client secret alone (hosted page). Scope checkout.session.confirm.
Takes back the wallet QR code (JN Pay / Jam-Dex) a confirm issued, so the payer can choose another payment method. The session stays open. Call it before showing your method picker again: a code left live could be paid on top of whatever the payer picks next. No request body.
Response
{
"sessionId": "cs_live_abc123",
"outcome": "withdrawn",
"status": "payment_pending"
}withdrawn: the code can no longer be paid; the session is back topayment_pending. Confirm again with another option.already_paid: the code had been paid (or the wallet refused to withdraw it because it was); the session iscompleted. Show the payment as done.failed: the code could not be withdrawn and may still be paid. Nothing changed; keep waiting on it and try again later.messageexplains, in words you can show the payer.
A cancelled or expired session is refused (400); its codes were already withdrawn.
Get Session Status
/api/v1/checkout-sessions/{id}/statusAuth: Publishable key + client secret
Lightweight endpoint for polling session status from the client.
Response
{
"status": "completed"
}SRC Lookup (Click to Pay)
/api/v1/checkout-sessions/{id}/src/lookupAuth: Publishable key + client secret
Look up whether the customer is enrolled in Click to Pay (Secure Remote Commerce).
Request Body
{
"email": "[email protected]"
}Response
{
"enrolled": true,
"cards": [
{
"srcCardId": "src_card_abc123",
"brand": "visa",
"last4": "4242",
"expiryMonth": 12,
"expiryYear": 2027,
"artUri": "https://cdn.quickpay.com/card-art/visa-4242.png"
}
]
}SRC Authenticate (Click to Pay)
/api/v1/checkout-sessions/{id}/src/authenticateAuth: Publishable key + client secret
Authenticate a Click to Pay card selection and obtain a payment token.
Request Body
{
"srcCardId": "src_card_abc123",
"validationData": "otp_or_biometric_token"
}Response
{
"paymentMethodId": "pm_src_visa_4242",
"token": "tok_src_abc123",
"card": {
"brand": "visa",
"last4": "4242"
},
"authenticated": true
}