> ## Documentation Index
> Fetch the complete documentation index at: https://docs.thedecard.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Card issuing flow

> The end-to-end integration path for issuing a card to your customers: create the customer record, submit a KYC ticket, await KYC approval, then apply for a virtual card. Each stage below sets out what you call, what DCS handles, and the status transitions to expect.

## 📄 Guide

Whether your customers originate from an exchange, a wallet or a platform application, you can issue them a virtual card through the DCS card issuing endpoints and upgrade it to a physical card at a later stage. The issuing path is consistent in all cases: establish the customer record and complete KYC with DCS first, then submit a virtual card application once KYC has been approved.

As a licensed issuer operating its own BIN, DCS is responsible for card issuance, KYC review, authorization forwarding, clearing and reconciliation. As the partner, you own the cardholder-facing experience and your own limit and risk decisions.

## Card issuing sequence

The sequence is the same regardless of how the KYC documents are collected: **create the customer, apply for KYC (uploading documents first only if required), wait for KYC to pass, then apply for a virtual card**. When the same customer applies for another card later, the existing `kycTicketId` can be reused and the KYC documents do not have to be submitted again.

You choose one of two document-collection routes: collect the KYC documents in **your own interface** and submit them to DCS, or hand the customer off to a **DCS-hosted H5 page** that captures them for you. In both cases the review is performed by our KYC vendor — see [KYC vendor](../../customer-success/faq-kyc-vendor) for details. Everything after KYC approval is identical.

<Frame>
  <img className="block dark:hidden" src="https://mintcdn.com/dcs-0bf7a937/SwaeBNwQm2hgkUz9/imgs/en/diagrams/pa-card-issuing-light.svg?fit=max&auto=format&n=SwaeBNwQm2hgkUz9&q=85&s=7ad4908c84134568f427de622ff622ea" alt="End-to-end card issuing flow, from KYC to the virtual card" width="816" height="1052" data-path="imgs/en/diagrams/pa-card-issuing-light.svg" />

  <img className="hidden dark:block" src="https://mintcdn.com/dcs-0bf7a937/SwaeBNwQm2hgkUz9/imgs/en/diagrams/pa-card-issuing-dark.svg?fit=max&auto=format&n=SwaeBNwQm2hgkUz9&q=85&s=4de8ab707f47476854c6263cd78e959a" alt="End-to-end card issuing flow, from KYC to the virtual card" width="816" height="1052" data-path="imgs/en/diagrams/pa-card-issuing-dark.svg" />
</Frame>

For the execution details of the two routes, see [Apply for KYC](../kyc/apply-kyc) and [H5 KYC guidance page](../kyc/h5-kyc-guidance).

> The two URLs do different jobs: `generate-pre-upload-url` only issues an S3 upload address, whereas `card-redirect/v1/guidance-link` issues a DCS-hosted H5 page. Use the former when you collect the documents in your own interface and upload the files yourself; use the latter when the end user has to complete liveness, information verification, supplementary card application details, KYC or KYC renewal on a DCS page.

## Core endpoint: apply for a virtual card

**`POST /open-api/card-order/v1/apply-virtual`**

> For the request and response fields, the corresponding endpoint page in the API reference is authoritative.

### Request parameters

| Field           | Type   | Required | Description                                                                                                                                                                                     |
| --------------- | ------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `profileId`     | string | Required | Card profile ID. See [Card profile](./card-profiles); contact your DCS account team to obtain it. Max length 50                                                                                 |
| `cardOrderRef`  | string | Required | Card order idempotency key, generated by you. Max length 50                                                                                                                                     |
| `cardApplyMode` | string | Required | Fixed value `NORMAL`. The legacy `COMPLETE` mode still visible at the endpoint level is kept only for existing integrations and is scheduled for retirement — do not use it in new integrations |
| `kycTicketId`   | string | Required | KYC ticket ID returned by "apply for KYC"                                                                                                                                                       |
| `customerId`    | string | Required | Customer ID returned by "create customer"                                                                                                                                                       |

### Minimum request example

```json theme={null}
{
  "profileId": "PROFILE_xxx",
  "cardOrderRef": "ord-20260616-0001",
  "cardApplyMode": "NORMAL",
  "customerId": "C100001",
  "kycTicketId": "KYC_1a2b"
}
```

### Response

The unified response structure is `{ code, message, messageDetail, data }`:

* `code` / `message`: the system-level return code and its text.
* `messageDetail`: a prompt you can show to the end user (`title` / `message` / `type` / `action` / `linkUrl` and so on), used in your front end to guide a document resubmission or a retry.
* `data`: the business payload, described in the table below.

<Warning>
  **Response structure consistency**: this API uses `code` to indicate system-level success, while the business result is provided separately in `data.status`. When a card order is rejected, the response `code` may still indicate success, while `data.status=FAILED`. Partners should use `data.status` to determine the card application result and should not rely solely on `code` to determine whether a card application was successful. For the unified response structure and successful `code` values, please refer to the [Authentication guide](../../integration-resources/authentication); for the classification of card order failure `errorCode` values, please refer to [Card application error codes](./card-order-codes).
</Warning>

`data` fields:

| Field                       | Description                                                                    |
| --------------------------- | ------------------------------------------------------------------------------ |
| `cardOrderId`               | Card order ID, used to query the order detail                                  |
| `profileId`                 | Card profile ID                                                                |
| `type`                      | Card type: `VIRTUAL` / `VIRTUAL_TO_PHYSICAL` / `REPLACEMENT`                   |
| `customerId`                | Customer ID                                                                    |
| `cardId`                    | Card ID, returned once the order completes; every later card operation uses it |
| `status`                    | Card order status, see the state machine below                                 |
| `errorCode` / `errorReason` | Failure code and reason when the order fails                                   |
| `cardOrderRef`              | The idempotency key echoed back                                                |
| `needExtraInfo`             | Whether a supplementary questionnaire is required (used when `type=VIRTUAL`)   |
| `createTime` / `modifyTime` | Creation and last update time, formatted `yyyy-MM-dd'T'HH:mm:ss+08:00`         |

