7.9 KiB
7.9 KiB
1. 数据、配置与双读基础
- 1.1 冻结现状契约与新旧分流边界:追踪
tb_wechat_config、订单/充值、tb_payment、支付加载器、微信/支付宝/富友回调、查单和现有退款处理的payment_config_id读写链路,形成文件/符号级实现清单。明确新单以merchant_id非空走商户加载,历史merchant_id为空继续走旧payment_config_id;明确三类新支付仅为 C 端套餐购买、C 端资产钱包充值、代理在线预存款充值,后台线下订单、后台钱包余额支付和员工线下代充值不经过商户池;列出敏感字段、富友 CommonQuery 接缝及退款 A(仅商户加载/能力判定)的边界。不得修改源码。 - 1.2 新增成对 Schema 迁移:创建商户、商户池、成员、微信授权配置、凭证版本、成功累计唯一事实及支付路由/统计世代快照所需表列;建立每种支付方式最多一个启用池、成员支付方式一致、历史引用保护、唯一累计事实和查询索引约束。不得修改既有迁移,不把迁移文件编号写死在任务或实现契约中。
- 1.3 实现商户、商户池与微信授权配置管理:交付模型、Query、Handler、可执行 RouteSpec 及管理审计;写操作仅限超级管理员和平台用户;实现启停、成员顺序、引用字段锁定、移除后二次确认删除、唯一启用池和全局唯一微信授权配置。C 端微信登录、OpenID、JSSDK 和支付 AppID 只读授权配置;普通 DTO、错误、日志、审计、快照、导出不得返回或保存敏感凭证。
- 1.4 先行实现商户双读与凭证版本化加载:在三类新支付接入前,使商户/微信授权凭证更新在事务提交时递增版本;支付创建、回调验签、查单和退款 A 先从主库取得当前版本,再按“配置 ID + 版本”读取缓存,旧版本提交后不得被新读取命中,缓存不可用时回源当前数据库记录。
merchant_id非空的新单走商户服务商凭证,空值历史单走payment_config_id;不得按当前启用池推断历史商户。 - 1.5 实现上线迁移与零 active A 规则:存在唯一当前生效综合支付配置时,仅复制完整凭证;按完整微信/支付宝凭证分别创建商户及单成员启用池,微信授权字段完整时创建全局授权配置;凭证不完整的方式不建池,授权字段不完整不建授权配置。零条 active 综合支付配置时仅创建新 Schema 和管理入口,绝不插入商户、商户池或微信授权业务行;新线上支付明确按“暂无可用商户”失败且不回退旧配置。多条 active 配置时迁移失败且不选择来源。敏感数据仅在数据库复制,迁移日志不得输出凭证,不批量回填既有支付单
merchant_id。
2. 商户池与支付链路
- 2.1 实现商户池选择器与统计世代规则:支持金额、笔数、时间轮询;金额/笔数支持每轮累计、自然日累计、自然月累计,时间周期最小 1 分钟并带单位和起始时间。支付创建事务内选择启用且未达阈值成员,冻结商户、池、轮询快照和
routing_epoch;修改阈值保留当前统计,修改统计周期、策略、时间周期、起始时间或每轮排序按规则开启新世代;自然周期仅排序调整时保留未移除成员累计;停用成员即时跳过但不改写既有支付。不得预下单预占。 - 2.2 接入支付成功首次生效统计:以支付 ID 唯一事实按支付创建时冻结的商户和
routing_epoch累计金额/笔数;迟到首次成功仍写入冻结世代,不改写当前选路世代;失败、关闭、预下单和退款不计入;重复回调、重复事件和重复执行不得重复累计。 - 2.3 接入三类新支付创建并保持代理边界:在双读/版本加载和选择器完成后,将商户池选择接入 C 端套餐购买、C 端资产钱包充值、代理在线预存款充值。每笔支付在同一业务事务内冻结 merchant/pool/支付方式/服务商/非敏感身份/轮询及统计世代快照,再使用所选商户凭证创建支付。三类后续新支付始终只走商户池;无池、无可用成员或池停用时明确失败,预下单失败不得回退旧综合配置、不得自动换商户重试。后续 Apply 必须删除商户池新支付创建开关、所有引用及任何旧综合配置创建回退。仅代理在线预存款充值走池;员工线下代充值、后台线下订单、后台钱包余额支付及其它代理后台钱包操作不得经过商户池。
- 2.4 改造回调、查单及退款 A 的商户加载:微信、支付宝、富友回调和代理在线查单对
merchant_id非空新单使用商户当前凭证,对空值历史单继续按payment_config_id双读;停用商户不得阻断已冻结历史单的本地回调/查询/退款 A 路径。退款 A 仅实现依据冻结商户加载当前凭证并作退款能力/必需凭证完整性判断、接入既有退款流程;不得新增或验收微信/支付宝/富友实际渠道退款 API、退款请求、渠道退款回调或外部退款成功;保留客户凭证退款、代理钱包回退及既有幂等语义。不得按当前池推断历史商户。
3. 文档、渠道核验与发布控制
- 3.1 更新支付、商户、商户池和微信授权管理接口 OpenAPI、可执行路由说明及生成入口,覆盖权限、启停、成员排序、引用锁定、二次确认删除、零 active 失败提示、三类新支付和后台排除边界。敏感凭证的脱敏/禁止泄露仅适用于普通 DTO、错误、日志、审计、支付快照、导出及非专用管理响应;超级管理员和平台用户的专用管理列表、详情响应继续允许返回完整凭证。文档与 OpenAPI 示例只能使用占位值,绝不写入真实凭据。不得把具体迁移编号或 candidate 目录写入契约,不新增测试体系;不得暗示本 Change 实现渠道退款 API。
- 3.2 富友 B:保持现有
CommonQuery请求格式、签名算法、验签、状态映射和恢复语义;仅改本地双读配置来源与商户加载,使双读查单可按商户当前凭证调用。不得改变协议、验签、状态解释、恢复规则或业务能力,不得增加退款能力;未第三方实测可记录但不得作为任务或归档阻塞。 - 3.3 在本地工作区以明确
DB_*指向维护者提供的junhong_cmp_testPostgreSQL 与 Redis DB6,完成 migration up/down/up 和数据行为验证:零/一/多 active、支付/授权凭证缺失、三类新支付始终走商户池、后台 wallet/offline 排除、缺失配置、三种轮询、统计世代与迟到成功、凭证轮换及缓存一致性、并发成功累计、商户停用后的历史回调/查单/退款 A、merchant ID 为空旧单兼容、敏感字段不泄露和重复处理幂等。允许仅为当前 Change 创建/删除 fixtures,禁止重置整个库;仅连接、迁移或实际行为失败时阻塞对应场景。完成后才提交推送 Iteration/8-11;每个场景提供可观察状态/错误/快照/统计事实证据;不新增测试体系,不验收实际渠道退款成功。 - 3.4 Iteration/8-11 分支 Gitea 以本次提交 SHA 仅构建/部署
cmp-test测试镜像并检查 migration version,不自动执行 migration up/down 或重置整库;记录 API/Worker 容器状态、健康检查和/opt/junhong_cmp/logs的有限日志,不建运行时开关且不是生产发布。部署后验证三类后续新支付立即走商户池并冻结路由,无池、成员或停用池明确失败且无旧创建回退,merchant ID 为空历史支付仍读旧路径。故障仅在双读版本上前向修复;存在非空merchant_id支付、成功事实或新配置时,禁止部署不识别新路由的旧二进制和破坏性 down。后续 Apply 必须删除商户池新支付创建开关、所有引用及任何关闭后恢复旧创建的代码。