# 9.8-人民币结汇 POBO、锁汇与提现付款页面选项优化

## 1. 背景与目标

### 1.1 业务背景与问题

1. **人民币结汇 POBO**。易宝人民币结汇接口同名付款必须先向通道报备付款人，且报备状态为**成功**后方可使用。当前平台未对接，商户无法以自己名义完成人民币端付款，收款方对账付款人名称与预期不符，产生退汇/驳回与人工核对成本。
2. **结汇汇率波动与 60 秒锁汇诉求**。人民币结汇（外币兑人民币）交易受汇率实时波动影响大，商户在下单时需要明确锁定汇率并精准试算扣款或到账金额。上游已开放 60 秒询价锁汇能力（支持定额买与定额卖），当前系统未对接，商户无法锁汇下单，导致实际成交汇率与下单预期存在偏差。
3. **上游同名付款规则收紧**。通过国际汇款（SWIFT）方式发起的所有交易，不再支持以平台付款人（Global Payment E-Commerce Limited）名义付款，仅支持以子商户注册企业主体名义付款——即 **SWIFT 不再支持非同名付款**。当前付款表单对 SWIFT 非同名组合不拦截，订单提交后被通道拒绝。
4. **提现页面缺少同名付款口径**。同名付款选项仅存在于付款表单，提现（CNY 到账同样走人民币端付款）未同步，口径不一致。
5. **中间行费用承担方与清分方式不符**。中间行费用仅存在于 SWIFT 电汇链路；当前表单在 Local（本地清分）账户下仍展示「中间行费用承担方」选项，误导商户选择无意义的承担方式。

### 1.2 目标与成功标准

| # | 目标 | 成功标准（业务可观察结果） | 受益角色 | 关联验收 |
|---|---|---|---|---|
| G-01 | 付款人报备全自动与即时告警 | KYC 通过即自动纳入：系统定时批量报备（入参仅 `subMerchantId`）、定时查询回写，商户无任何操作；不自动重试；1 次失败或停留超 120 分钟未成功即经 outbox 向独立配置邮箱告警；运维层手动 job 兜底；CLOSE 本期不处理（见 §5.2） | 商户、运营 | AC-01~AC-06, AC-14, AC-20 |
| G-02 | 同名付款报错展示 | 未成功时选择同名付款提交时提示报错（文案 A/B） | 商户 | AC-07~AC-09 |
| G-03 | SWIFT 非同名硬拦截 | SWIFT 账户下「否（非同名）」不可选 | 商户、运营 | AC-10 |
| G-04 | 承担方选项与清分方式一致 | 承担方选项仅海外付款 + SWIFT 清分下展示（仅 OUR/SHA，无 BEN）；其余场景（外币 Local / 人民币结汇 / 提现全部）隐藏且固定记录 OUR（R-12/R-15） | 商户 | AC-11, AC-12 |
| G-05 | 人民币结汇 60 秒锁汇下单 | 结汇支持 60 秒实时锁汇（定额买/定额卖、统一外扣），展示参考汇率、倒计时与试算金额；下单金额 `amount` 必填且严格取锁汇返回的 `debitAmount`，60 秒内携 `inquiryToken` 提交，超时硬拦截提示刷新汇率 | 商户 | AC-15~AC-19 |

### 1.3 不做的影响

若不对接：人民币端以商户主体名义付款（POBO）能力无法开放；结汇汇率波动造成商户成本不可控与对账纠纷；SWIFT 非同名订单持续被上游拒绝形成失败订单与客诉；提现与付款口径分裂。

---

## 2. 用户角色与场景

### 2.1 角色、权限与职责

| 角色 | 入口 | 可见条件 | 可执行动作 | 明确禁止 | 业务责任 |
|---|---|---|---|---|---|
| 商户 | 付款/提现表单（既有入口，无新增） | 报备状态通过同名付款提交校验结果体现（未成功提交时报错）；人民币结汇表单展示 60s 锁汇汇率与试算 | 选择同名/非同名付款（SWIFT 下「否」不可选）；输入结汇金额并触发 60s 锁汇；提交付款/提现 | 无任何报备设置/查询/重试入口（三端页面均无） | 无（报备全流程无感知；锁汇超时需自行刷新） |
| 运营 | 独立配置告警邮箱（经 outbox 服务发送） | **1 次报备失败或 120 分钟查询未查到成功**收到告警邮件 | 线下跟进商户与通道原因 | 页面无任何报备操作入口 | 收到告警后人工跟进处置 |
| 运维 | 运维层脚本/命令行（非页面入口） | 运维权限 | 对指定商户号执行手动报备 job（不处理记录） | 页面无任何报备操作入口 | 针对异常商户手动触发报备 |
| 系统（定时任务/服务） | — | — | 定时批量报备、定时查询回写、outbox 告警邮件发送、结汇 60 秒询价锁汇与令牌校验、结汇下单参数拼装 | — | 报备与锁汇链路唯一执行者 |

### 2.2 核心业务场景