### Virtual card order state machine

<Frame>
  <img className="block dark:hidden" src="https://mintcdn.com/dcs-0bf7a937/oUoeUKtwWWK2o-Li/imgs/en/diagrams/pa-card-order-states-light.svg?fit=max&auto=format&n=oUoeUKtwWWK2o-Li&q=85&s=d2894a75cb1cb734a41e04bbcf4accb3" alt="Virtual card order state machine" width="742" height="390" data-path="imgs/en/diagrams/pa-card-order-states-light.svg" />

  <img className="hidden dark:block" src="https://mintcdn.com/dcs-0bf7a937/oUoeUKtwWWK2o-Li/imgs/en/diagrams/pa-card-order-states-dark.svg?fit=max&auto=format&n=oUoeUKtwWWK2o-Li&q=85&s=9f150786aa95ab6e79f617314f1044b1" alt="Virtual card order state machine" width="742" height="390" data-path="imgs/en/diagrams/pa-card-order-states-dark.svg" />
</Frame>

| status                  | Meaning                                                                                                                                |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `PENDING`               | Application received and queued for processing                                                                                         |
| `CUSTOMER_PASS`         | Customer record checks have passed                                                                                                     |
| `KYC_PASS`              | KYC review has passed                                                                                                                  |
| `CHANNEL_CUSTOMER_PASS` | The issuing channel has accepted the cardholder; the card is being created                                                             |
| `COMPLETED`             | Card issued. `cardId` is returned and the card is ready to spend                                                                       |
| `FAILED`                | The application failed. This can occur at any stage; read `errorCode` / `errorReason` to decide whether to retry or resubmit documents |

Once the order reaches `COMPLETED`, `data.cardId` is usable. **A virtual card needs no activation: it is ready to spend as soon as it is issued.**

> Note: the success value for this endpoint is `COMPLETED`.

## When extra information is requested

DCS may require supplementary information from the cardholder before an application can be approved. When we do, the card application returns `needExtraInfo = true`; the application stays in progress and will not reach `COMPLETED` until the request is resolved.

There is **no dedicated open-api endpoint** for this: the cardholder has to complete the supplementary application details on the H5 guidance page (`guidance-link` `type=6`). Where our review determines that the cardholder must supply additional KYC information, DCS automatically creates a **KYC extra information ticket** that tracks the request from creation through to approval or rejection. You do not create the ticket yourself.

1. **Detect the request.** The card order's `needExtraInfo` becomes `true` and you receive a `KYC_EXTRA_INFO_TICKET` webhook with the ticket in status `INIT`.
2. **Direct the user to submit.** `POST /open-api/card-redirect/v1/guidance-link` with `type=6` and the `cardOrderId` to obtain the H5 link, then open it for the user.
3. **Track the outcome.** The ticket moves to `PENDING` on submission, then to `PASSED` (the card order continues) or `REJECTED`, where the webhook carries `rejectReason` and `rejectRemark`.
4. **Query at any time.** `GET /open-api/kyc-extra-info-ticket/v1/list` returns the ticket list, statuses and rejection reasons for the card.

| Status     | Description                       | Terminal | Your action                                                                                                |
| ---------- | --------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------- |
| `INIT`     | Ticket created, awaiting the user | No       | Direct the user to the H5 page to submit the information                                                   |
| `PENDING`  | Submitted, under review           | No       | Wait for the review result                                                                                 |
| `PASSED`   | Approved                          | Yes      | The card order continues; no action needed                                                                 |
| `REJECTED` | Rejected or closed                | Yes      | Read `rejectReason` / `rejectRemark`. If the reviewer requests information again, DCS creates a new ticket |

Query by `cardOrderId` to return every ticket for that order, newest first, including the rejection reasons of earlier tickets. Pass `kycExtraInfoTicketId` (from the webhook) to narrow the result to one ticket.

<Warning>
  A card order can have several tickets — a rejected request that the reviewer raises again creates a new one — but only one is in progress at any time. `rejectReason` and `rejectRemark` are populated only in `REJECTED`; in all other statuses they are empty strings.
</Warning>

## After the card is issued

1. Poll `GET /open-api/card-order/v1/detail` with `cardOrderId` (the response fields are the same as in the table above), or wait for the card order status webhook. Take `cardId` once the status is `COMPLETED`.
2. Call [card detail](./virtual-card) with `cardId` to read non-sensitive data such as `panFirst6` and `panLast4`.
3. To display the full card number or CVV: PCI-certified partners use [get sensitive card data](./secure-card); partners without PCI certification use the DCS-hosted page (guidance link), where the sensitive data is rendered directly in the end user's front end and never passes through your back end.
4. When the cardholder needs a physical card, call the virtual-to-physical endpoint (see [Physical card](./physical-card)).
5. If the order returns `needExtraInfo`, resolve the request first — see the section "When extra information is requested" above.

## Next steps

* Applying for, shipping and activating a physical card: see [Physical card](./physical-card).
* Day-to-day operations such as freeze, unfreeze, termination and PIN reset: see [Card management](./card-management).
* Card order statuses and how failure `errorCode` values are grouped, including whether a retry or a document resubmission helps: see [Card application error codes](./card-order-codes).
