Checkout Session Guide
Session lifecycle, secure mode, redirect, webhook, and final state verification in hosted payment experience.
This page explains what Checkout Session is, when to use it, and the differences between Hosted Checkout and API-only payment flow.
Checkout Session is the session layer that manages HSRC Pay hosted or semi-hosted payment experience. It collects payment method and checkout context from the user; Confirm starts provider execution.
What is Checkout Session?
Checkout Session is a payment session the merchant creates to start the payment experience quickly and in a controlled way. The session carries amount, currency, customer context, redirect URLs, expiry, payment method selection, and final payment state relationship.
This model suits merchants who do not want to build a payment form from scratch, or who want multi-step flows such as 3DS/redirect handled in a safer hosted experience.
When should you use it?
- When you want fast integration
- When you prefer a hosted payment form
- When you want to leave 3DS/requires_action handling to the checkout experience
- When you want to reduce card data exposure on the frontend
- When you want to standardize redirect, cancel, and return URL behavior
Difference from API-only flow
| Topic | Hosted Checkout | API-only Payment |
|---|---|---|
| UI responsibility | HSRC Pay checkout experience | Merchant frontend |
| 3DS handling | Can be managed inside checkout | Merchant handles nextAction |
| Card data exposure | Narrower frontend responsibility | Merchant UI carries more responsibility |
| Customization | More controlled and limited | More flexible |
| Integration complexity | Lower | Higher |
| Recommended use | Fast, standard payment experience | Custom UX, custom checkout, or platform integration |
Session lifecycle
Checkout Session status values: PENDING, PROCESSING, COMPLETED, EXPIRED, CANCELLED, FAILED.
- Merchant creates session with
POST /v1/checkout-sessions(PENDING,tokengenerated). - Payer enters session via merchant
url(hosted page) orGET /v1/checkout-sessions/token/:token. - Checkout UI collects payment method and payer fields; linked Payment is
CREATED. - Confirm starts provider execution; Payment may become
SUCCEEDED/AUTHORIZED/REQUIRES_ACTION/REQUIRES_PAYMENT_METHOD. - Session moves from
PROCESSINGto terminal state (COMPLETED,FAILED,CANCELLED,EXPIRED). - Merchant verifies final result with webhook or
GET /v1/payments/:id.
User experience
Checkout confirm side may collect:
- Payer name, email, and phone
- Billing address
- Shipping address
- Simplification signals such as
shipping_same_as_billing - Custom fields defined by the merchant
These fields are completed in session context before payment execution starts.
3DS / requires_action handling
When secure mode is on or issuer/provider behavior requires challenge, Payment becomes REQUIRES_ACTION; confirmResult.paymentNextAction (redirect_user_to_url) provides redirect inside checkout.
In API-only model the merchant frontend carries the same responsibility with paymentNextAction.
Redirect and return URL behavior
Return URL is for closing user experience; it is not final financial proof. The user may close the browser, redirect may delay, or the provider may produce async results.
Final verification
Do not rely on frontend redirect result alone. Final payment outcome must be verified via backend/API status query or webhook/event delivery.
Verifying result with webhook
Merchant backend should close payment outcome with webhook. Webhook handler should:
- Be idempotent
- Tolerate duplicate delivery
- Match records by Payment ID and trace/request ID
- Interpret event types such as
payment.requires_action,payment.succeeded,payment.authorized,checkout_session.completed, andcharge.declinedseparately
Security notes
- Do not move production card data and credentials into sandbox.
- Do not log raw card data, CVV, challenge HTML, or provider secrets.
- Treat checkout tokens as short-lived and context-specific.
- Validate return/cancel URLs against open redirect risks.
Example integration flow
const { data } = await api.post("/v1/checkout-sessions", {
amount: 12500,
currency: "TRY",
url: "https://pay.merchant.example/checkout",
return_url: "https://merchant.example/return",
metadata: { order_id: "ord_123" },
});
// Payer: merchant hosted page or token session
redirectUserTo(`${data.checkout_session.url}?token=${data.checkout_session.token}`);// Webhook side
if (event.type === "payment.succeeded") {
await markOrderPaid(event.paymentId);
}Best practices
- Do not skip backend verification when using hosted checkout.
- Provide user-friendly paths for session expiry and cancel behavior.
- Treat
requires_actionas a normal flow part. - Keep Session and Payment relationship visible on ops screens.
- Test success, decline, timeout, and 3DS scenarios in sandbox.
Related docs
Payment Lifecycle and Confirm
Understand payment creation, confirm, requires_action, succeeded, authorized, and charge attempt relationships in HSRC Pay.
Business Flow - Payments & Charges
Understand Payment and Charge separation, routing/fallback attempt model, and the business flow of payment operations.