| 场景 | 流程 | 用户可见结果 |
|---|---|---|
| S-01 新商户完成 KYC | KYC 通过 → 自动纳入待报备 → 下一批次报备 → 定时查询回写成功 | 同名付款提交不再报错，可正常下单 |
| S-02 报备完成前付款/提现 | **人民币结汇场景**，商户在报备未成功时选择「是（同名付款）」提交 | 提交报错并按状态提示原因（处理中/请联系业务员处理）；可改选「否」继续。报备仅影响人民币结汇，海外付款（SWIFT/Local）不涉及报备（见 R-02） |
| S-03 SWIFT 账户付款 | 选择清分方式为 SWIFT 的收款账户 | 「否（非同名）」不可选；「是」可提交但受报备状态校验；「中间行费用承担方」选项展示（仅 OUR/SHA） |
| S-04 Local 账户付款/提现 | 选择清分方式为 Local 的账户 | 「中间行费用承担方」隐藏（数据记录 OUR）；清分方式只读展示 |
| S-05 报备失败或超时告警 | 定时查询回写失败（1 次即触发）或超 120 分钟未成功 → 通过 outbox 服务触发告警邮件 | **仅人民币结汇场景**同名付款提交报错（请联系业务员处理）；海外付款（SWIFT/Local）不需要报备、不受任何影响 |
| S-06 人民币结汇 60 秒锁汇下单 | 选择人民币结汇，输入金额（定额卖或定额买） | 触发 60s 锁汇倒计时，展示参考汇率、外扣手续费与到账/扣款金额；60s 内点击提交结汇成功下单（下单金额 `amount` 严格取锁汇返回 `debitAmount`） |
| S-07 结汇锁汇超时失效 | 锁汇倒计时归零（超过 60 秒未提交） | 提交拦截并提示「汇率已失效，请重新获取汇率」；点击「刷新汇率」重新锁汇并重置 60s 倒计时 |

---

## 3. 功能范围

### 3.1 能力清单与发布状态

| # | 能力 | 端 | 本期状态 | 生效条件 |
|---|---|---|---|---|
| F-01 | 付款人自动报备（KYC 后定时批量触发 + 定时查询回写；入参仅 `subMerchantId`；**不做失败重试**） | 后端 | **9.8 开放** | 商户 KYC 认证通过（终态） |
| F-02 | 报备告警（**1 次失败即告警 + 120 分钟未成功告警**，对接 outbox 服务，邮箱单独配置）+ 运维层手动 job（不处理记录） | 后端/运维 | **9.8 开放** | 1 次失败 / 停留超 120 分钟 / 运维手动处置 |
| F-03 | 付款页「是否同名付款」选项与报备状态校验（未成功时提交报错提示） | 商户端 | **9.8 开放** | 付款表单 |
| F-04 | 提现页同步增加「是否同名付款」选项（规则与付款页一致） | 商户端 | **9.8 开放（新增）** | 提现表单 |
| F-05 | SWIFT 不再支持非同名付款（选项禁用 + 提交守卫） | 商户端 | **9.8 开放** | 所选账户清分方式 = SWIFT |
| F-06 | 清分方式只读展示；「中间行费用承担方」仅 SWIFT 清分时显示（选项仅 OUR/SHA，无 BEN），Local 隐藏固定 OUR | 商户端 | **9.8 开放** | 选择收款账户/提现卡后 |
| F-07 | 人民币结汇 60 秒询价锁汇（定额买/定额卖、手续费统一外扣计算、参考汇率试算、60s 倒计时与超时刷新） | 商户端/后端 | **9.8 开放（新增）** | 付款/提现为人民币结汇场景 |
| F-08 | 人民币结汇下单携带锁汇令牌与严格金额映射（`amount` 必填且严格取锁汇 `debitAmount`、`inquiryToken`、`tradeSide`、`paymentAmount` 与 `appointPayerId` 联动） | 后端 | **9.8 开放（新增）** | 人民币结汇下单提交 |

### 3.2 In Scope / Out of Scope

| 范围 | 项 | 说明 |
|---|---|---|
| In | 付款人报备全链路（自动报备/查询/1次失败告警/120分钟未成功告警/运维 job） | 详见 §4.1 与 R12 立项稿；入参仅 `subMerchantId` |
| In | 付款页、提现页同名付款选项与提交校验（未成功报错提示） | 两页规则一致 |
| In | SWIFT 非同名禁用与提交守卫 | 对齐上游「SWIFT 不再支持平台付款人名义」 |
| In | 清分方式只读展示；承担方选项仅海外付款 + SWIFT 显示且仅限 OUR/SHA | 付款页与提现页同构 |
| In | 人民币结汇 60 秒询价锁汇与下单链路（定额买/定额卖、统一外扣、倒计时、超时守卫、`amount` 严格取锁汇 `debitAmount` 上送） | 详见 §4.4 |
| Out | 付款人报备失败自动重试 | **明确不做系统自动重试**（1次失败即告警，由线下人工/运维介入处置） |
| Out | 结汇手续费内扣模式 | **明确不开放内扣**（内部统一按外扣 OUTER 计算，保持极简） |
| Out | 中间行费用承担方 BEN（收款人承担） | **无 BEN 内容**（仅支持 OUR / SHA） |
| Out | 运维手动 job 处理业务记录 | **明确不处理记录**（仅运维层工具，不留存业务审计记录） |
| Out | 三端页面任何手动报备设置/查询/重试/注销入口 | **明确不做**（报备全自动；兜底走运维层 job） |
| Out | Local 受限地区（英国/澳大利亚/美国/欧元区）同币种/错币种付款人名义规则 | 上游已生效，平台前端联动**后续迭代承接**（本期 Local 不区分地区限制「否」的可用性；原型已按上游口径演示，正式链路以后续 PRD 为准） |
| Out | 自定义付款人名义（除注册主体外的第三类付款人）维护与选择 | 上游概念，本期不开放 |
| Out | 海外付款（外币不结汇）锁汇 | 外币不结汇链路不涉及人民币汇率询价 |
| Out | 报备结果的通知触达（站内/邮件通知商户） | 明确不触达；商户仅通过表单选项可用性与提交校验感知 |

