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

# 卡管理（冻结、解冻、换卡与 PIN）

> 说明卡片状态，以及冻结、解冻、注销、激活、重置 PIN、换卡和虚拟卡转实体卡等操作。

## 📄 正文

一张卡发行后，需要在整个生命周期中持续管理：持卡人可能要临时冻结卡片、丢卡后注销、收到实体卡后激活，或在忘记 PIN 时重置。无论操作来自后台运营人员，还是终端用户在接入机构应用内自行发起，您都可以通过同一套 `/open-api/card/v1/` 接口，用 `cardId` 定位并管理对应卡片。

作为持牌、自有 BIN 的发卡机构，DCS 在底层完成与卡组织、发卡处理器之间的状态同步，您只需关心业务语义：这张卡现在是什么状态、允许做什么操作。

> **前置条件**：您需要先成功开卡并拿到 `cardId`。如果还不清楚如何申请，请先阅读[开卡](./card-issuing)。

## 核心概念：卡状态机

DCS 用 `status` 字段表达卡的生命周期阶段，所有管理操作本质上都是在驱动这台状态机。

<Frame>
  <img className="block dark:hidden" src="https://mintcdn.com/dcs-0bf7a937/oUoeUKtwWWK2o-Li/imgs/diagrams/pa-card-states-light.svg?fit=max&auto=format&n=oUoeUKtwWWK2o-Li&q=85&s=22e7d3d49e84edb0acbbdaf2e94e7b17" alt="卡状态机" width="812" height="320" data-path="imgs/diagrams/pa-card-states-light.svg" />

  <img className="hidden dark:block" src="https://mintcdn.com/dcs-0bf7a937/oUoeUKtwWWK2o-Li/imgs/diagrams/pa-card-states-dark.svg?fit=max&auto=format&n=oUoeUKtwWWK2o-Li&q=85&s=b45407e5e419e7f19001c817095cc318" alt="卡状态机" width="812" height="320" data-path="imgs/diagrams/pa-card-states-dark.svg" />
</Frame>

| 状态                         | 含义                          | 谁能改变它 | 可执行操作        |
| :------------------------- | :-------------------------- | :---- | :----------- |
| `PENDING_ACTIVATION`（等待激活） | 实体卡已发行但尚未激活的初始状态（仅实体卡有此状态）  | 接入机构  | 激活           |
| `ACTIVATED`（已激活）           | 卡可正常交易                      | 接入机构  | 冻结、注销        |
| `FROZEN`（已冻结）              | 由持卡人或接入机构发起的暂停，可被接入机构解冻     | 接入机构  | 解冻、注销        |
| `BLOCKED`（已阻止）             | 由发卡行/风控发起的阻止，接入机构**无法**直接解冻 | 仅 DCS | 等待 DCS 解除、注销 |
| `INVALID`（已无效）             | 已注销，永久失效，**不可逆**            | —     | 无            |

> **冻结（FROZEN）与阻止（BLOCKED）的区别**：`FROZEN` 是接入机构掌握的可逆开关；`BLOCKED` 是发卡行/风控侧出于合规或安全原因施加的限制，需 DCS 介入才能解除。两者都不是终态，只有 `INVALID` 是终态。

### 卡状态原因（statusReason）

当卡处于 `FROZEN` / `BLOCKED` / `INVALID` 时，可通过卡详情接口返回的 `statusReason` 进一步判断变更原因，用于向持卡人解释或决定后续动作。

| statusReason             | 适用状态    | 说明                                    |
| :----------------------- | :------ | :------------------------------------ |
| `NORMAL`                 | 全部      | 无特殊原因                                 |
| `USER_FREEZE`            | FROZEN  | 用户主动冻结                                |
| `USER_REQUESTED_CLOSURE` | BLOCKED | 持卡人主动销卡                               |
| `COMPLIANCE_REVIEW`      | BLOCKED | 合规审查阻止                                |
| `AUTHENTICATION_FAILED`  | FROZEN  | 验证失败冻结（连续 3 次 CVV / PIN 输入错误，卡片已暂停使用） |
| `SECURITY_RESTRICTION`   | BLOCKED | 风控安全阻止                                |
| `VERIFICATION_OVERDUE`   | BLOCKED | 验证逾期未完成（客户未在规定期限内回应或提供所需验证资料）         |
| `ACCOUNT_TERMINATED`     | BLOCKED | 账户已终止                                 |
| `OTHER`                  | BLOCKED | 其他原因                                  |

