HSRCPAY Documentation

3DS Simulation

Sandbox testing of secure mode, requires_action, nextAction, challenge, resume, and callback flows.

What does this page cover? How HSRC Pay sandbox simulates 3DS, secure mode, and requires_action flows.

Payment does not always return direct success. Some payments require user action, redirect, HTML render, challenge, or resume/callback flow. HSRC Pay represents this with the normalized requires_action model.

Important: 3DS simulation does not guarantee real authentication; it tests integration behavior. Sandbox 3DS is not real card network authentication or a real issuer ACS connection.

What Is 3DS Simulation?

3DS simulation is sandbox-only challenge behavior that tests whether the merchant integration is ready for multi-step payment flows.

In this flow, the sandbox provider adapter may return requires_action instead of direct authorization. The merchant or checkout frontend shows this next action to the user; after the challenge completes, resume/callback flow finalizes the payment result.

When Should Secure Mode Be Used?

Secure mode should be tested when:

  • The merchant API request requires secure mode
  • Provider capability supports 3DS
  • The payment is confirmed with secure_mode: true and the sandbox provider supports the flow
  • Routing or product configuration requires a secure provider

Confirm Result: requires_action

When the adapter has latestResult.kind === "requires_action", Payment becomes REQUIRES_ACTION. The merchant uses confirmResult.paymentNextAction for redirect:

{
  "payment": { "id": "pay_sandbox_123", "status": "REQUIRES_ACTION" },
  "confirmResult": {
    "ok": true,
    "latestResult": { "kind": "requires_action" },
    "paymentNextAction": {
      "action": "redirect_user_to_url",
      "url": "https://sandbox.hsrcpay.com/..."
    }
  }
}

nextAction inside the provider adapter (e.g. render_html) can be handled on checkout or dashboard; for public API redirect, rely on paymentNextAction.

Next Action Types

TypeDescription
render_htmlCheckout or merchant frontend renders HTML challenge content
redirectUser is redirected to sandbox challenge URL
collect_inputConceptual model: additional test input may be collected from the user
sdk_actionConceptual model: may be used for SDK-managed actions

In the current public narrative, render_html and redirect-like models are primary; treat other types as future-compatible conceptual models.

HTML Render / Redirect Flow

If hosted checkout is used, HSRC Pay may manage challenge rendering inside the checkout experience. In API-only integration, the merchant must handle the nextAction result on their own frontend.

Merchant frontend:

  • Must not log raw payload when rendering HTML.
  • Must use redirect URL only in sandbox context.
  • Must wait for resume/callback result after challenge completes.

Resume / Callback Flow

After the challenge completes, the provider returns to GET|POST /v1/gateway/three-d-secure-callback-urls/:chargeId on the HSRC Pay gateway. This flow runs the resumeThreeDSecure use case; the merchant does not need to call resumePayment(paymentId) separately.

const { data } = await api.post("/v1/payments/pay_sandbox_123/confirm", {
  payment_method: { id: "pm_sandbox" },
  payer_identity: { ip_address: clientIp, user_agent: ua },
});

if (data.confirmResult.paymentNextAction?.url) {
  redirectUser(data.confirmResult.paymentNextAction.url);
}

// After callback: verify final status via GET payment or webhook

Authorization After Successful 3DS

When the challenge completes successfully, Payment becomes SUCCEEDED or AUTHORIZED; Charge becomes CAPTURED or AUTHORIZED. Webhook: payment.succeeded, payment.authorized, charge.captured, etc.

Failed or Cancelled Challenge

If the challenge fails, the adapter may return error + declined; Charge becomes DECLINED, Payment stays REQUIRES_PAYMENT_METHOD. The merchant should offer controlled re-confirm or a different method.

Webhook and Event Expectations

The merchant webhook handler must be idempotent. Expect multiple events for the same payment.

Expected event family:

  • payment.requires_action
  • payment.succeeded
  • payment.authorized
  • charge.declined
  • checkout_session.completed (hosted checkout)

Do not use frontend result alone as the final accounting record; verify with server-side status and webhook/event flow.

Testing Checklist

  • Handle requires_action response.
  • Test hosted checkout vs API-only integration difference.
  • Test gateway 3DS callback and payment GET/webhook verification after callback.
  • Test successful and failed challenge outcomes separately.
  • Check webhook idempotency behavior.
  • Mask raw HTML, card data, and transaction metadata logging.

Limitations and Security Notes

  • 3DS simulation is not real card network authentication.
  • No real issuer ACS connection is established.
  • Fields such as CAVV/ECI/XID/MD should be treated as test metadata in sandbox.
  • Raw challenge payload, HTML, and transaction metadata must be masked carefully in logs.
  • Production authentication outcome is not guaranteed; only integration flow is tested.

On this page