---

## 4. 页面/交互说明

### 4.1 F-01 / F-02 付款人报备链路（系统侧，无页面）

1. **纳入**：商户 KYC 认证通过（终态成功）当刻自动进入待报备名单，商户无感知、无消息。
2. **报备**：定时任务按批次汇总「待报备」商户，向通道提交付款人设置（入参仅 `subMerchantId`），提交后置「报备中」。
3. **查询**：定时任务对「报备中」商户批量查询并回写：成功 / 失败（含失败原因）。查询返回**注销（CLOSE）本期不做处理**：忽略该返回、不回写、不重报，商户状态保持不变。
4. **无自动重试**：报备失败后**系统不做自动重试**；状态保持「报备失败」，等待线下人工介入处置或运维手动 job 重新报备。
5. **告警机制（双触发，对接新 outbox 服务）**：
   - 告警邮件统一通过系统**新 outbox 服务**发送，收件邮箱支持**独立单独配置**；
   - **1 次失败即告警**：通道查询返回失败（FAILED）或提交通道失败时，立即发送告警邮件（含商户号、企业名称、失败原因、发生时间）；
   - **120 分钟超时告警**：待报备/报备中累计停留超过 120 分钟仍未变更为 SUCCESS 终态，立即发送告警邮件（含商户号、企业名称、当前状态、停留时长）。
   - 报备成功后告警状态解除；同一故障生命周期内不重复触发同一类型告警。
6. **运维手动兜底**：运维层手动报备 job 按单商户号立即发起一次报备（等同批次报备效果），结果仍走定时查询回写；**job 仅在运维层使用，不处理记录**；不影响自动链路。

> 报备/查询频率、批量大小、幂等与退避属研发设计；业务约束：**批处理、全自动、商户无感知、即时告警、job 不处理记录**。完整规则（含异常态）见 `prd/9月迭代-R12-人民币结汇POBO付款人报备.md` §4~§7。

### 4.2 F-03 / F-04 付款页与提现页「是否同名付款」选项（两页同构）

#### 4.2.1 业务流程

```
进入付款/提现表单 → 选择币种 → 选择收款账户（供应商）/提现卡
    ↓
展示「是否同名付款」选项（是 / 否）：
    ├─ 「是（同名付款）」：可正常选择；**人民币结汇（到账 CNY）场景**提交时校验报备状态——
    │     报备成功 → 正常提交（结汇下单透传 appointPayerId）
    │     未成功（待报备/报备中/失败）→ 提交报错，按状态提示原因（文案 A/B）
    │     （报备仅影响人民币结汇；海外付款无论 SWIFT/Local 均不做报备校验）
    └─ 「否（非同名）」：按清分方式判定——
          SWIFT 账户 → 选项禁用不可选（F-05）
          Local 账户 → 可选，正常提交（本期不区分地区，见 Out of Scope）
```

![图 4-1 商户端付款表单（人民币结汇到账 CNY）](/screenshots/r12-pobo-payer-filing/payment-cny-both-selectable.png)
*图 4-1 商户端付款表单（对应 R-02~R-06：到账 CNY 时同名付款是/否均可选，未报备成功在提交时报错拦截，无承担方选项）*

#### 4.2.2 业务规则与联动

| # | 规则 | 说明 |
|---|---|---|
| R-01 | 报备触发条件 | 仅 KYC 认证通过（终态成功）的商户进入报备链路 |
| R-02 | 同名付款提交校验 | 「是（同名付款）」选项可正常选择；**人民币结汇（到账 CNY）场景**提交时校验本商户报备状态：成功 → 正常提交；未成功 → 提交报错并按状态提示原因（文案 A/B），不改单、不进入验密。**报备仅影响人民币结汇；海外付款（外币不结汇）无论 SWIFT/Local 均不做报备校验** |
| R-03 | 「否」可选条件（本期口径） | ① **到账币种为 CNY 时**：「否」永远可选，与「是」并存；<br>② **到账币种为非 CNY 时**：清分方式 = Local 时「否」可选；清分方式 = SWIFT 时「否」**禁用不可选**（上游：SWIFT 仅支持注册主体名义付款） |
| R-04 | 报错不静默 | 报错提示需说明原因与下一步（等待报备完成 / 联系业务员处理），可改选「否」以非同名方式操作 |
| R-05 | 报错文案 | 待报备/报备中：「付款人报备处理中，暂不能提交同名付款」；报备失败：「付款人报备未成功，请联系业务员处理」（不提示系统自动重试，失败由线下人工介入）。均附「可先选择『否』以非同名方式付款」。报错校验仅限人民币结汇场景，海外付款（SWIFT/Local）不涉及 |
| R-06 | 默认值 | 「是否同名付款」默认「是」，商户可改选；默认值不随报备状态变化（状态仅在提交时校验） |
| R-07 | 提现同构 | 提现表单「是否同名付款」选项位置与付款页完全一致（位于「其他信息」卡片内），报错文案、默认值与守卫规则与付款页完全同构 |
| R-08 | 提交守卫 | 提交时后端按同一条件复核（报备成功 + SWIFT 限同名）；会话期间状态变化（如被注销）时同样拦截报错 |
| R-09 | 无页面入口 | 三端页面均无报备设置、查询、重试、注销的任何入口与按钮 |
| R-10 | 非同名不受报备影响 | 报备状态只校验同名付款；Local 账户的非同名付款任何报备状态下均可正常提交 |