***

## 操作一览

下列接口均为 `POST`（除查询类外），统一在 `/open-api/card/v1/` 下；鉴权头、签名与响应结构见[鉴权指南](../../integration-resources/authentication)。

| 操作      | 方法 / 路径                                       | 谁做        | 适用卡  |
| :------ | :-------------------------------------------- | :-------- | :--- |
| 查询卡详情   | `GET /open-api/card/v1/detail`                | 接入机构      | 全部   |
| 冻结 / 解冻 | `POST /open-api/card/v1/freeze`               | 接入机构      | 全部   |
| 注销      | `POST /open-api/card/v1/terminate`            | 接入机构      | 全部   |
| 激活实体卡   | `POST /open-api/card/v1/physical-active`      | 接入机构      | 仅实体卡 |
| 重置 PIN  | `POST /open-api/card/v1/reset-pin`            | 接入机构（PCI） | 全部   |
| 获取卡寄送信息 | `GET /open-api/card/v1/shipping-info`         | 接入机构      | 仅实体卡 |
| 获取卡敏感信息 | `POST /open-api/card/v1/retrieve-secure-card` | 接入机构（PCI） | 全部   |
| 换卡（补发）  | `POST /open-api/card-order/v1/replace`        | 接入机构      | 全部   |

> 注：上表多数操作在 `/open-api/card/v1/` 下；**换卡**属卡订单域 `/open-api/card-order/v1/replace`，详见下文[换卡（补发）](#换卡（补发）)。

### 操作类调用通用时序

冻结/解冻、注销等操作卡接口遵循同一调用时序：接入机构收到持卡人请求 → 调对应接口 → 返回结果。

<Frame>
  <img className="block dark:hidden" src="https://mintcdn.com/dcs-0bf7a937/oUoeUKtwWWK2o-Li/imgs/diagrams/pa-card-ops-seq-light.svg?fit=max&auto=format&n=oUoeUKtwWWK2o-Li&q=85&s=38371907a36ffb601390dd5e08b0c74e" alt="操作类调用通用时序" width="476" height="318" data-path="imgs/diagrams/pa-card-ops-seq-light.svg" />

  <img className="hidden dark:block" src="https://mintcdn.com/dcs-0bf7a937/oUoeUKtwWWK2o-Li/imgs/diagrams/pa-card-ops-seq-dark.svg?fit=max&auto=format&n=oUoeUKtwWWK2o-Li&q=85&s=9268c00dfd38a72eeea0df550ed9f084" alt="操作类调用通用时序" width="476" height="318" data-path="imgs/diagrams/pa-card-ops-seq-dark.svg" />
</Frame>

> **关于响应结构**：所有接口返回统一结构 `{ code, message, messageDetail, data }`。`code` 标识业务结果、`message`/`messageDetail` 为提示文案（`messageDetail` 可携带可展示给终端用户的标题、图标、跳转链接）、`data` 为业务数据。code 的成功取值与完整错误码字典请见[鉴权指南](../../integration-resources/authentication)。

***

## 查询卡详情

```
GET /open-api/card/v1/detail
```

| 参数       | 位置    | 类型     | 必填 | 说明   |
| :------- | :---- | :----- | :- | :--- |
| `cardId` | query | string | 是  | 卡 ID |

返回卡状态、`statusReason`、卡类型、`panFirst6`（卡号前 6 位）、`panLast4`（卡号后 4 位）等信息，**不含**完整卡号、CVV 等敏感信息（敏感信息见下文「获取卡敏感信息」）。

```json theme={null}
{
  "code": "...",
  "message": "...",
  "data": {
    "cardId": "card_xxx",
    "enterpriseId": "ent_xxx",
    "profileId": "prof_xxx",
    "type": "VIRTUAL",
    "customerId": "cus_xxx",
    "status": "ACTIVATED",
    "statusReason": "NORMAL",
    "panFirst6": "441364",
    "panLast4": "0123",
    "createTime": "2026-01-01T10:00:00+08:00",
    "modifyTime": "2026-01-01T10:00:00+08:00"
  }
}
```

***

## 冻结 / 解冻

**冻结与解冻是同一个接口**，通过 `freeze` 布尔值切换方向——这是本页最容易踩坑的地方，请注意不要把它当成两个接口。

```
POST /open-api/card/v1/freeze
```

| 字段             | 类型      | 必填  | 说明                                      |
| :------------- | :------ | :-- | :-------------------------------------- |
| `cardId`       | string  | 是   | 卡 ID，最大长度 50                            |
| `freeze`       | boolean | 是   | **冻结/解冻开关**：`true` = 冻结卡；`false` = 解冻卡  |
| `freezeReason` | string  | 见说明 | 冻结原因，最大长度 20，如 `USER_FREEZE` / `NORMAL` |

> **`freezeReason` 何时必填**：仅冻结（`freeze=true`）时必填；解冻（`freeze=false`）时服务端不读取该字段，省略或传入都会被忽略。
>
> 在单自然日对同一张卡频繁解冻可能被限制，此时接口返回 `DAPI_CARD_UNFREEZE_DAILY_LIMIT_EXCEEDED`，次日重试即可。

请求示例（冻结）：

```json theme={null}
{
  "cardId": "card_xxx",
  "freeze": true,
  "freezeReason": "USER_FREEZE"
}
```

请求示例（解冻）：

```json theme={null}
{
  "cardId": "card_xxx",
  "freeze": false,
  "freezeReason": "NORMAL"
}
```

上例为完整写法；解冻请求可以只传 `cardId` 与 `freeze=false`。

响应 `data` 返回操作后的整张卡对象（结构同[查询卡详情](#查询卡详情)），其中 `status` 会变为 `FROZEN` 或 `ACTIVATED`。

<Warning>
  `freeze` 接口只能在 `ACTIVATED` ⇄ `FROZEN` 之间切换。处于 `BLOCKED` 的卡由发卡行/风控阻止，接入机构无法用本接口解除，需联系 DCS。
</Warning>

***

## 注销

注销是**不可逆**操作。卡被注销后状态变为 `INVALID`，无法再恢复为可用状态。

```
POST /open-api/card/v1/terminate
```

| 字段                 | 类型     | 必填 | 说明                                           |
| :----------------- | :----- | :- | :------------------------------------------- |
| `cardId`           | string | 是  | 卡 ID，最大长度 50                                 |
| `invalidateReason` | string | 是  | 注销原因，最大长度 20。`CARD_LOST`：丢失；`CARD_STOLEN`：被盗 |

```json theme={null}
{
  "cardId": "card_xxx",
  "invalidateReason": "CARD_LOST"
}
```

响应 `data` 返回注销后的卡对象，`status` = `INVALID`。

***

## 换卡（补发）

当持卡人的卡片丢失、损坏或需更换时，可对一张已有卡发起<b>换卡（补发）</b>订单：作废原卡并补发一张新卡。换卡产生一笔 `type=REPLACEMENT` 的卡订单。

> **换卡的硬规则**：
>
> * **换出来的一定是虚拟卡**。虚拟卡和实体卡都可以发起换卡，但新卡一律是虚拟卡；持卡人若仍需要实体卡，需在换卡完成后再走一次[虚拟卡转实体卡](./physical-card)。
> * **24 小时内换卡有次数上限**，超限返回 `DAPI_REPLACE_CARD_APPLY_LIMIT_EXCEEDED`，需退避后重试。
> * **卡号（PAN）会变**。这与虚转实不同（虚转实卡号不变），换卡后新卡是一个全新卡号。请提醒持卡人更新已绑定的自动扣款、订阅与商户预留卡信息。

```
POST /open-api/card-order/v1/replace
```

| 字段              | 类型     | 必填 | 说明                  |
| :-------------- | :----- | :- | :------------------ |
| `cardOrderRef`  | string | 是  | 卡订单幂等字段，最大长度 50     |
| `replaceCardId` | string | 是  | 被替换的 cardId，最大长度 50 |

```json theme={null}
{
  "cardOrderRef": "your-idempotent-ref",
  "replaceCardId": "card_xxx"
}
```

成功响应返回一笔卡订单，关键字段：

| 字段                          | 说明                     |
| :-------------------------- | :--------------------- |
| `cardOrderId`               | 卡订单 ID                 |
| `type`                      | 订单类型，此处为 `REPLACEMENT` |
| `cardId`                    | 新卡 cardId              |
| `replaceCardId`             | 被替换的原卡 cardId          |
| `status`                    | 订单状态（见下方说明）            |
| `errorCode` / `errorReason` | 失败时的错误码与原因             |

> **订单状态**：卡订单成功时的最终状态为 `COMPLETED`，失败时为 `FAILED`。处理响应时以这两个状态为准，也可结合是否已生成 `cardId` 辅助判断。

### 换卡流程

<Frame>
  <img className="block dark:hidden" src="https://mintcdn.com/dcs-0bf7a937/oUoeUKtwWWK2o-Li/imgs/diagrams/pa-replace-card-seq-light.svg?fit=max&auto=format&n=oUoeUKtwWWK2o-Li&q=85&s=3a1c9b02931eeb59c20832c35f647f24" alt="换卡流程" width="638" height="610" data-path="imgs/diagrams/pa-replace-card-seq-light.svg" />

  <img className="hidden dark:block" src="https://mintcdn.com/dcs-0bf7a937/oUoeUKtwWWK2o-Li/imgs/diagrams/pa-replace-card-seq-dark.svg?fit=max&auto=format&n=oUoeUKtwWWK2o-Li&q=85&s=105c1d01c7e6452df73f958715cec03d" alt="换卡流程" width="638" height="610" data-path="imgs/diagrams/pa-replace-card-seq-dark.svg" />
</Frame>

***

## 激活实体卡

**只有实体卡需要激活；虚拟卡发行后默认即为 `ACTIVATED`。** 实体卡寄出后处于 `PENDING_ACTIVATION`，持卡人收到卡后由接入机构调用本接口激活。

```
POST /open-api/card/v1/physical-active
```

| 字段       | 类型     | 必填 | 说明           |
| :------- | :----- | :- | :----------- |
| `cardId` | string | 是  | 卡 ID，最大长度 50 |

响应 `data` 返回卡对象，`status` 由 `PENDING_ACTIVATION` 变为 `ACTIVATED`。实体卡的申请与寄送流程详见[实体卡](./physical-card)。

***

## 获取卡寄送信息

实体卡寄出后，可查询物流单号以便向持卡人展示配送进度。

```
GET /open-api/card/v1/shipping-info
```

| 参数       | 位置    | 类型     | 必填 | 说明   |
| :------- | :---- | :----- | :- | :--- |
| `cardId` | query | string | 是  | 卡 ID |

```json theme={null}
{
  "code": "...",
  "data": {
    "cardId": "card_xxx",
    "trackingNumber": "SF1234567890",
    "trackingCompanyName": "SF Express"
  }
}
```

***

## 重置 PIN

`reset-pin` 用于设置实体卡的 PIN。出于 PCI 安全要求，所有敏感字段（原卡过期日期、CVV2、卡号后 4 位、新 PIN）都必须经 **AES/GCM 加密**后传入，并随请求附上加密所用的 `iv`。

> **此接口仅对具备 PCI 资质的接入机构开放。** 若接入机构没有 PCI 资质，请改用引导页方案（见下文「无 PCI 资质如何重置 PIN 与查看卡敏感信息」）。

```
POST /open-api/card/v1/reset-pin
```

| 字段                    | 类型     | 必填 | 说明                      |
| :-------------------- | :----- | :- | :---------------------- |
| `cardId`              | string | 是  | 卡 ID，最大长度 50            |
| `encryptedExpireDate` | string | 是  | 加密后的原卡过期日期，最大长度 200     |
| `encryptedCvv2`       | string | 是  | 加密后的原卡 CVV2，最大长度 200    |
| `encryptedPanLast4`   | string | 是  | 加密后的卡号后 4 位，最大长度 200    |
| `encryptedNewPin`     | string | 是  | 加密后的新 PIN，最大长度 200      |
| `iv`                  | string | 是  | 加解密所用 IV（初始化向量），最大长度 20 |

响应 `data` 为布尔值，`true` 表示重置成功。

**加密算法（AES/GCM/NoPadding）**：使用企业密钥（`enterpriseSecret`）作为 AES 密钥，每次随机生成 12 字节 IV（Base64 编码），认证标签长度 128 位。参考实现：

```java theme={null}
// 生成随机 IV（GCM 推荐 12 字节）
public static String generateIV() {
    byte[] iv = new byte[12];
    new SecureRandom().nextBytes(iv);
    return Base64.getEncoder().encodeToString(iv);
}

// GCM 加密
public static String encryptGCM(String plaintext, String enterpriseSecret, String base64IV) {
    SecretKey key = new SecretKeySpec(Base64.getDecoder().decode(enterpriseSecret), "AES");
    byte[] iv = Base64.getDecoder().decode(base64IV);
    Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
    cipher.init(Cipher.ENCRYPT_MODE, key, new GCMParameterSpec(128, iv));
    byte[] ct = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8));
    return Base64.getEncoder().encodeToString(ct);
}
```

> 关于 PIN 的概念性说明（PIN 与 CVV 的用途、何时需要），详见[虚拟卡](./virtual-card)。

***

## 获取卡敏感信息

`retrieve-secure-card` 返回完整卡号（`pan`）、`cvv2`、过期时间（`expireDate`）。返回值为加密形态，需配合 `iv` 用上文同样的 AES/GCM 算法解密。

> **此接口仅对具备 PCI 资质的接入机构开放。** 解密后的明文应直接在前端向持卡人展示，**不应经过接入机构后端持久化**。

```
POST /open-api/card/v1/retrieve-secure-card
```

| 字段       | 类型     | 必填 | 说明           |
| :------- | :----- | :- | :----------- |
| `cardId` | string | 是  | 卡 ID，最大长度 50 |

```json theme={null}
{
  "code": "...",
  "data": {
    "cardId": "card_xxx",
    "pan": "<加密卡号>",
    "cvv2": "<加密 CVV2>",
    "expireDate": "<加密过期时间>",
    "iv": "<解密所用 IV>"
  }
}
```

无 PCI 资质时的替代方案，以及 SecureToken 两段式取数细节，统一见[获取卡敏感信息](./secure-card)。

***

## 无 PCI 资质如何重置 PIN 与查看卡敏感信息

如果接入机构没有 PCI 资质，**不能**直接调用 `reset-pin` 或 `retrieve-secure-card`，而应使用引导页方案：由 DCS 托管的安全页面直接面向持卡人完成 PIN 设置或卡密展示，敏感数据不经过接入机构系统。

```
POST /open-api/card-redirect/v1/guidance-link
```

该接口返回一个 DCS 托管的引导链接，接入机构将其下发给持卡人在前端打开即可。引导页方案的完整参数与使用方式见[获取卡敏感信息](./secure-card)。

***

## 下一步

卡的发行与维护流程已经完成。接下来可以：

* 配置消费限额，参阅[卡限额（Velocity Limits）](./velocity-limits)；
* 处理持卡人刷卡时的实时授权，参阅[授权转发](../transactions/authorization)。
