HSRCPAY Documentation

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

TopicHosted CheckoutAPI-only Payment
UI responsibilityHSRC Pay checkout experienceMerchant frontend
3DS handlingCan be managed inside checkoutMerchant handles nextAction
Card data exposureNarrower frontend responsibilityMerchant UI carries more responsibility
CustomizationMore controlled and limitedMore flexible
Integration complexityLowerHigher
Recommended useFast, standard payment experienceCustom UX, custom checkout, or platform integration

Session lifecycle

Checkout Session status values: PENDING, PROCESSING, COMPLETED, EXPIRED, CANCELLED, FAILED.

  1. Merchant creates session with POST /v1/checkout-sessions (PENDING, token generated).
  2. Payer enters session via merchant url (hosted page) or GET /v1/checkout-sessions/token/:token.
  3. Checkout UI collects payment method and payer fields; linked Payment is CREATED.
  4. Confirm starts provider execution; Payment may become SUCCEEDED / AUTHORIZED / REQUIRES_ACTION / REQUIRES_PAYMENT_METHOD.
  5. Session moves from PROCESSING to terminal state (COMPLETED, FAILED, CANCELLED, EXPIRED).
  6. 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, and charge.declined separately

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_action as a normal flow part.
  • Keep Session and Payment relationship visible on ops screens.
  • Test success, decline, timeout, and 3DS scenarios in sandbox.

On this page