#### 4.2.3 提现页差异与同构说明

提现页面与付款页在「其他信息」卡片布局、同名付款选项位置、SWIFT 禁非同名规则上**完全同构**；提现全部场景均不展示中间行费用承担方（固定记录 OUR）。

![图 4-2 商户端提现表单（人民币结汇到账 CNY）](/screenshots/r12-pobo-payer-filing/withdraw-cny-both-selectable.png)
*图 4-2 商户端提现表单（对应 R-07、R-15：同名付款选项位于「其他信息」卡片中，与付款页完全同构，是/否均可选，提现无承担方）*

### 4.3 F-06 清分方式展示与承担方选项联动（仅外币 SWIFT 付款展示承担方；提现与其余场景无承担方）

承担方按业务场景呈现差异：

| 场景 | 清分方式只读展示 | 「是否同名付款」选项 | 「中间行费用承担方」选项 | 提交数据承担方 |
|---|---|---|---|---|
| **付款·外币 + SWIFT 清分** | `SWIFT（国际电汇）` | **仅“是”**（“否”置灰禁用） | **展示并必选**（**仅 OUR / SHA，无 BEN**） | 按商户选择（OUR/SHA） |
| **付款·外币 + Local 清分** | `LOCAL（本地清分）` | **是 / 否 均可选** | **不展示**（隐藏卡片） | 固定记录 OUR |
| **付款·人民币结汇（到账 CNY）** | 随所选账户展示 | **是 / 否 均可选**（提交校验报备） | **不展示**（隐藏卡片） | 固定记录 OUR |
| **提现·全部场景（含外币/CNY）** | 随所选提现卡展示 | 随清分方式联动（CNY均可选/SWIFT仅是） | **不展示**（全场景无承担方） | 固定记录 OUR |

![图 4-3 商户端付款表单（外币 SWIFT）](/screenshots/r12-pobo-payer-filing/payment-foreign-swift-charge-indicator.png)
*图 4-3 商户端付款表单（外币 SWIFT 场景：清分方式 SWIFT，同名付款仅支持“是”，展示「中间行费用承担方」选项 OUR/SHA，无 BEN）*

![图 4-4 商户端付款表单（外币 Local）](/screenshots/r12-pobo-payer-filing/payment-foreign-local-both-selectable.png)
*图 4-4 商户端付款表单（外币 Local 场景：清分方式 LOCAL，同名付款是/否均可选，无中间行费用承担方）*

![图 4-5 商户端提现表单（外币 SWIFT）](/screenshots/r12-pobo-payer-filing/withdraw-foreign-swift-no-charge.png)
*图 4-5 商户端提现表单（外币 SWIFT 场景：清分方式 SWIFT，同名付款仅支持“是”，提现全场景无中间行费用承担方）*

| # | 规则 | 说明 |
|---|---|---|
| R-11 | 清分方式只读展示 | 选择账户后在表单中只读展示「清分方式：SWIFT（国际电汇）/ LOCAL（本地清分）」，取自所选账户，不可编辑；未选账户不展示（付款/提现两页同构） |
| R-12 | 承担方选项存在条件 | 「中间行费用承担方」选项**仅海外外币付款且清分方式 = SWIFT 时展示**；其余场景（外币 Local、人民币结汇、提现全部场景）一律不展示该卡片 |
| R-13 | 承担方选项集（仅外币 SWIFT 付款适用） | **选项仅支持 OUR（付款人承担）/ SHA（共同承担），无 BEN（收款人承担）相关内容** |
| R-14 | 切换账户重判 | 付款内更换账户后清分方式与承担方选项随之重新判定；承担方取值按既有默认逻辑重置 |
| R-15 | 固定 OUR 记录 | 选项不展示的场景（外币 Local / 人民币结汇 / 提现全部），提交数据承担方一律固定记录 **OUR（付款人承担）** |

### 4.4 F-07 / F-08 人民币结汇 60 秒询价锁汇与下单交互说明

#### 4.4.1 业务流程与锁汇时序

