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

# 升级虚拟账户 API 集成

> 在新的申请流程于 Production 生效前，完成现有虚拟账户集成的适配。

如果你的集成已经调用 Create Virtual Account 或处理虚拟账户 Webhook，请按照本指南完成升级。新流程将于 **2026 年 8 月 13 日**在 Sandbox 生效，并于 **2026 年 9 月 3 日**在 Production 生效。

<Warning>
  请在 Production 生效日期前完成升级。Create 成功响应和虚拟账户 Webhook 数据都会发生变化。
</Warning>

<h2 id="changes-at-a-glance">
  变更概览
</h2>

| 集成环节        | 旧行为                                    | 新行为                                              |
| ----------- | -------------------------------------- | ------------------------------------------------ |
| Create 成功响应 | HTTP `202`，返回 `message` 和 `request_id` | HTTP `200`，在 `data` 中返回已受理的申请                    |
| 请求关联        | 使用 `request_id` 或 `x-request-id`       | 使用 `application_id`                              |
| 国家与币种       | 没有申请国家；币种可包含多个值                        | 一个必填 `country` 和一个必填 `currency`                  |
| 收款方式        | 请求选择一种方式                               | 传 `LOCAL` 或 `SWIFT`，或省略 `payment_method` 以评估两种方式 |
| 结果处理        | 没有收款方式级别的申请结果                          | 逐项处理 `results[]`                                 |
| 申请查询        | 没有申请查询接口                               | 使用申请列表与申请详情接口                                    |
| Webhook     | 事件可能代表一条已开通银行信息                        | 事件代表整笔申请，并使用 `public_version` 处理顺序               |

Create 路径仍为 `POST /v1/virtual/accounts`。

<h2 id="1-update-the-create-request">1. 更新 Create 请求</h2>

继续传入必填的 `x-idempotency-key`，并按以下方式修改请求构造逻辑：

1. 新增必填的两位国家代码 `country`。
2. `currency` 只传一个三位币种代码。
3. `payment_method` 传 `LOCAL` 或 `SWIFT`，或省略以评估两种方式。不要传 `ALL` 或 `AUTO`。
4. 将 `nickname` 作为可选字段处理。
5. 移除该接口中依赖 `x-request-id` 的逻辑。

如果为子账户创建申请，请继续在 `x-on-behalf-of` 中传入其账户 ID。请求结构详见 [Create Virtual Account](/zh/global-account/v1.6/api-reference/create-virtual-account)，有效值详见[支持的参数组合](/zh/global-account/v1.6/guide/virtual-account-api-lifecycle#choose-what-to-request)。

网络失败后重试时，请为同一账户发送相同请求，并复用同一个 `x-idempotency-key`。任何申请输入发生变化时，都应使用新的 key。

<h2 id="2-replace-the-create-success-response">2. 替换 Create 成功响应</h2>

将 HTTP `200` 解析为“申请已受理”，而不是“银行信息已可用”。

停止解析 `message` 和 `request_id`，改为：

1. 将 `data.account_id` 和 `data.direct_id` 与申请一起保存。
2. 保存 `data.application_id`。
3. 保存 `data.public_version`。
4. 逐项处理 `data.results[]`，并通过 `payment_method` 识别。
5. 只有当结果为 `COMPLETED` 且具体记录为 `ACTIVE` 时，才使用银行信息。

省略 `payment_method` 时，一项结果可能为 `SKIPPED`，另一项为 `SUBMITTED`。不要将申请顶层状态当成每种收款方式的状态。

<h2 id="3-add-application-queries">3. 增加申请查询</h2>

为集成增加以下接口：

* [List Virtual Account Applications](/zh/global-account/v1.6/api-reference/list-virtual-account-applications) 用于查找和对账申请。`page_number` 和 `page_size` 必填。
* [Retrieve Virtual Account Application](/zh/global-account/v1.6/api-reference/retrieve-virtual-account-application) 用于查询某个 `application_id` 的最新完整详情。

[List Virtual Accounts](/zh/global-account/v1.6/api-reference/list-virtual-accounts) 继续用于查询已开通的银行信息，不会列出待处理申请。

<h2 id="4-update-the-webhook-consumer">4. 更新 Webhook 消费逻辑</h2>

处理全部三种申请事件：

| 事件                       | 必须执行的操作                               |
| ------------------------ | ------------------------------------- |
| `virtual.account.create` | 保存已受理的申请。不要假设它一定晚于 Create 响应到达。       |
| `virtual.account.update` | 仅当 `public_version` 高于本地已存版本时，应用新的数据。 |
| `virtual.account.closed` | 应用最终的 `CLOSED` 数据，并停止使用全部关联银行信息。      |

保留现有的验签与响应确认流程，并将关联和顺序处理逻辑改为：

1. 使用 `event_id` 对投递去重。
2. 使用 `data.account_id` 将事件关联到对应账户；如适用，使用 `data.direct_id` 识别其主账户。
3. 使用 `data.application_id` 定位申请。
4. 仅应用更高的 `data.public_version`。
5. 应用事件后逐项处理全部结果。
6. 发现版本缺口或疑似乱序时，调用 Retrieve 查询最新详情。

事件时机、示例和补偿处理详见[虚拟账户申请 Webhook](/zh/global-account/v1.6/webhooks/virtual-account-create-update)。

<h2 id="5-separate-request-errors-from-later-failures">5. 区分请求错误与后续失败</h2>

Create 同步返回 `400` 表示没有创建申请，后续也不会产生申请 Webhook。请修正请求或账户配置后再试。

HTTP `200` 之后，某种收款方式仍可能变为 `FAILED`。此时请处理 `virtual.account.update` 事件，并使用 `results[].error.code` 决定后续操作。错误码和建议操作详见[通过 API 集成虚拟账户](/zh/global-account/v1.6/guide/virtual-account-api-lifecycle#handle-errors)。

<h2 id="sandbox-checklist">
  Sandbox 验收清单
</h2>

Production 上线前，请确认你的集成能够：

* 发送一组受支持的 `country` 和 `currency`，并按需传入 `payment_method`。
* 使用同一 `x-idempotency-key` 重试相同请求，并保持一个 `application_id`。
* 拒绝使用同一个 key 提交不同的申请输入。
* 解析 HTTP `200`，并逐项处理 `results[]`。
* 处理同一申请中一项 `SKIPPED`、另一项 `SUBMITTED` 的情况。
* 保存并比较 `application_id + public_version`。
* 查询申请列表和最新详情。
* 接受早于或晚于 Create 响应到达的 `virtual.account.create`。
* 使用 `account_id` 和 `direct_id` 将申请事件关联到正确的账户。
* 在不依赖到达顺序的情况下应用 `COMPLETED`、`FAILED` 和 `CLOSED` 数据。
* 只使用 `ACTIVE` 银行信息，并在 `close_reason` 为空时仍停止使用 `CLOSED` 记录。
* Create 同步报错后停止等待 Webhook。

通过以上检查后，请使用[通过 API 集成虚拟账户](/zh/global-account/v1.6/guide/virtual-account-api-lifecycle)作为后续接入指南。
