> ## 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.

# KYC 工单

> 为每一次 KYC 进件建立可查询、可通知的工单：API 直传与 H5 两种模式、五个状态、四种失败去向，以及如何凭 PASSED 工单以 NORMAL 模式申请虚拟卡。

## 📄 正文

KYC 工单（KYC Ticket）把「用户是否通过 KYC」从账户级状态细化到**每一次进件**：这一次走到了哪一步、为什么没过、什么时候可以开卡。工单与卡申请单是两层——先有 PASSED 的工单，再凭它建卡申请单。状态每次变化都会通过 `KYC_TICKET` Webhook 通知您，也可以随时用 `detail` 查询。

![KYC 工单状态机](https://mintlify.s3.us-west-1.amazonaws.com/dcs-0bf7a937/imgs/diagrams/va-kyc-ticket-states-light.svg)

图中画的是最长路径。**`PENDING` 不是必经状态**：API 模式的工单在风控回查时可能直接从 `INIT` 或 `NEED_VERIFY` 落到 `PASSED` / `REJECTED`。请按实际收到的 `status` 处理，不要假设状态一定逐级推进。

## 两种进件模式

| 模式 | 适用场景 | 您要做的 |
| :- | :- | :- |
| **H5** | 由用户在 DCS 托管的 H5 页面自助完成证件上传、人脸与资料填写 | `POST /kyc-ticket/v1/apply-kyc-h5` 建单 → `POST /redirect/v2/guidance-link`（`action=KYC_APPLY`，带 `kycTicketId` 与 `categoryId`）换链接给用户 |
| **API** | 您已采集身份证明文件与职业信息，一次性直传 | `POST /kyc-ticket/v1/apply-kyc` 建单 → 工单 `NEED_VERIFY` 后 `POST /redirect/v2/guidance-link`（`action=KYC_LIVENESS`，`kycTicketId` 必填）换人脸页链接给用户 |

> [!NOTE]
>
> 存量接入不受影响：不建单直接调 `guidance-link`（`action=KYC_GUIDE`）仍可用，DCS 会在**签发链接时**为该用户复用或新建 H5 工单。工单号不在该接口返回，但新建时会推一条 `KYC_TICKET` Webhook 带出 `kycTicketId`，凭它即可用 `detail` 查询。`KYC_GUIDE` 不读 `kycTicketId`，传了也不会被使用，工单号以 `KYC_TICKET` Webhook 带出的为准；要凭自己建的工单换链接，请用 `KYC_APPLY`。

## 工单状态

| 状态 | 描述 | 是否终态 | 后续操作 |
| :- | :- | :-: | :- |
| `INIT` | 工单已建立；H5 用户尚未提交，API 资料已收到待送风控 | 否 | H5：把引导链接发给用户；API：等待系统处理 |
| `NEED_VERIFY` | 待人脸核验 | 否 | 仅 API 模式出现：`action=KYC_LIVENESS` 换人脸页链接 |
| `PENDING` | 资料已提交，审核中 | 否 | 等待 Webhook 或主动查询 |
| `PASSED` | 审核通过 | 是 | 凭 `kycTicketId` 以 `cardApplyMode=NORMAL` 申请虚拟卡 |
| `REJECTED` | 审核拒绝 | 是 | 查看 `errorCode` / `errorMessage`；如需重试请换新 `kycTicketRef` 重新建单 |

渠道建单时，该用户只要已有任何在途（非终态）工单即被拒，**包括服务端在签发 `action=KYC_GUIDE` 引导链接时自动建的 H5 工单**；而自动建单只看有没有在途的 H5 工单、不看 API 工单，因此一个用户可能同时持有一张渠道建的 API 工单与一张服务端自动建的 H5 工单。自动建的工单会占用「在途工单」名额且不会过期回收——用户取过链接但始终没提交时，该工单停在 `INIT`，渠道调 `apply-kyc` 会一直收到 `KYC_TICKET_IS_IN_PROCESSING`，打算走 API 模式就不要先给该用户签发 `KYC_GUIDE` 链接。同一 `kycTicketRef` 重复建单：`apply-kyc` 一律返回 `KYC_TICKET_REF_NOT_UNIQUE`（超时需确认结果时按 `kycTicketRef` 查单）；`apply-kyc-h5` 在原单仍为 `INIT` 时幂等返回原单（网络重试场景）；原单已到 `PENDING` 及以后按状态拒绝（`KYC_TICKET_IS_IN_PROCESSING` / `KYC_TICKET_ALREADY_PASSED` / `KYC_TICKET_VERIFY_FAIL`）；换 `kycTicketRef` 重建而在途单仍存在时返回 `KYC_TICKET_IS_IN_PROCESSING`。

## 四种失败去向

| 失败发生在 | 工单表现 | 您怎么知道 | 用户能否重试 |
| :- | :- | :- | :-: |
| 风控审核拒绝 | `status=REJECTED`，`errorCode` 为拒绝原因 | Webhook / `detail` | 换新 `kycTicketRef` 重新建单 |
| 引导链接门禁拒绝（工单已 `PENDING` / 终态） | 工单不变 | `guidance-link` 返回对应错误码 | 按错误码处置 |
| 建卡门禁拒绝（工单未 `PASSED`） | 工单不变，卡申请单不创建 | `virtual-card/apply` 返回 `KYC_TICKET_NOT_PASSED` | 等 `PASSED` 后重试 |

## API 直传：职业信息密文

`encryptedKycCareerInfo` = Base64( AES-GCM( key = Base64Decode(SecretKey), iv = Base64Decode(`iv`), plaintext = `careerInfo` 的 JSON ) )，认证标签 128 位。DCS 用请求头 `X-DAPI-API-KEY` 反查您的 SecretKey 解密，不落明文日志。明文 `careerInfo` 与密文至少传一个，都传以密文为准。

## 凭工单申请虚拟卡

工单 `PASSED` 后，调用 `POST /card/v1/virtual-card/apply` 传 `cardApplyMode=NORMAL` + `kycTicketId`，无需再内联 `kycInfo`；不传 `cardApplyMode` 即为 `COMPLETE`，与改造前完全一致。工单不绑定卡产品：KYC 结果是用户级的，一张 `PASSED` 工单可为该用户申请任意卡产品的多张卡。申请与详情响应新增 `kycTicketId` / `cardApplyMode`。详见 [申请卡](https://docs.thedecard.com/zh/decard-managed/how-to-use/managing-cards/issuing-cards.md)。

## 引导链接时效与人脸页错误

* 链接中的 secret **300 秒内一次性有效**，页面打开后建立 **1 小时**会话；过期需重新换链接，工单不受影响。
* 人脸页可能返回：`PERMISSION_DENIED`（链接已用过/过期）、`SUMSUB_TOKEN_NOT_FOUND`（会话不是人脸场景或工单不属于当前用户）、`KYC_TICKET_STATUS_NOT_LIVENESS`（工单已提交或终态）。**前两个码只由人脸页返给前端，不出现在渠道 API 的响应里**，列在这里是便于您排查用户反馈；`KYC_TICKET_STATUS_NOT_LIVENESS` 在您用 `action=KYC_LIVENESS` 调 `guidance-link` 而工单已到 `PENDING` 或终态时，也会直接返回给您。

## 错误码

| 错误码 | 含义 |
| :- | :- |
| `KYC_TICKET_NOT_FOUND` | 工单不存在或不属于本渠道本用户 |
| `KYC_TICKET_MODE_MISMATCH` | 工单模式与动作不符：`KYC_APPLY` 只服务 H5 工单，`KYC_LIVENESS` 只服务 API 工单 |
| `KYC_TICKET_REF_NOT_UNIQUE` | `kycTicketRef` 已被同渠道其他用户占用 |
| `KYC_TICKET_IS_IN_PROCESSING` | 已有在途工单 |
| `KYC_TICKET_ALREADY_PASSED` | 工单已通过，直接申请虚拟卡即可 |
| `KYC_TICKET_VERIFY_FAIL` | 工单已拒绝，请换新 `kycTicketRef` |
| `KYC_TICKET_NOT_PASSED` | 工单未通过，不能建卡申请单 |
| `KYC_TICKET_STATUS_NOT_LIVENESS` | 工单已到 `PENDING` 或终态，不能再取人脸链接 |
| `KYC_TICKET_NOT_READY_FOR_LIVENESS` | 工单仍为 `INIT`（API 资料尚在送审），暂不能取人脸链接；等工单转 `NEED_VERIFY` 后重试 |
| `SUMSUB_TOKEN_NOT_FOUND` | 人脸页会话不含工单或归属不符 |

> 对外返回时错误码沿用所在模块前缀（如 `CARD_KYC_TICKET_NOT_FOUND`），请按实际字符串匹配。审核拒绝（`REJECTED`）的 `errorCode`：**API 模式**取风控码表，与卡申请一致，见 [申请数据字典](https://docs.thedecard.com/zh/decard-managed/how-to-use/managing-cards/application-data-dictionary.md)；**H5 模式**为 `KYC_REJECTED`，具体原因在 `errorMessage` 里；用户未在 Sumsub 时限内完成时为 `TIMEOUT`，可引导用户重新发起。

## 相关接口

* `POST /kyc-ticket/v1/apply-kyc-h5` / `POST /kyc-ticket/v1/apply-kyc` / `GET /kyc-ticket/v1/detail`：见 [API 参考](https://docs.thedecard.com/zh/decard-managed/api-reference/index.md)
* `POST /redirect/v2/guidance-link`：新增 `kycTicketId`、`categoryId` 与 `action=KYC_APPLY` / `KYC_LIVENESS`，见 [H5 引导页](https://docs.thedecard.com/zh/decard-managed/integration-resources/h5-kyc-guidance.md)
* `KYC_TICKET` Webhook：见 [Webhook 与 WebSocket](https://docs.thedecard.com/zh/decard-managed/integration-resources/webhook-websocket.md)