```
进入人民币结汇付款/提现表单 → 选择付款原币（USD/EUR等）与到账币种（CNY）
    ↓
选择交易方向并输入金额：
    ├─ 定额卖（CUSTOMER_SELL）：输入外币付款金额（系统内部统一按外扣 OUTER 计算手续费）
    └─ 定额买（CUSTOMER_BUY）：输入人民币到账金额（系统内部统一按外扣 OUTER 计算手续费）
    ↓
系统自动调用询价接口（/rest/v1.0/gpt/stdexc/inquiry，feeBear 固定传 OUTER）锁汇 60 秒：
    ├─ 返回询价令牌 inquiryToken、参考汇率 fxRate、手续费 feeAmount、出款金额 debitAmount、到账金额 paymentAmount
    ├─ 表单启动 60 秒锁汇倒计时，展示「锁汇汇率：1 USD = x.xxxx CNY（有效时间剩 xx 秒）」与试算明细
    ↓
商户操作与提交：
    ├─ 60 秒内点击「提交」：发起结汇下单（/rest/v1.0/gpt/stdexc/commit-order）——
    │     * 付款金额 amount 字段必填：严格取自锁汇返回的 debitAmount 进行上送！
    │     * 必传参数：inquiryToken、tradeSide、paymentAmount、paymentCurrency="CNY"、feeBear="OUTER"
    │     * 若勾选「是（同名付款）」，同时透传报备成功的 appointPayerId
    └─ 超过 60 秒未提交：锁汇令牌失效，提交按钮置灰/点击拦截提示「汇率已失效，请重新获取汇率」
          商户点击「刷新汇率」重新触发询价锁汇，重置 60 秒倒计时
```

#### 4.4.2 锁汇与下单规则

| # | 规则 | 说明 |
|---|---|---|
| R-16 | 交易方向（tradeSide）与统一外扣计算 | ① **定额卖（`CUSTOMER_SELL`）**：商户指定卖出外币金额（`debitAmount`），系统根据实时汇率反算 CNY 到账金额（`paymentAmount`）；<br>② **定额买（`CUSTOMER_BUY`）**：商户指定 CNY 到账金额（`paymentAmount`），系统根据实时汇率反算扣除外币金额（`debitAmount`）；<br>③ **手续费统一外扣（`OUTER`）**：询价与下单接口 `feeBear` 固定上送 `OUTER`，页面不提供内扣选项，全场景口径一致。 |
| R-17 | 60 秒锁汇倒计时与高亮 | 询价接口成功返回后，表单展示：参考汇率、手续费金额（外扣）、预计出款外币（`debitAmount`）与预计到账 CNY（`paymentAmount`），并以动态倒计时标签展示「剩余有效时间：xx 秒」。 |
| R-18 | 超时失效硬拦截 | 倒计时归零后，`inquiryToken` 视作失效。此时点击提交直接硬拦截，提示「汇率已失效，请重新获取汇率」，不发起结汇下单请求。 |
| R-19 | 汇率刷新机制 | 表单在汇率失效态或倒计时期间提供「刷新汇率」图标/按钮；金额修改、币种切换或手动点击刷新时，前端重新调用询价接口获取新 `inquiryToken` 并重置 60 秒倒计时。 |
| R-20 | 结汇下单金额必填与锁汇上送规则 | 结汇下单中付款金额字段 `amount` 必填，且严格取自锁汇询价返回的 `debitAmount`（出款金额；定额买为锁汇反算值，定额卖与商户输入一致）。同时必传 `inquiryToken`、`tradeSide`、`paymentAmount`、`paymentCurrency="CNY"`、`feeBear="OUTER"`。 |
| R-21 | 锁汇与同名付款联动 | 若结汇同时选择「是（同名付款）」，询价与下单接口均须携带报备成功的 `appointPayerId`（商户钱包申请 ID / 报备成功 ID）；若报备未成功，按 R-02 规则在提交时报错拦截。 |

---

## 5. 字段说明

### 5.1 关键业务字段

| 字段 | 含义与文案 | 来源 | 可见/可编辑 | 参与规则 |
|---|---|---|---|---|
| 付款人报备状态（商户级） | 同名付款人向通道的报备进展，仅系统可变 | 系统定时任务回写 | 商户不可见（通过同名付款提交校验结果体现） | R-02 |
| 设置付款人入参（`subMerchantId`） | 子商户编号，上游设置付款人仅入参此单一字段 | 系统提取商户子商编 | 商户不可见（系统内部透传） | §4.1 |
| 「是否同名付款」选项 | 是（以商户注册主体名义付款）/ 否（非同名）；默认「是」 | 商户选择 | 两页表单；「否」在 SWIFT 清分下禁用 | R-02~R-08, R-21 |
| 报错文案（A/B） | 报备处理中 / 报备未成功请联系业务员处理 | 按报备状态生成 | 提交报错时展示（仅人民币结汇场景） | R-05 |
| 清分方式 | SWIFT（国际电汇）/ LOCAL（本地清分） | 所选账户/提现卡自带 | 只读展示 | R-11~R-12 |
| 中间行费用承担方 | OUR（付款人承担）/ SHA（共同承担） | 商户选择（仅海外付款 + SWIFT 清分，**无 BEN**）；其余场景选项隐藏，提交固定记录 OUR | 仅海外付款 + SWIFT 清分时可见可选 | R-12~R-15 |
| 交易方向（tradeSide） | 定额卖（`CUSTOMER_SELL`） / 定额买（`CUSTOMER_BUY`） | 商户选择/输入触发 | 人民币结汇表单可见可选 | R-16 |
| 询价令牌（inquiryToken） | 锁汇 60 秒有效凭据 | 询价接口返回 | 商户不可见（系统内部透传） | R-17~R-20 |
| 锁汇有效秒数（validSeconds）/ 倒计时 | 锁汇令牌剩余有效秒数（初始 60 秒） | 询价接口返回 | 表单高亮动态倒计时展示 | R-17~R-19 |
| 参考汇率（fxRate） | 锁定结汇参考汇率 | 询价接口返回 | 只读展示 | R-17 |
| 结汇手续费承担方（feeBear） | 外扣（`OUTER`） | 系统固定外扣 | 内部固定 OUTER，表单无需商户选择 | R-16, R-20 |
| 结汇下单付款金额（`amount`） | 付款原币扣款金额，**必填且严格取自锁汇返回 `debitAmount`** | 锁汇询价接口返回 `debitAmount` | 表单展示试算外币金额，下单接口必填透传 | R-20 |
| 指定付款人 ID（appointPayerId） | 报备成功后的同名付款人 ID / 钱包申请 ID | 报备成功回写 | 商户不可见（同名结汇时透传） | R-21 |
| outbox 告警邮件 | 报备 1 次失败或停留超 120 分钟由 outbox 发送至单独配置邮箱 | 系统 outbox 服务 | 运营经配置邮箱可见；无页面 | §4.1 |

