Skip to main content

📄 Guide

Whether you are after card issuance progress, card status changes, real-time authorization results or the flow of KYC and tickets, a single webhook subscription covers all of it: the moment an event happens DCS pushes it to the webhookUrl you registered, so your own system stays in step with DCS without polling. As a licensed issuer with its own BIN, DCS notifies you by webhook at every key point in the card lifecycle, in authorization and in compliance. All events share one envelope structure, so a single receiving endpoint on your side is enough to handle every event type.
Prerequisites: before you can receive events you need to register your webhookUrl, get your IPs whitelisted, and be ready to verify X-Signature with your secretKey. For the configuration steps and the HMAC-SHA256 verification code, see Webhook configuration.

Mental model: one envelope, many events

Every webhook arrives in the same common envelope: the outer layer tells you what the event is, which object it concerns and when it happened, while the inner data holds the payload specific to that event type. Your receiver only has to look at webhookType first and then parse the matching data structure.
Webhook verification and dispatch by event typeWebhook verification and dispatch by event type
Idempotent deduplication: the same event may be delivered several times because of network retries. Use the webhookId in the envelope as your idempotency key and acknowledge and skip any webhookId you have already processed, so you never double-post an entry or issue a card twice.

Common envelope structure

Every webhook shares these outer fields:
Time zones: notificationTime, along with createTime/modifyTime inside each data, carries a +08:00 offset (Singapore time), consistent with the UTC+8 convention used across the business time fields. Parse them using the offset the string carries.

webhookType event enum

AUTHORISATION_RESULT is the receipt for an authorization, which is a different thing from the authorization forwarding request that asks you to decide synchronously while the cardholder is paying. The latter is delivered in real time over authUrl (RSA two-way signing) and requires you to return approve or decline within a strict deadline. For how to handle those requests, see Authorization forwarding.

The data structure of each event

Card Order

webhookType = CARD_ORDER, the progress push for card orders such as issuance, virtual-to-physical conversion and replacement. status values per type:
For the full card order state machine, the meaning of each errorCode and what to resubmit, see Card issuing and Card order error codes.

Card

webhookType = CARD, pushed when the card’s own status changes (frozen, blocked, canceled and so on).
Webhooks never carry sensitive data such as the full card number or the CVV. For the card state machine (FROZEN can be lifted by you, BLOCKED only by DCS) and for statusReason, see Card management.

Authorization Result

webhookType = AUTHORISATION_RESULT, the receipt for how an authorization was posted.
Pushed for approvals and declines alike: DCS pushes this event whether the authorization was approved or declined (approveFlag=A/D). A decline you return on authUrl (01/11/21) is pushed as approveFlag=D; a failed DCS pre-check (a frozen or canceled card, for example, where the request was never forwarded to authUrl) is also pushed as approveFlag=D. You can therefore build a complete authorization ledger from this webhook alone, with the next day’s authorization report as the reconciliation backstop. For how authType, direction and originalAuthId combine in returns, incremental authorizations, multi-part settlements and similar scenarios, see Authorization and settlement and Capture scenarios.

Authorization 3DS Challenge

webhookType = AUTHORISATION_3DS_CHALLENGE, the 3DS challenge notification. flowsType tells the two authentication modes apart:
  • OOB (out of band): the cardholder is sent to you to complete the verification. On receiving this webhook you guide the cardholder through authentication in your own app or another channel, then report the result back to DCS via API.
  • OTP_DELEGATE: you send the verification code to the cardholder by SMS or email. DCS pushes the code to you in this webhook, and you decrypt it before sending it on to the cardholder.
Decrypting the sensitive fields (OTP_DELEGATE only): DCS encrypts otpPasscode, phoneNumber and email with AES-GCM using your secretKey, and the webhook carries the matching iv. Decrypt them with secretKey plus iv before you send the verification code to the cardholder. For a reference AES/GCM implementation (12-byte IV, 128-bit authentication tag), see Card management: reset PIN. For the full 3DS forwarding sequence, see 3DS forwarding.

KYC Ticket

webhookType = KYC_TICKET, a status change on a KYC verification ticket.
The statuses a ticket can take differ per kycApplyMode: H5-RENEWAL and H5-MIGRATION only ever use INIT / PASSED / REJECTED and never NEED_VERIFY or PENDING. For each mode’s status line, see Updating KYC information and KYC information migration. For the KYC state machine, the rejection codes and what to resubmit, see Query KYC and KYC rejection codes.

KYC

webhookType = KYC, a user-level KYC event: DCS has detected that the user’s documents or KYC data have expired and need renewing, or that the renewal has completed. This is not the same as KYC_TICKET, which is ticket-level and tracks the progress of a single verification.
For how to guide the user through a renewal after receiving kycRenewalRequired=true, see Updating KYC information; you can also call Query a user’s KYC information at any time to confirm.

A complete webhook example

Taking a completed virtual card issuance as the example, the HTTP POST body you receive looks like this:
The sample follows the actual lexicographic field order and is only pretty-printed for readability; the real payload is compact (see Notes below).
The headers carry X-Signature (HMAC-SHA256, computed over the whole body). On your side you should:
  1. Verify X-Signature first and discard the request if verification fails;
  2. Deduplicate on webhookId;
  3. Dispatch to the right handler by webhookType;
  4. Return HTTP 200 (any 2xx response counts as received); otherwise DCS redelivers according to its retry policy.
Apart from the real-time AUTHORISATION channel, a general webhook is retried at most 3 times; retries are driven by a scheduled job and the backoff interval follows that job’s configuration. The real-time AUTHORISATION channel is never retried and a timeout is treated directly as responseCode=21. The outbound DCS Content-Type is always application/json.

Notes

Payload format and field order

Webhook payloads are sent as compact JSON (no spaces, no line breaks). At every level (the common envelope, data and any nested objects) the fields are sorted in ascending lexicographic order of the full field name — compared character by character by character code, moving on to the next character when the previous ones are equal, case-sensitively. This ordering is a determinism guarantee of DCS-side serialisation that helps when you need to inspect a raw payload; parse the JSON normally and do not rely on field order to read values.

Field extensions

New fields may be added to webhook payloads (the data of each event) in the future. Field extensions follow these compatibility commitments:
  1. Existing fields stay stable: the fields already defined in this document never change their name, type or meaning, and are never removed;
  2. Extension happens only by adding fields: partners can read the new fields as needed; if you do not need them yet, simply ignore them — existing parsing is unaffected;
  3. Ignore unknown fields when parsing: do not parse webhook payloads in a strict mode that rejects unknown fields, so that new fields never break an existing integration.

New fields and signature verification

X-Signature is computed over the raw payload string DCS actually sent. Compute the HMAC-SHA256 directly over the raw body as received and compare — do not parse the payload and regenerate JSON before verifying: the regenerated document can differ in missing fields, field order or formatting, and verification will fail. As long as you verify against the raw payload, new fields never affect the result. See Webhook configuration for the verification procedure.

Next steps