Files
jsowell-charger-web/docs/汇付开户V2流程计划.md
2026-05-29 13:33:16 +08:00

535 lines
24 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 汇付开户 V2 流程与落地计划
## 背景
现有开户页已经从旧组件切到了 `jsowell-charge-ui/src/views/financial/accountUserInfo.vue`,但整体仍偏向“资料展示 + 操作按钮”。新版开户流程需要按汇付官方账户体系重新梳理为状态驱动的流程,明确个人用户、企业用户、结算账户三个对象之间的关系。
官方文档来源:
- 个人用户:<https://docs.adapay.tech/api/trade.html#member-create>
- 企业用户:<https://docs.adapay.tech/api/trade.html#corpmember>
- 结算账户:<https://docs.adapay.tech/api/trade.html#settle-account-create>
## 官方约束摘要
### 个人用户 Member
- 创建用户对象用于将商户侧 `member_id` 与 Adapay 系统关联,`member_id` 需在同一个 `app_id` 下唯一。
- 创建成功后可创建结算账户,用于用户分账。
- 若创建用户对象用于分账功能,官方文档说明 `tel_no``user_name``cert_type``cert_id` 不应上送。
- 当前项目个人开户只上送 `location``email``gender``nickname`,符合分账场景的轻量开户模型。
### 企业用户 CorpMember
- 创建企业用户对象本质是提交企业开户申请,同步返回 `pending` 表示申请已受理。
- 企业开户结果由异步通知返回。审核成功后企业用户创建成功;审核失败后可根据失败原因重新提交。
- 企业开户若同时上送 `bank_code``bank_acct_type``card_no``card_name`,审核成功后汇付会自动创建结算账户。
- 若企业开户未上送银行要素,不会自动创建结算账户,需要后续单独调用结算账户创建接口。
- 企业更新同样同步返回 `pending`,审核结果通过异步通知返回。
- 企业更新不支持修改银行代码、银行账户类型、银行卡号、银行卡开户姓名。结算账户信息变更应先删除结算账户,再使用原 `member_id` 重新创建。
### 结算账户 SettleAccount
- 结算账户用于承接用户分账金额结算,目前仅支持银行卡。
- 创建对私结算账户时会校验银行卡号、银行卡开户姓名、身份证号三要素。
- 结算账户由汇付生成唯一 `id`,用于查询和删除。
- 银行账户类型为 `2-对私` 时,建议绑定 I 类银行卡,否则单次结算超过 10000 元可能失败。
- 22:30 后创建成功的结算账户,结算会延后一个结算日。
- 更新银行卡必须删除原结算账户后重新创建,且需与原结算账户使用的身份证和银行卡户名保持一致。
## V2 产品流程
### 页面入口
入口保持不变:
- 路由:`/financial/merchant/index/:merchantId`
- 页面:`jsowell-charge-ui/src/views/financial/accountUserInfo.vue`
页面进入后只关心一个业务状态:当前运营商的汇付开户进度。
### 状态机
| V2 状态 | 来源判断 | 页面主状态 | 允许操作 |
| --- | --- | --- | --- |
| `NONE` | 无有效 `adapay_member_account` | 未开户 | 创建个人用户、创建企业用户 |
| `PERSONAL_OPENED_NO_SETTLE` | 个人用户已创建,未查询到结算账户 | 个人已开户,待创建结算账户 | 更新个人资料、创建对私结算账户 |
| `PERSONAL_COMPLETED` | 个人用户已创建,且存在结算账户 | 个人开户完成 | 更新个人资料、查看/删除结算账户 |
| `CORP_AUDITING` | 企业用户提交后,汇付 `audit_state=A` 或本地状态待审核 | 企业审核中 | 刷新、查看资料 |
| `CORP_FAILED` | 汇付 `audit_state=B/C` 或本地状态失败 | 企业开户失败 | 查看失败原因、重新提交企业开户 |
| `CORP_OPENED_NO_SETTLE` | 企业 `audit_state=D`,或企业审核通过但无结算账户 | 企业已开户,待创建结算账户 | 更新企业资料、创建对公结算账户 |
| `CORP_COMPLETED` | 企业 `audit_state=E` 或存在结算账户 | 企业开户完成 | 更新企业资料、查看/删除结算账户 |
企业审核状态沿用项目已有枚举:
| 汇付 `audit_state` | 含义 | V2 归类 |
| --- | --- | --- |
| `A` | 待审核 | `CORP_AUDITING` |
| `B` | 审核失败 | `CORP_FAILED` |
| `C` | 开户失败 | `CORP_FAILED` |
| `D` | 开户成功但未创建结算账户 | `CORP_OPENED_NO_SETTLE` |
| `E` | 开户和创建结算账户成功 | `CORP_COMPLETED` |
### 用户可见流程
```mermaid
flowchart TD
A["进入开户页"] --> B["查询开户聚合详情"]
B --> C{"是否已开户"}
C -->|否| D["选择个人/企业开户"]
D -->|个人| E["提交个人资料"]
E --> F["个人开户成功"]
F --> G["创建对私结算账户"]
G --> H["开户完成"]
D -->|企业| I["提交企业资料和附件"]
I --> J["企业审核中"]
J --> K{"审核结果"}
K -->|失败| L["展示失败原因并重新提交"]
L --> J
K -->|成功| M["创建对公结算账户"]
M --> H
C -->|是| N["按状态展示下一步动作"]
```
## 字段映射
### 个人用户创建
当前接口:
- 前端:`createAdapayMember`
- 后端:`POST /adapay/member/createAdapayMember`
- DTO`CreatePersonalMemberDTO`
- 汇付 SDK`Member.create`
| 页面字段 | 后端 DTO | 汇付字段 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| 运营商 ID | `merchantId` | 不直接传汇付 | Y | 后端根据运营商查询 `wechatAppId``app_id` |
| 昵称 | `nickname` | `nickname` | N | 当前页面设为必填,便于运营识别 |
| 性别 | `gender` | `gender` | N | 取值 `MALE` / `FEMALE` |
| 邮箱 | `email` | `email` | N | 当前页面校验邮箱格式 |
| 地址 | `location` | `location` | N | 当前页面设为必填 |
| 汇付会员 ID | 后端生成 | `member_id` | Y | 当前使用 `Constants.ADAPAY_MEMBER_PREFIX + IdUtils.getMemberId()` |
| 应用 ID | 后端配置 | `app_id` | Y | 从 `AdapayConfigFactory` 获取 |
V2 处理原则:
- 保持轻量个人开户,不新增实名字段。
- 个人用户创建成功后,本地 `adapay_member_account.status` 记为成功。
- 页面下一步引导创建对私结算账户。
### 企业用户创建
当前接口:
- 前端:`createCorpMember`
- 后端:`POST /adapay/member/createCorpMember`
- DTO`CreateCorpMemberDTO`
- 汇付 SDK`CorpMember.create`
| 页面字段 | 后端 DTO | 汇付字段 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| 运营商 ID | `merchantId` | 不直接传汇付 | Y | 后端根据运营商查询配置 |
| 企业名称 | `name` | `name` | Y | 长度不超过 50 |
| 省份编码 | `provCode` | `prov_code` | Y | 四位省市编码 |
| 地区编码 | `areaCode` | `area_code` | Y | 四位省市编码 |
| 统一社会信用码 | `socialCreditCode` | `social_credit_code` | Y | 长度 18 |
| 统一社会信用证有效期 | `socialCreditCodeExpires` | `social_credit_code_expires` | Y | `YYYYMMDD` |
| 经营范围 | `businessScope` | `business_scope` | Y | 长度不超过 200 |
| 法人姓名 | `legalPerson` | `legal_person` | Y | 长度不超过 20 |
| 法人身份证号 | `legalCertId` | `legal_cert_id` | Y | 长度不超过 20 |
| 法人身份证有效期 | `legalCertIdExpires` | `legal_cert_id_expires` | Y | `YYYYMMDD` |
| 法人手机号 | `legalMp` | `legal_mp` | Y | 11 位手机号 |
| 企业地址 | `address` | `address` | Y | 长度不超过 256 |
| 邮编 | `zipCode` | `zip_code` | N | 长度 6 |
| 企业电话 | `telphone` | `telphone` | N | 长度不超过 30 |
| 企业邮箱 | `email` | `email` | N | 长度不超过 40 |
| 附件列表 | `imgList` | `attach_file` | Y | 后端压缩为 zip 上传,最大 9 MB |
| 汇付会员 ID | 后端生成 | `member_id` | Y | 当前使用 `Constants.ADAPAY_CORP_MEMBER_PREFIX + IdUtils.getMemberId()` |
| 请求订单号 | 后端生成 | `order_no` | Y | 需保证同 `app_id` 下唯一 |
| 异步通知地址 | 后端配置 | `notify_url` | N | 当前使用 `ADAPAY_CALLBACK_URL` |
企业附件要求:
| 附件 | 当前页面 upload key | 汇付要求 |
| --- | --- | --- |
| 法人身份证正面 | `idCardFace` | 法人身份证正面照 |
| 法人身份证反面 | `idCardBack` | 法人身份证反面照 |
| 开户许可证 | `bankLicense` | 开户银行许可证照 |
| 营业执照 | `businessLicense` | 三证合一证件照 |
V2 处理原则:
- 企业开户阶段不随开户上送银行字段,避免审核成功后自动创建结算账户,统一改为审核通过后手动创建结算账户。
- 提交成功后页面展示“审核中”,不提示开户完成。
- 异步回调成功后再进入“待创建结算账户”或“已完成”状态。
### 结算账户创建
当前接口:
- 前端:`createSettleAccount`
- 后端:`POST /adapay/member/createSettleAccount`
- DTO`CreateSettleAccountDTO`
- 汇付 SDK`SettleAccount.create`
| 页面字段 | 后端 DTO | 汇付字段 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| 运营商 ID | `merchantId` | 不直接传汇付 | Y | 后端查询当前汇付会员 |
| 账户类型 | `bankAcctType` | `account_info.bank_acct_type` | Y | `1-对公``2-对私` |
| 银行卡号 | `cardId` | `account_info.card_id` | Y | 当前后端同时保留 `cardNo`V2 统一使用 `cardId` |
| 户名 | `cardName` | `account_info.card_name` | Y | 对公时必须与企业名称一致 |
| 身份证号 | `certId` | `account_info.cert_id` | 对私必填 | 对私三要素认证使用 |
| 证件类型 | `certType` | `account_info.cert_type` | N | 默认 `00-身份证` |
| 手机号 | `telNo` | `account_info.tel_no` | Y | 银行预留手机号 |
| 银行编码 | `bankCode` | `account_info.bank_code` | Y | 取银行编码列表 |
| 省份编码 | `provCode` | `account_info.prov_code` | Y | 开户银行省份 |
| 地区编码 | `areaCode` | `account_info.area_code` | Y | 开户银行地区 |
| 渠道 | 后端固定 | `channel` | Y | 固定 `bank_account` |
| 汇付会员 ID | 后端查询 | `member_id` | Y | 当前运营商绑定的汇付会员 |
| 应用 ID | 后端配置 | `app_id` | Y | 从汇付配置获取 |
V2 处理原则:
- 个人用户默认创建 `2-对私` 结算账户。
- 企业用户默认创建 `1-对公` 结算账户。
- 按官方 account_info 字段说明V2 前端应收集 `bankCode``provCode``areaCode`,包括对私账户也建议保留,减少生产环境参数不完整风险。
- 创建前后端都校验“当前会员不能已有结算账户”。
### 企业用户更新
当前接口:
- 前端:`updateAdapayMember`
- 后端:`POST /adapay/member/updateAdapayMember`
- DTO`UpdateCorpMemberDTO`
- 汇付功能号:`corp_members.update`
| 页面字段 | 汇付字段 | 必填 | V2 说明 |
| --- | --- | --- | --- |
| 企业基础信息 | `name``prov_code``area_code``business_scope` 等 | N | 仅用于企业资料变更 |
| 法人信息 | `legal_person``legal_cert_id``legal_cert_id_expires``legal_mp` | N | 更新后进入审核流程 |
| 附件 | `attach_file` | N | 当前实现要求重新上传四张附件V2 可继续要求,降低资料不一致风险 |
| 通知地址 | `notify_url` | N | 建议补齐,确保更新审核结果也能回调 |
V2 处理原则:
- 企业资料更新不处理银行卡信息。
- 若要换银行卡,走“删除结算账户 -> 重新创建结算账户”流程。
- 企业更新提交成功后页面进入 `CORP_AUDITING`,等待回调或主动刷新。
### 个人用户更新
当前接口:
- 前端:`updateAdapayMember`
- 后端根据 `adapayMemberId` 前缀判断后调用 `Member.update`
| 页面字段 | 汇付字段 | V2 说明 |
| --- | --- | --- |
| 昵称 | `nickname` | 保留 |
| 性别 | `gender` | 保留 |
| 邮箱 | `email` | 保留 |
| 地址 | `location` | 保留 |
V2 处理原则:
- 个人更新不改变开户状态。
- 若未来引入禁用用户,需单独设计 `disabled` 操作,不混入普通资料更新。
## 后端落地计划
### 1. 新增 V2 聚合响应模型
建议新增:
- `AdapayMemberOpenV2VO`
- `AdapayOpenStatusEnum`
- `AdapayOpenActionEnum`
响应结构建议:
```json
{
"merchantId": "1",
"status": "CORP_OPENED_NO_SETTLE",
"memberType": "CORP",
"adapayMemberId": "ACM29102732",
"auditState": "D",
"auditDesc": "",
"settleAccountStatus": "NONE",
"primaryAction": "CREATE_SETTLE_ACCOUNT",
"actions": [
"REFRESH",
"UPDATE_CORP_MEMBER",
"CREATE_SETTLE_ACCOUNT"
],
"member": {},
"settleAccount": null,
"tips": []
}
```
### 2. 新增 V2 查询接口
建议新增接口,不破坏现有页面调用:
- `POST /adapay/member/v2/detail`
职责:
- 查询 `adapay_member_account` 当前有效记录。
- 判断个人/企业用户类型。
- 查询汇付会员详情。
- 查询结算账户详情。
- 汇总 V2 状态、主操作、可用动作、提示信息。
### 3. 状态计算集中到后端
当前前端通过 `memberType``auditState``settleAccountList` 自行判断V2 改为后端统一计算。
建议规则:
- 无本地记录:`NONE`
- 个人 + 无结算账户:`PERSONAL_OPENED_NO_SETTLE`
- 个人 + 有结算账户:`PERSONAL_COMPLETED`
- 企业 + `audit_state=A``CORP_AUDITING`
- 企业 + `audit_state=B/C` 或本地 `status=2``CORP_FAILED`
- 企业 + `audit_state=D` 或审核通过但无结算账户:`CORP_OPENED_NO_SETTLE`
- 企业 + `audit_state=E` 或有结算账户:`CORP_COMPLETED`
### 4. 本地表状态增强
当前 `adapay_member_account.status` 只有:
- `0` 待审核
- `1` 审核通过
- `2` 创建失败
V2 建议新增字段,避免只靠 `remark` 存失败信息:
```sql
alter table adapay_member_account
add column audit_state varchar(8) null comment '汇付企业审核状态 A/B/C/D/E',
add column audit_desc varchar(512) null comment '汇付企业审核说明',
add column last_order_no varchar(64) null comment '最近一次企业开户/更新请求订单号';
```
兼容策略:
- 不强制迁移历史数据。
- 查询时优先使用汇付实时查询结果。
- 若汇付查询失败,再使用本地 `status``remark` 兜底。
### 5. 企业回调更新
现有回调处理在 `OrderService.corpMemberFailed``OrderService.corpMemberSucceeded`
V2 调整:
- 成功回调:写入 `audit_state``audit_desc``status=1`
- 失败回调:写入 `audit_state``audit_desc``status=2`
- 若回调中包含结算账户 ID同步写入 `settle_account_id`
- 清理 `ADAPAY_MEMBER_ACCOUNT + merchantId` 缓存。
### 6. 创建/更新动作校验
后端服务层统一校验:
- `CREATE_PERSONAL_MEMBER`:仅 `NONE` 可执行。
- `CREATE_CORP_MEMBER`:仅 `NONE``CORP_FAILED` 可执行。
- `UPDATE_PERSONAL_MEMBER`:仅个人已开户状态可执行。
- `UPDATE_CORP_MEMBER`:仅企业非审核中状态可执行。
- `CREATE_SETTLE_ACCOUNT`:仅已开户且无结算账户可执行;企业必须非审核中、非失败。
- `DELETE_SETTLE_ACCOUNT`:仅已有结算账户可执行,且需确认不会影响未结算分账。
## 前端落地计划
### 1. API 封装
`jsowell-charge-ui/src/api/adapayMember/adapayMember.js` 增加:
```js
export function getAdapayOpenDetailV2(data) {
return request({
url: '/adapay/member/v2/detail',
method: 'post',
data
})
}
```
### 2. 页面结构
`accountUserInfo.vue` 调整为:
1. 顶部状态总览:显示当前 V2 状态、汇付会员 ID、审核状态、结算账户状态。
2. 流程步骤条:未开户、提交资料、审核、结算账户、完成。
3. 主操作区:只渲染后端返回的 `primaryAction``actions`
4. 会员资料区:个人/企业按字段分组展示。
5. 结算账户区:独立展示,包含删除后重建提示。
6. 失败原因区:企业失败时展示 `auditDesc`,并给出重新提交入口。
### 3. 表单调整
个人开户表单:
- 昵称
- 性别
- 邮箱
- 地址
企业开户表单:
- 企业主体
- 法人信息
- 联系信息
- 附件上传
结算账户表单:
- 账户类型
- 银行卡号
- 户名
- 身份证号
- 手机号
- 银行编码
- 省份/地区
### 4. 交互规则
- 状态由后端响应驱动,前端不再手写复杂判断。
- 企业审核中:禁用更新、结算账户创建、重复提交。
- 企业失败:主按钮为“重新提交企业开户”。
- 企业成功但无结算账户:主按钮为“创建对公结算账户”。
- 个人无结算账户:主按钮为“创建对私结算账户”。
- 结算账户删除前提示:删除后支付分账将不可用,需重新创建后恢复。
## Review 待修复计划
### 问题一:结算账户创建成功后缓存未失效
风险:
- `createSettleAccount` 成功写入 `settle_account_id` 后,当前使用 `updateAdapayMemberAccountByMemberId` 更新本地记录。
- `updateAdapayMemberAccountByMemberId` 只更新数据库,没有清理 `ADAPAY_MEMBER_ACCOUNT + merchantId` 缓存。
- `/adapay/member/v2/detail` 继续读取旧缓存时,页面可能仍显示“未创建结算账户”,导致状态停留在 `PERSONAL_OPENED_NO_SETTLE``CORP_OPENED_NO_SETTLE`
修改计划:
-`AdapayMemberAccountServiceImpl.updateAdapayMemberAccountByMemberId` 中补齐缓存清理。
- 优先使用传入对象的 `merchantId` 清理缓存。
- 若调用方只传 `adapayMemberId`,则先按 `adapayMemberId` 查询当前记录,拿到 `merchantId` 后清理缓存。
- 调整 `AdapayService.createSettleAccount``changeBankCard` 等调用点,尽量在更新对象中补充 `merchantId`,减少额外查询。
验收标准:
- 创建结算账户成功后,立即刷新 V2 页面,状态应变为 `PERSONAL_COMPLETED``CORP_COMPLETED`
- 结算账户 ID、银行卡信息能立即展示不依赖 Redis 过期。
### 问题二:删除结算账户缺少业务阻断校验
风险:
- 文档已确认删除结算账户前需要校验未结算分账/在途提现。
- 当前 `deleteSettleAccount` 只校验 V2 action 和结算账户是否存在,随后直接调用汇付删除并清空本地结算账户。
- 若存在未结算分账或在途提现,删除结算账户会影响后续结算、提现或分账状态追踪。
修改计划:
-`AdapayService.deleteSettleAccount` 调用汇付删除前增加业务校验方法,例如 `assertSettleAccountCanDelete(merchantId)`
- 校验维度先按现有数据能力落地,明确数据源和阻断状态:
- 在途提现:查询 `clearing_withdraw_info`,若存在 `withdraw_status = '0'` 的记录,阻断删除。
- 清分账单:查询 `clearing_bill_info`,若存在 `bill_status in ('0', '1', '3', '5')` 的记录,阻断删除,分别对应未清分、清分在途、提现申请中、等待处理。
- 未分账订单:查询 `order_unsplit_record`,若存在 `status = 'unsplit'` 且订单归属当前 `merchantId` 的记录,阻断删除。
- 为未分账订单补齐按商户查询能力:
-`OrderUnsplitRecordMapper` 新增 `countUnsplitByMerchantId(merchantId)`
- SQL 通过 `order_unsplit_record.order_code` 关联 `order_basic_info.order_code`,按 `order_basic_info.merchant_id` 过滤当前商户。
-`OrderUnsplitRecordService` 增加同名方法,供 `AdapayService.assertSettleAccountCanDelete` 调用。
- 为提现和清分账单尽量使用轻量查询:
- 优先新增 `ClearingWithdrawInfoService.countProcessingByMerchantId(merchantId)`,只统计 `withdraw_status = '0'`
- 优先新增 `ClearingBillInfoService.countBlockingByMerchantId(merchantId)`,只统计 `bill_status in ('0', '1', '3', '5')`
- 若已有列表查询能满足,可先复用现有方法,但最终实现应避免在删除前加载大量历史记录。
- 阻断时返回明确错误信息,例如“存在在途提现,请完成后再删除结算账户”或“存在未结算分账,请完成结算后再删除结算账户”。
- 前端保留现有确认弹窗,但以后端校验结果作为最终准入。
验收标准:
- 无在途提现、无未结算分账时,可以删除结算账户并清空本地 `settle_account_id`
- 存在 `withdraw_status = '0'` 的提现记录时,删除接口返回业务错误,汇付删除请求不会发起,本地结算账户不会清空。
- 存在 `bill_status in ('0', '1', '3', '5')` 的清分账单时,删除接口返回业务错误,汇付删除请求不会发起,本地结算账户不会清空。
- 存在 `status = 'unsplit'` 且归属当前商户的未分账订单时,删除接口返回业务错误,汇付删除请求不会发起,本地结算账户不会清空。
### 问题三:删除汇付用户未接入 V2 action 后端校验
风险:
- V2 计划要求后端统一动作校验,避免绕过前端按钮限制。
- 当前创建、更新、创建/删除结算账户已接入 `assertActionAllowed`
- `deleteAdapayMember` 未校验 `DELETE_MEMBER`,直接调用接口时可能删除企业审核中的本地记录,导致后续汇付回调无法匹配记录。
修改计划:
-`AdapayService.deleteAdapayMember` 开始处增加 `assertActionAllowed(dto.getMerchantId(), AdapayOpenActionEnum.DELETE_MEMBER)`
- 保留现有 `adapayMemberId` 一致性校验和“需先删除结算账户”校验,作为二次保护。
- 确认 `resolveActions` 中仅允许以下状态删除会员:
- `PERSONAL_OPENED_NO_SETTLE`
- `CORP_FAILED`
- 若后续业务允许更多状态删除,再由状态机统一扩展,不在接口中散落判断。
验收标准:
- 企业审核中状态调用删除汇付用户接口,应返回“不允许执行删除”类业务错误。
- 企业失败且无结算账户时,可以删除本地失败记录。
- 个人已开户但未创建结算账户时,可以删除本地会员记录。
- 已有结算账户时仍必须先删除结算账户。
## 分阶段实施清单
### 阶段一:后端状态与接口
- [ ] 新增 `AdapayOpenStatusEnum``AdapayOpenActionEnum`
- [ ] 新增 V2 聚合 VO。
- [ ] 新增 `/adapay/member/v2/detail` 接口。
- [ ]`AdapayService` 中增加状态计算方法。
- [ ] 后端统一动作校验,避免前端绕过状态限制。
### 阶段二:企业审核状态持久化
- [ ] 新增数据库字段 `audit_state``audit_desc``last_order_no`
- [ ] 更新 `AdapayMemberAccount` domain、mapper、XML。
- [ ] 调整企业创建、企业更新逻辑,记录 `last_order_no`
- [ ] 调整回调处理,写入审核状态和说明。
- [ ] 清理相关 Redis 缓存。
### 阶段三:前端 V2 页面
- [ ] 新增 V2 聚合查询 API。
- [ ] 改造 `accountUserInfo.vue` 数据源为 V2 detail。
- [ ] 增加状态步骤条和主操作区。
- [ ]`actions` 渲染按钮。
- [ ] 调整结算账户表单,补齐银行编码、省份、地区采集。
- [ ] 企业失败态展示审核说明并支持重新提交。
### 阶段四:回归与联调
- [ ] 无开户记录 -> 创建个人用户 -> 创建对私结算账户。
- [ ] 无开户记录 -> 创建企业用户 -> 审核中展示。
- [ ] 企业审核失败 -> 展示失败原因 -> 重新提交。
- [ ] 企业审核成功但无结算账户 -> 创建对公结算账户。
- [ ] 已有结算账户 -> 禁止重复创建。
- [ ] 删除结算账户 -> 重新创建结算账户。
- [ ] 个人资料更新后刷新展示一致。
- [ ] 企业资料更新后进入审核中,回调后状态正确。
## 需要确认的问题
1. 企业开户 V2 是否确定不使用汇付“开户时自动创建结算账户”的能力?本计划建议不使用,统一手动创建,流程更清晰。
回答:确定不使用。
2. 企业资料更新后是否必须重新上传四张附件?官方为非必填,但当前系统要求重传;本计划建议继续重传。
回答:确定继续重传。
3. 个人结算账户是否也强制填写银行编码、省份、地区?官方 account_info 字段说明为非空字段,本计划建议 V2 补齐采集。
回答:确定补齐采集。
4. 删除结算账户前是否需要校验未结算分账/在途提现?本计划建议后续补一层业务校验。
回答:需要校验 。