### 5.2 付款人报备状态枚举（商户级，唯一状态口径）

| 状态 | 中文标签 | 进入条件 | 退出条件 | 同名付款「是」提交 | 告警触发（outbox服务） |
|---|---|---|---|---|---|
| PENDING | 待报备 | KYC 认证通过 | 下一报备批次提交 | 报错（文案 A） | 累计停留超 120 分钟触发超时告警邮件 |
| PROCESSING | 报备中 | 批次已提交通道（入参 `subMerchantId`） | 查询回写成功/失败 | 报错（文案 A） | 累计停留超 120 分钟触发超时告警邮件 |
| SUCCESS | 报备成功 | 查询回写成功 | —（本期终态） | **正常提交** | — |
| FAILED | 报备失败 | 查询回写失败（含原因） | 运维手动 job 重新报备（**系统不做自动重试**） | 报错（文案 B） | **1 次失败立即触发告警邮件** |

> **注销（CLOSE）本期不做处理**：状态机不含注销态；查询返回 CLOSE 时忽略、不回写、不重报，商户保持原状态，页面与提交行为不变。上游 CLOSE 枚举与本地状态的映射仅保留 SUCCESS/PROCESSING/FAILED 三项。

---

## 6. 业务状态与服务支撑

### 6.1 业务状态流转

```
【付款人报备状态机】
（KYC 认证通过）→ 待报备 ─── 停留超 120 分钟 ───→ [outbox 服务发告警邮件至独立配置邮箱]
                     ↓
                   报备中 ─── 停留超 120 分钟 ───→ [outbox 服务发告警邮件至独立配置邮箱]
                     ├─成功→ 报备成功（终态，同名付款正常提交）
                     └─失败→ 报备失败（不做系统重试；1 次失败立即 [outbox 发告警邮件]；运维层 job 不处理记录处置）

【人民币结汇 60 秒锁汇状态机】
输入金额/切换条件 → 发起询价锁汇（feeBear=OUTER） → 锁汇成功（60s 倒计时中）
                                                     ├─ 60s 内点击提交 ──→ 下单 amount 严格取锁汇 debitAmount 上送下单成功
                                                     └─ 超过 60s 未提交 ─→ 锁汇失效（提交拦截，提示点击「刷新汇率」重新锁汇）
```

### 6.2 关联研发设计

- **上游接口与通知契约**：
  1. **设置付款人（主动请求）**：向通道设置同名付款人，请求参数仅 `subMerchantId`（子商户编号，string(32)，非必填），无额外明细字段；上游状态 PROCESSING/SUCCESS/FAILED/CLOSE 与 §5.2 枚举一一映射。
  2. **设置付款人信息结果通知（Webhook / Callback）**：
     - **说明**：下方为解密后的明文参数结构，解密过程和对接流程请参考：结果通知机制说明；
     - **通知类型**：`type` 固定为 `EXCHANGE_APPOINTPAYER_RESULT`；
     - **通知参数表**：

| 参数名 | 参数中文名 | 类型 | 必填 | 描述与枚举值说明 |
|---|---|---|---|---|
| `serialNum` | 流水号 | string(32) | 必填 | 通道方通知流水号 |
| `merchantId` | 商户编号 | string(32) | 必填 | 对应商户编号 |
| `status` | 开通状态 | string(32) | 必填 | 枚举值：<br>• `PROCESSING`: 处理中<br>• `SUCCESS`: 成功<br>• `FAILED`: 失败<br>• `CLOSE`: 注销 |
| `appointPayerName` | 付款人名称 | string(32) | 非必填 | 报备成功的付款人名称 |
| `appointPayerId` | 付款人id | string(32) | 非必填 | 报备成功的付款人唯一标识（结汇同名付款必传参数） |
| `errorMsg` | 设置失败的原因 | string(128) | 非必填 | 设置失败时的错误原因描述 |
| `requestId` | 请求流水号 | string(32) | 非必填 | 对应发起设置付款人请求时的流水号 |
| `type` | 通知类型 | string(128) | 非必填 | 设置付款人结果通知类型固定为：`EXCHANGE_APPOINTPAYER_RESULT` |

     - **通知接收与处理逻辑**：
       - 收到通知后按统一解密机制解密验签；
       - 根据 `merchantId` / `requestId` 匹配本地商户报备记录：
         - `status = SUCCESS`：本地回写状态为「报备成功」，持久化存储 `appointPayerId` 与 `appointPayerName`；
         - `status = FAILED`：本地回写状态为「报备失败」，持久化存储 `errorMsg`，并立即触发 outbox 服务发送失败告警邮件；
         - `status = CLOSE`：按本期规则忽略不回写，保持原状态；
         - `status = PROCESSING`：保持「报备中」。
       - 异步结果通知与主动定时查询任务（queryPayer）互为补充，任一通道先返回终态均可完成本地状态收敛。
  3. **人民币结汇-询价**：`POST https://openapi.gptransfer.hk/yop-center/rest/v1.0/gpt/stdexc/inquiry`，锁汇有效 60 秒，请求 `feeBear` 固定传 `OUTER`，返回 `inquiryToken`、`validSeconds`、`fxRate`、`feeAmount`、`debitAmount`、`paymentAmount` 等。
  4. **人民币结汇-请求**：`POST https://openapi.gptransfer.hk/yop-center/rest/v1.0/gpt/stdexc/commit-order`，**付款金额字段 `amount` 必填且必须严格取自锁汇返回的 `debitAmount`**；携带 `inquiryToken`、`tradeSide`、`paymentAmount`、`paymentCurrency="CNY"`、`feeBear="OUTER"`、`appointPayerId`（同名付款）发起结汇下单。
- **系统服务与任务设计**：
  - 批量报备、异步通知接收解析与定时查询补偿任务设计；
  - **邮件告警对接新 outbox 服务**，告警收件邮箱通过独立配置项维护；
  - **运维层手动 job**：仅限运维命令行工具，**不处理审计与数据库记录**；
  - 前端 60 秒倒计时组件与超时守卫拦截逻辑。

---

## 7. 异常/边界/权限

| 异常/边界场景 | 触发条件 | 用户看到什么 | 下一步 | 责任人 |
|---|---|---|---|---|
| 报备完成前付款/提现 | KYC 通过但报备未成功，人民币结汇场景选「是」提交 | 提交报错 + 原因文案；改选「否」（Local）可继续 | 等待报备完成，或先以非同名方式操作 | 系统自动 |
| 海外付款 + 报备未成功 | 海外付款（外币不结汇，SWIFT 或 Local）且报备未成功 | 不做报备校验，正常提交；SWIFT 下「否」仍按 R-03 禁用 | — | — |
| 报备 1 次失败 | 通道返回失败 | 「是」提交报错：「付款人报备未成功，请联系业务员处理」；outbox 立即发送告警邮件至单独配置邮箱 | 商户联系归属业务员线下介入；运营/运维跟进处置 | 商户联系业务员；运营/运维收告警处置 |
| 报备超 120 分钟未成功 | 停留 PENDING/PROCESSING 累计超 120 分钟 | 商户端提交同名付款仍提示处理中；outbox 发送 120 分钟超时告警邮件 | 运营排查通道延迟或运维执行手动 job 兜底（不处理记录） | 运营/运维收告警处置 |
| 查询返回注销（CLOSE） | 上游返回注销状态 | 无任何变化（忽略不回写，状态保持） | —（本期不处理；后续如需承接另行立项） | — |
| 锁汇倒计时超时（>60s） | 询价后超过 60 秒未提交 | 提交拦截提示「汇率已失效，请重新获取汇率」 | 点击「刷新汇率」重新锁汇并刷新倒计时 | 商户自助 |
| 下单金额与锁汇反算不一致 | 结汇下单试图篡改 `amount` 或未取锁汇 `debitAmount` | 后端校验拦截报错，阻止非法下单 | 重新刷新汇率并按系统锁汇结果提交 | 系统拦截 |
| 询价接口超时/异常 | 网络抖动或通道询价接口报错 | 提示「汇率获取失败，请稍后重试」 | 点击重试或重新输入金额 | 商户自助 |
| 会话期间状态变化 | 页面打开时报备成功，提交前状态变为未成功 | 提交报错并提示状态已变化 | 重新提交按最新状态校验 | 商户自助 |
| Local 账户承担方数据 | 选择 Local 账户提交 | 承担方选项隐藏；订单承担方记录 OUR | — | — |
| 权限-无手动入口 | 任何角色 | 三端页面无报备入口 | 异常仅经告警/既有渠道反馈 | — |
| 权限-跨商户 | 商户 A 试图影响商户 B 报备/锁汇 | 不存在入口；接口层仅允许本商户上下文 | — | — |

---

## 8. 验收标准

| # | 场景 | 前置条件 | 操作 | 预期 | 原型锚点 |
|---|---|---|---|---|---|
| AC-01 | KYC 通过自动纳入报备 | 商户 KYC 审核通过 | 不做任何操作，等待报备批次 | 自动提交通道（参数仅 `subMerchantId`），全程无手动动作、无商户消息 | —（系统链路） |
| AC-02 | 定时查询回写 | 商户报备中 | 等待定时查询 | 状态自动回写成功或失败（含原因） | —（系统链路） |
| AC-03 | 报备成功后同名可提交（付款） | 报备成功；付款选账户，选「是」 | 提交 | 同名付款正常提交，不报错；Local 下「否」亦可选 | 付款表单 |
| AC-04 | 未报备成功时提交报错 | 人民币结汇场景，报备状态为待报备/报备中/失败，选「是」提交 | 点击提交 | 提交报错并分别展示文案 A/B（失败提示请联系业务员处理）；改选「否」（Local）可正常提交 | 付款/提现表单 |
| AC-05 | 报备不做自动重试 | 报备失败 | 等待下一批次 | 系统不自动重新提交，状态保持 FAILED，不产生轮询重报重试 | —（系统链路） |
| AC-06 | 注销（CLOSE）不处理 | 商户报备成功 | 查询返回 CLOSE | 状态保持报备成功不变（忽略不回写不重报），同名付款提交行为不变 | —（系统链路） |
| AC-07 | 提现页同步同名付款 | 提现选提现卡 | 查看提现表单选项 | 提现页出现「是否同名付款」，报错文案/默认值/守卫与付款页一致 | 提现表单 |
| AC-08 | 提现页报备未成功 | 报备未成功 | 提现选「是」提交；再改选「否」提交 | 选「是」提交报错 + 原因文案；改选「否」（Local）正常提交 | 提现表单 |
| AC-09 | 状态变化提交守卫 | 页面打开时报备成功，提交前被注销 | 提交同名付款 | 后端按最新状态报错拦截；报备成功后可重新提交 | 付款/提现提交态 |
| AC-10 | SWIFT 不再支持非同名 | 付款/提现选择 SWIFT 账户 | 查看与提交 | 「否」不可选（禁用）；「是」不做报备校验（报备仅影响人民币结汇）可直接提交；绕过前端选「否」时提交被守卫拦截 | 付款/提现表单 |
| AC-10b | 海外付款 Local 不涉及报备 | 报备未成功，海外付款选 Local 账户 | 选「是」或「否」提交 | 均不做报备校验、正常提交，无报备报错（报备仅影响人民币结汇） | 付款表单 |
| AC-11 | 无选项场景固定 OUR | 分别验证：海外付款选 Local 账户、人民币结汇（到账 CNY）付款、提现全部场景 | 查看表单并提交，核对订单数据 | 三类场景「中间行费用承担方」均不展示；清分方式只读展示；提交/订单数据承担方记录为 OUR | 付款/提现表单 |
| AC-12 | 海外付款 SWIFT 承担方（无 BEN） | 海外付款选择 SWIFT 账户 | 查看表单选项集 | 「中间行费用承担方」展示且必选，选项仅包含 OUR（付款人承担）/ SHA（共同承担），无 BEN 选项；选择结果随订单提交 | 付款表单 |
| AC-13 | 无页面入口 | 商户/代理商/运营身份检索 | 检查三端页面 | 无任何报备设置/查询/重试/注销入口 | — |
| AC-14 | 运维手动 job 兜底（不处理记录） | 商户报备失败 | 运维执行手动 job | job 仅在运维层执行并立即发起一次报备（不处理记录），结果走定时查询回写 | —（运维链路） |
| AC-15 | 结汇定额卖 60 秒锁汇（统一外扣） | 人民币结汇选择定额卖，输入外币金额 | 查看表单试算与倒计时 | 正确试算并展示参考汇率、手续费（统一按外扣 OUTER 计算）及到账 CNY，启动 60 秒倒计时 | 付款/提现表单 |
| AC-16 | 结汇定额买 60 秒锁汇（统一外扣） | 人民币结汇选择定额买，输入 CNY 金额 | 查看表单试算与手续费 | 正确试算扣款外币金额（`debitAmount`），手续费统一外扣计算，启动 60 秒倒计时 | 付款/提现表单 |
| AC-17 | 60 秒锁汇超时与刷新 | 锁汇后停留超过 60 秒未提交 | 尝试提交；点击刷新 | 提交被拦截并提示「汇率已失效，请重新获取汇率」；点击刷新后重新获取汇率并重置 60 秒倒计时 | 付款/提现表单 |
| AC-18 | 结汇下单金额严格取锁汇结果 | 60 秒内提交人民币结汇订单 | 核对下单请求入参 | 付款金额 `amount` 必填且严格等于锁汇返回的 `debitAmount`；正确透传 `inquiryToken`、`tradeSide`、`paymentAmount`、`feeBear="OUTER"` 与 `paymentCurrency="CNY"` | 付款/提现提交态 |
| AC-19 | 结汇同名付款与锁汇联动 | 报备成功，结汇选「是（同名付款）」并在 60s 内提交 | 提交结汇订单 | 请求同时携带 inquiryToken 与 appointPayerId（付款人ID），成功完成 POBO 锁汇下单 | 付款/提现提交态 |
| AC-20 | outbox 告警邮件（1 次失败与 120 分钟超时） | ① 报备 1 次失败；<br>② 报备停留超 120 分钟未成功 | 检查 outbox 告警服务输出 | ① 报备失败立即由 outbox 发送邮件至单独配置邮箱（含商户号/原因）；<br>② 累计停留超 120 分钟发送超时告警邮件 | —（系统监控） |
| AC-21 | 设置付款人异步结果通知对接 | 通道推送 `type="EXCHANGE_APPOINTPAYER_RESULT"` 结果通知 | 系统接收通知并解密验签 | 正确解析明文参数并回写本地状态（SUCCESS 回写 appointPayerId 并置为报备成功；FAILED 回写 errorMsg 并触发告警；CLOSE 忽略不更新） | —（系统链路） |
