适用提交: 6c42f8f | 最后验证: 2026-09-18 | 何时会失效: 各条证据指向的代码被重构、或通道返回码语义变化时
汇付侧的协议与反直觉行为在05-汇付对接注意事项.md,本文件只收**我方**的坑。
怎么读:不必通读。按你正要改的链路跳到对应小节即可;每条都是「现象 + 根因」自包含的,commit/文件引用是**补充不是论据**。置信档写法同 05:【实测】有真实回执或库内数据,【推断】只有代码逻辑可推。
更细的版本(每条带完整证据引用与我当初的疑问)在 .scratch/huifu-handover/pitfall-checklist.md。
| # | 现象 | 根因 |
|---|---|---|
| 37 | 用户没付过钱但订单被取消,钱却在通道被收下,人才端显示「已取消」、连退款入口都没有 | 旧实现在本地取消/超时只把流水置成「本地已关闭」(LOCAL_CLOSED,**该状态现已不存在**)、订单置取消,**从不调通道关单**;用户手上那张预支付单照样能付进来 |
| 48 | 「关不掉的预支付单」所在订单被自动取消,而那张单子**仍然可付** → 钱落在已取消订单上 | expireDueOrders/expireOrder 的排除表漏了 CANCEL_UNCONFIRMED;钱进来后记 PAYMENT_ORDER_CANCELLED,而正常退款接口要求 order_status=1,这笔钱**没有程序化出口** |
| 50 | 0.01 元的成功回调可以把 100 元订单改成已支付 | 回调只查流水 ID、订单 ID、状态,**不取金额比对**(修复后回调与主动查询共用 PaymentSettlementService 校验金额/商户号/订单归属) |
| 52 | 一笔订单存在两张都能被支付的预支付单;两笔都成功时**没有多收款退回流程** | 防重只按 idempotency_key 查已有流水,不按订单阻止**另一个键**创建有效流水(一次订单、两个键 → 两次预授权) |
| 56 | 实付 100 退了 40 之后,剩下的 60 永远退不了 | 旧规则「存在退款中或已退款就阻止新退款」;正确规则是按「已成功金额 + 处理中金额 < 实付」控制,在途金额也要算进去 |
| 57 | 退款查单确认时把唯一的通道凭证擦成空串 | 通道退款流水号**只在发起退款的那次回执里**有,退款查询回执不带它;旧代码无条件覆盖 |
| 60 | 撤销核销只翻库、不碰钱:订单回到「待核销」,钱却留在商户手里,等 D1 结算到银行卡后**再也追不回来** | 核销时钱已从延迟户划给商户,撤销核销必须调通道的【交易确认退款】把钱退回延迟户 |
| 63 | 确认被认领后进程中断(部署/崩溃)留下 confirming 孤儿,那笔钱**永远冻在延迟户** |
资金确认补偿任务只挑得到它、从不重发(修复后隔天收掉孤儿重发一次,重发是幂等的) |
| 64 | 扫码核销与后台核销都只把订单置为已核销,资金冻在通道延迟户,商户**永远收不到钱** | 核销有三条入口,此前只有「订单管理里点确认」那条调用了交易确认 |
| 66 | 未核销的钱直接落进商户账户,退款时收不回来 | delay_acct_flag 是否延迟由订单类型决定;写反或漏配就会把钱直接分给商户(口径:只有 STORE_CONSUME 不延迟,其它订单含**以后新增的类型**一律延迟) |
| 74 | (生产 bug)绑卡(业务开通)回调地址从未在通道侧注册,即使有公网也收不到 | merchant-business-notify-url 当时在 yml 里没有这个键,靠 notify-url 推导——「通道侧到底注册了哪个地址」取决于另一个配置 |
| 75 | 回调丢了以后**没有任何人推进状态**(订单 520/521 的悬账根因) | 只靠回调推进的状态,在本地/无公网部署里根本收不到 |
| 77 | 2026-09-15 后台**全站不可用**(所有页面加载到超时,健康检查都超时) | 进件回调先 select ... for update 锁住记录,然后在事务里同步调汇付 HTTP:拿着行锁 + 一条数据库连接等不受控的网络响应,连接池(10 条)很快借光 |
| 78 | 2026-09-15 上午后台**再次**全站不可用 | 启动时补列的 ALTER 永久等锁(一个空闲未提交事务持着 SHARED_READ 元数据锁 280 秒),该表所有查询排队,连接池借光 |
| 96 | 单测各自正常,合起来异常(「一次提现之后支付用错产品号」) | SDK 的 initWithMerConfig 写静态 configMap["default"],未指定配置名的请求读该默认配置;各网关用自己的锁,彼此不能隔离 |
| # | 现象 | 根因 | 档 |
|---|---|---|---|
| 1 | 通道侧配置失败的商户,进件页永远停在「审核中」,表单进不去、同一张卡也用不了 | 进件页见 pending 就跳待审页;submitOnboarding 见 active 进件直接返回旧记录;银行卡校验又拦「该银行卡已有审核中的进件」 |
【实测】 |
| 2 | 进件放行了,但商户用同一张卡重提仍被拒 | 收口只把进件标 rejected,**漏了它绑定的 merchant_bank_card** |
【实测】 |
| 3 | 第一次提交进件就 500,报 Unknown column 'license_validity_type' |
代码 INSERT 写了这些列,V80/V99/V127/V128 都没建;此前测试用 JDBC 直接造进件记录,**绕过了真实入口** | 【实测】 |
| 4 | 个人(小微)走完进件也拿不到微信收款能力 | 门店照片(F22 门头照 / F24 内景照)**一个字段都没收**,而官方在业务开通与实名两处都点名要 | 【实测】 |
| 4b | 线下报备后进件在**第一步**就被整笔驳回:缺失图片:F22-店铺门头照图片;F24-店铺内景图片;F105-店铺收银台 |
通道把「线下经营的门店材料」定成**一组三张**、并在进件这一步由材料校验服务逐张核对;我方只收了两张、且只对个人主体收,**第三张(F105 收银台)全仓没有任何采集口**,企业主体更是一张都不发(extended_material_list 的下发条件写成「仅个人」)。商户端的「重新提交」也没有那两张图的入口 |
【实测】(2026-09-29 真实驳回原文) |
| 5 | 已拿到真实汇付号的存量个人进件一次业务开通都没做过,也没有补图入口 | 分阶段模型下重复提交不新建进件,商户没有别的补图入口(开发库实测 10 条全部 business_open_status=not_started) |
【实测】 |
| 6 | 商户端换账号登录,进件页把**上一个账号**的身份证号、银行卡号预填进来 | 草稿存在固定全局 key,uni storage 不分账号,restoreDraft() 不校验归属 |
【实测】 |
| 7 | 进件能过、商户建得出来,但平台对它调 config/open/query 一律 20002 数据权限认证失败 |
20002 与层级无关;改 head_office_flag+head_huifu_id 建成平台下级**实测无效**,还额外被索要 F725/F726/F727 |
【实测】 |
| 8 | 企业进件通过后,微信配置与业务开通两步**一次都不会被触发** | applyOnboardingResult 把「拿到银行卡序列号 token_no」当前置,而企业进件的同步响应常常只回 huifu_id 和 apply_no |
【推断】 |
| 9 | 商户在进件表单里选的行业没人读,上报 MCC 一律落到「其它(7399)」 | 表单把行业塞进 companyType,而个人进件 MCC 取的是商家档案 merchant_type_code;后来又发现取值优先级反了(表单盖过档案) |
【实测】 |
| # | 现象 | 根因 | 档 |
|---|---|---|---|
| 10 | 任何新商户都开不出微信收款能力:微信支付、人才端绑定、实名全部连坐 | 「微信小程序配置」排在「商户业务开通」**之前**,而微信子商户号是业务开通创建的,配置必被驳;配置一失败就 return,业务开通永远轮不到 |
【实测】 |
| 11 | 业务开通报 wx_conf_list格式错误(第一层) |
小微的 mcc 写在 fee_rule_id 的 else 分支里,平台配了默认规则号之后小微的 mcc 一次都没发过 |
【实测】 |
| 12 | 换号后**仍是**同一句 wx_conf_list格式错误(第二层) |
wx_real_name_info 双重编码:官方字段目录类型列是 Object,代码又 JSON.toJSONString 编了一层;网关 javadoc 与实现不一致 |
【实测】 |
| 13 | 业务开通报「微信费率规则号填写不正确,请检查!」 | CID 按「场景 × 业务开通类型 × 主体类型」三维定位,不能全平台共用一个号(线下2026-09-24起:企业 758/个体户 762/小微 770) | 【实测】 |
| 14 | 六项阶段里 5 项绿,「微信支付」永远未确认,而 sync_error 是空的 |
判定要求 fee_min_amt 必须出现且为 0,而该字段可选、通道在不设最低收费时不返回;缺失被判成未生效 |
【推断】 |
| 15 | 商户端没有授权二维码,而「本人扫码授权」是完成实名的唯一途径 | qrCode() 写死 PNG 的 base64 magic(iVBORw0KGgo),通道回的是 JPEG(/9j/),被判非法返回空串 |
【实测】 |
| 16 | 已授权成功的商户(authorize_stat=1)被显示成「待办理」,二维码还在让人扫 |
授权判定要求 APPLYMENT_STATE_PASSED,而真实样本是 APPLYMENT_STATE_FREEZED + authorize_stat=1;授权完成**只能看 authorize_stat** |
【实测】 |
| 17 | 实名发起被驳回,且**驳回后要换业务申请编号重来** | 实名接口的姓名/手机号/证件号三项必须是**法人本人**的,而进件只收了联系人手机号(实测那家联系人是经办人、法人是另一个人) | 【实测】 |
| 18 | 实名路径选不了经办人 | 经办人(contact_type=SUPER)额外要求经办人身份证正反面 + 加盖公章的《微信业务办理授权函》,盖章件无法自助提交 |
【实测】 |
| 19 | 无回调的部署里整单**永远完不成**,能力快照也永远不刷新 | needsProvisioningStep 只认 blank/not_started/failed,**不含 processing**,而 approved 正是能力刷新与整单完成的判据 |
【推断】 |
| 20 | 业务开通申请被受理了,紧接着发微信配置仍被拒「未查到入驻记录」 | 配置的闸门原取**本地状态**,而**微信入驻是异步的**,那一刻通道侧还查不到子商户号;闸门必须取通道证据 | 【实测】 |
| 21 | 业务开通/微信配置被驳回后重试,通道当成重复请求 | 重试复用同一流水号。修「换号」时踩了第二个坑:**随机后缀必须保住**,先按剩余宽度裁前缀再接后缀,否则超长截断把随机位一起切掉 | 【推断】 |
| 22 | 业务开通被拒「失败:复用交易信息,上级商户号为空」 | use_chains_flag=3 要求上级**本身有商户级微信配置**,而渠道商没有 |
【实测】 |
| 23 | 业务开通被拒「【media_merCommon_flag】不能为空,或格式非法」 | media_mer_common_flag 是 online_media_info_list 的**元素字段**,不是顶层参数;上次「补顶层字段」的修复从来没被验证过 |
【实测】 |
| 24 | 已开好的商户在两端页面被显示成「失败」 | 90000000(审核中)被业务开通网关当成失败,会把一次成功受理记成 business_open_status=failed |
【实测】 |
| 25 | 收款就绪门槛一旦单独落地,**所有没有进度记录的存量商户都收不了款** | 门槛要求「微信开通 + 实名/授权」双 confirmed,而 confirmed 依赖分阶段进度记录,存量商户必须先刷新过进度 |
【推断】 |
| # | 现象 | 根因 | 档 |
|---|---|---|---|
| 26 | 延迟入账上线后,所有新支付都被闸门拦住,报「自动结算尚未关闭」 | 「自动结算必须关闭才能收款」是延迟分账之前立的规则;延迟户已兜住未核销的钱,这条规则不但多余,还把支付路径**直接堵死** | 【实测】 |
| 27 | 进件页标题说「请按待办理项补齐缺失能力」,但六项阶段全绿,一个待办理项都没有 | complete() 还要求 bank(结算卡核实)与 merchantNormal(通道商户状态),这两项既不在 LABELS 里、view() 也不返回 |
【实测】 |
| 28 | (改法风险)把两项核实加进阶段列表,进件会**永远无法 approved** | LABELS 同时是展示列表与完成判定的键集,且 bank/merchantNormal 是布尔值、其余六项必须是字符串 "confirmed"——加进去会两次破坏完成判定 |
【实测】 |
| 29 | 汇付控台关闭商户后,进件页依旧显示「进件已完成 + 六项全已确认」 | approved 之后商户端「刷新进度」按钮被隐藏,而全仓四个 @Scheduled 没有一个刷进件进度快照 |
【实测】 |
| 30 | 被通道关停/从没核实过通道状态的商户,能力快照最长有约 6 小时空窗,期间我们仍认为可收款 | 能力定时核实 30 分钟一轮、只扫超过 stale-hours(默认 6)未核实的申请 |
【实测】 |
| 31 | 「立即核实」按钮可以被连点 | 冷却若用 capability_verified_at 会导致失败时无节流(查询失败时那列不推进);而 updated_at 是 on update current_timestamp,任何无关 UPDATE 都会重置它 |
【实测】 |
| 32 | 一进「收款能力」页就 500,报 Unknown column 'capability_sync_until' |
开发库 flyway 关闭、新列靠初始化器补,而那条 alter 没成功(等 DDL 元数据锁超时);且该查询是**点名列**的,缺列会让整条 SQL 报错 | 【实测】 |
| 33 | 冷却倒计时只在重新进页面时才恢复;没查通道也说「刚核实过」 | 第一版只在重新进页面时判冷却到期,且 refreshed=false 时也宣称刚核实过 |
【实测】 |
| 34 | 结算记录页每次打开都白多几条失败提示(被关停的商户逐条报「客户与产品关系已关闭」) | 页面此前把「进件通过且有子商户号」的商户**全都**问一遍,包括被关停的和从没核实过通道状态的 | 【实测】 |
| 35 | 商户端页面说能收款、下单却被拒(同一个事实两套口径) | 页面判定与下单闸门读了不同的数据;ADR-0002 定为「同源同文案」 | 【实测】 |
| # | 现象 | 根因 | 档 |
|---|---|---|---|
| 36 | 关掉微信收银台后再点「确认支付」和「取消订单」都只报「支付结果确认中」,订单从放弃那刻起就是死的 | 三处叠加:① 重付用查单当闸门,通道对**未付款**的预支付单答 P,代码把 P 判成「不确定」→ 抛错(而本地其实存着支付参数);② 取消同样以查单为前置门,查单答 P 时**连关单接口都不调用**;③ 到期清理刻意排除带未定局流水的订单 |
【实测】 |
| 38 | 反复「继续支付 → 关掉收银台」后,微信弹「订单状态异常,支付请求无效」 | 23000000(原订单已为终态)被并入「其余拒绝」,于是那张**已经不可能被支付**的预支付单被记成 CANCEL_UNCONFIRMED(= 关不掉 = 可能还能付)并继续交回客户端 |
【实测】 |
| 39 | 一笔订单变成「既付不了、同一商品也再下不了单」的僵尸,永远不会被自动收掉 | giveUpClosing 只在「当前状态是 CLOSING」时才结束订单;第一次关单就被拒的流水直接落 CANCEL_UNCONFIRMED,到上限既不结束、也不被到期清理收掉 |
【实测】 |
| 40 | 点「继续支付」**没有任何反应**(按钮被禁),而那张凭证其实还活着 | 复用集合砍过头:CLOSING 是「关单可能已生效」,而 CANCEL_UNCONFIRMED 是「通道明确说这次关单没生效」——后者凭证明明还活着 |
【实测】 |
| 41 | 关单明明几秒就完成,用户却在前台等了 72 秒 | 汇付有专门的「关单查询」接口,我们只发关单、不问结论;副作用是重发关单让 close_attempts 增长,到上限会顺手取消订单 |
【实测】 |
| 42 | 「关单重试每分钟一次、最多三次」实际是「每五分钟一次、最多十五分钟」 | CLOSE_RETRY_MINUTES=1 只是「距上次处理满一分钟」的**资格窗口**,扫描本身由 fixed-delay-ms 决定,默认 300000 |
【实测】 |
| 43 | 用户点了取消、页面关了,取消也丢了;订单仍是「待支付」 | cancel 在关单没结论时只回一个 cancellationPending,意图**没有落库**;而关单后来真关掉时没有任何人去收那笔订单 |
【实测】 |
| 44 | 点了取消一直卡着;实测**三次取消全部**拿到「关单处理中」 | 通道对**刚创建的微信交易**最常见的答复就是「关单处理中」,叠上对账扫描周期 | 【实测】 |
| 45 | 偶发「用户付了钱又被自动退回」,且**手续费大概率不退** | 取消改成「查单确认没收款就立刻生效」,要求用户正好在「查单之后、凭证被关掉之前」那几秒完成支付 | 【实测】 |
| 46 | 待支付页**每秒闪一次**;「刷新支付状态」看着没反应 | 客户端 loadOrder ↔ checkPaymentStatus 互相触发,形成**无限循环** |
【实测】 |
| 47 | 点「确认支付」不拉起微信支付,而是跳到另一个页面再点一次同名按钮 | 设计如此但按钮名与行为不符;且支付结果轮询只有 5×1.5s,且只在 requestPayment 回调 success 后才开始 |
【实测】 |
| 49 | 退款/排查失去唯一的通道凭证(开发库 refund 43/44 的 provider_refund_no 都是空) |
支付查询回执里通道流水号的字段是 org_hf_seq_id;取 hf_seq_id 会把它**静默写成 NULL** |
【实测】 |
| 51 | 漏回调后由主动补查成功的到店订单长期不能计入可提现 | 主动查询更新了支付与订单,但没像回调那样置 STORE_CONSUME.verify_status=1;随后回调因流水已 SUCCEEDED 走幂等分支,也不会补核销 |
【实测】 |
| 53 | 对账台报错:同一笔业务被反复「结掉又开出」时撞唯一键 (issue_type, provider, business_no, status) |
结掉那一步会撞上已存在的 resolved 行 | 【实测】 |
第 37、48、50、52 条在 §1。
| # | 现象 | 根因 | 档 |
|---|---|---|---|
| 54 | 通道确认收了钱、但订单已取消(悬账),原先只在账目上留一条问题记录等人工,**没有任何自动出口** | 退款链路的硬门是 OrderFundBoundaryService.requireRefundable() 的 orderStatus != 1;四个 @Scheduled 没有一个消费这类问题记录 |
【实测】 |
| 55 | 「本地已关闭但通道其实收了钱」那类悬账**连支付键都看不到**,退款无从发起 | 支付键可见性只认「已成功流水」;旧实现下 CLOSED + 一条「取消后才收到钱」的问题记录定位不到原支付流水 |
【实测】 |
| 58 | 14:37:31 提交退款、14:43:41 才对账收敛,中间六分钟里钱已退回,两端却仍显示「待核销」 | 退款提交时通道只回「处理中」,退款通知到不了本地;**读路径不收敛**(收敛必须是调用方事务的第一条读语句,MySQL 一致性快照就在那条语句上定下) | 【实测】 |
| 59 | 商户端首页「交易总额」把未核销、退款中的订单也算进去,退款后金额不回落 | 首页卡片 SQL 只过滤 order_status = 1,**漏了核销条件**;退款受理只把订单置「退款中」 |
【实测】 |
| 61 | 回退被拒时只能给商户一句「撤销失败」,商户不知道该重试还是该找平台 | 回退结果有四种归途(成功→pending;明确拒绝→退回可重试的 confirmed;语义未定→停在 reverting 交人工;通道还在处理→在途),而通道侧语义未定 |
【实测】+【推断】 |
| 62 | 撤销核销被永久卡住 | 补偿任务只扫 pending/confirming,**reverting 永远没人再看**;delaytrans.confirmquery 有实现却是死代码;同一天认领的 confirming 要等到次日才重认领 |
【实测】 |
| 65 | 补偿任务每隔几分钟无意义地打一次通道,永远不自愈 | 通道对「已经没有待确认金额」的延迟交易返回 23000003,且**同时给 trans_stat=F**;旧实现先看交易状态、再看返回码,把幂等成功判成失败 |
【实测】 |
第 56、57、60、63、64、66 条在 §1。
| # | 现象 | 根因 | 档 |
|---|---|---|---|
| 67 | 后台「结算记录」页一条流水都不显示,而通道里其实有记录 | 结算记录查询 pageSize 上限 50,超了直接回 00000003 且**一条都不返回**(不是截断);后台默认传 100 |
【实测】 |
| 68 | 结算记录页的商家/联系电话/商家类型/状态四个查询条件**完全无效**;日期栏标签写「申请时间」,实际筛的是结算日期 | 前端切到结算记录时只发日期与条数,四个条件根本没发出去;状态下拉在结算记录下是空列表 | 【实测】 |
| 69 | 快速切换标签时,结算流水的响应**覆盖**了已经切过去的进件/银行卡表格 | load() 写回表格前没有身份校验,两次请求同时在飞时后到者覆盖先到者;而结算记录要逐商户问斗拱,是最慢的一次 |
【实测】 |
| 70 | 一笔已经受理的取现被本地误判成失败,解锁订单并把**同一笔钱再取一次** | 取现结果查询用 huifu_id + org_req_date + org_req_seq_id 定位;若商户在提交与查询之间换了子商户,会得到 23000001 交易不存在 |
【实测】 |
| 71 | 提现失败当天被当成「已汇总」,钱后来可取了也没有任何出账路径 | 失败记录没有退回 pending 复用同一条 | 【实测】 |
| 72 | 定时对账(支付与退款唯一的后台兜底)可能**静默消失** | 间隔曾靠注解默认值生效、没写进配置,而注解上 enabled 默认是 false,靠 yml 那一行打开——删掉那行兜底就没了(**现已修好并有测试钉住**) |
【实测】 |
| 73 | 交易确认补偿任务的开关**从未被读取**,任务永远在跑(javadoc 却宣称有这个开关) | 配置键在代码里从未读取、yml 里也不存在 | 【实测】 |
| 76 | (高风险)后台仍有「跳过真实支付、直接置为已支付」的入口,且页面权限拦截器没有匹配 /api/orders/** |
OrderService.pay 只更新 order_status=1,不要求支付流水或汇付结果;该订单再被核销便进入结算统计 → 待确认清单第 1 条 |
【推断】 |
第 74、75 条在 §1。
| # | 现象 | 根因 | 档 |
|---|---|---|---|
| 79 | 重启过也不代表有新列:legal_mobile 缺列时,**任何新进件提交**都 500,实名被拦成「还缺法人手机号」(看着像商户没填) |
addColumn 把 lock_wait_timeout 压到 5 秒,拿不到锁就放弃并记日志;同一轮循环里它后面的列都加成功、只有它没有 |
【实测】 |
| 80 | GET /api/merchant/onboarding/status 第一个请求就 500(Table ... doesn't exist) |
V144 新建的两张表在开发库从未建立;开发库 spring.flyway.enabled=false,而初始化器**只有加列路径、没有建表路径**;测试库由 Flyway 建表,所以测试全绿看不出 |
【实测】 |
| 81 | 合并后 Flyway 报「同一版本两个迁移」,本地四个迁移全部要改名 | 双方从同一祖先(V147)各自独立占了 V148–V151(**git 不报冲突,Flyway 会直接报重**) | 【实测】 |
| 82 | 迁移在 MySQL 8.0.36 上直接 ERROR 1064 |
不能写 ADD COLUMN IF NOT EXISTS——那是 MariaDB 的扩展(同一条坑在 V143/V145/V146 头注释里被记了三次) |
【实测】 |
| 83 | 已执行过的迁移改一个字符,测试库直接起不来 | Flyway checksum 不匹配 | 【实测】 |
| 84 | 看起来不可能的报错,例如 No qualifying bean of type 'HuifuPaymentProperties' |
同一 checkout 并发跑两个 Maven 构建会写坏 target/;mvnw.cmd 是 batch/PowerShell 混合 wrapper,**总是**用 PowerShell 5.1 引导,而 5.1 会把 Maven 打到 stderr 的警告当成终止错误 |
【实测】 |
| 85 | 首页统计的回归测试在 H2 缝上**根本跑不起来**(HEAD 上就红) | 相关 SQL 内联了 GovernmentSubsidySql.AMOUNT_CENTS,用到 MySQL 的 json_extract 与 if();H2 2.4.240(MODE=MySQL)两者都没有,if() 更是语法错误 |
【实测】 |
| 86 | 测试全部报 Connection refused,或更绕的 Unable to determine Dialect without JDBC metadata |
测试库那个 8.0.36 跑在 WSL 的 docker 里,WSL 虚拟机会在空闲时自己关掉。**光起容器不够**——命令一返回 VM 又空闲关掉(现象:容器每次 docker ps 都显示 Up 2 seconds),要用一个长命进程挂住它 |
【实测】 |
| 87 | 某个用例**从今往后每跑必红**,不是偶发 | 补偿任务扫全库 + order by o.id asc limit 50;用例自己新建的那单 id 最大,排在窗口外。测试库共享且从不清理,符合条件的行累计到 50 条以上就饱和(**已修**) |
【实测】 |
| 88 | 拿旧副本库判断开发库状态,结论全错 | 本机 8134 上有三个库是合并前的本机副本,**不再是开发库**;而 .scratch/ 下很早的探针把 URL 写死成 127.0.0.1:8134/talent_card |
【实测】 |
| 89 | (环境事故)开发库里迁移从未创建的历史表被删掉,一批数据丢失 | 「把测试库结构克隆到开发库」「reset-test-db.ps1 -Database talent_card」这类操作会删掉手建表;2026-09-13 就这样丢过一批 |
【实测】 |
第 77、78 条在 §1。
| # | 现象 | 根因 | 档 |
|---|---|---|---|
| 90 | 查目标商户一律 20002 数据权限认证失败;以目标商户自身作 sys_id 查自身,SDK 报无响应、HTTP 922 空响应 |
平台身份对不归自己的商户没有数据权限。凭据轮换成目标商户的**直属上级渠道**后 20002 才解除 | 【实测】 |
| 91 | 在控台的商户关系上做文章(head 层级、总部客群类型)对 20002 完全无效 | 20002 与层级无关,取决于签名身份本身有没有那些商户的数据权限 | 【实测】 |
| 92 | 测试输出里出现运行配置的**明文私钥** | HuifuSignatureServiceTests 会打印运行配置(已改为使用 keySummary 摘要函数) |
【实测】 |
| 93 | 微信费率默认写成 0.60,费率规则号默认为空,导致真实补开时费率与 CID 都是错的 | 默认值是在「企业 756 + 0.70」定稿之前写的;HuifuPaymentProperties 的 Java 默认值与 yml 也不一致 |
【实测】 |
| 94 | 配置里写着开发也能用的回调地址,实际开发机不可达 | 五个回调地址全指向一个公网 IP;且平台没有公网服务器 | 【实测】 |
| 95 | 回调地址为空时会静默指向一个不可达地址,没人知道回调其实没启用 | 原实现靠 notify-url 推导其余四个地址,缺一个也看不出来(现已显式写出,并有启动自检 HuifuCallbackUrlAudit) |
【实测】 |
第 96 条在 §1。
| # | 问题 | 影响 |
|---|---|---|
| 1 | 审计 §7 那个「跳过真实支付直接置为已支付」的入口现在是否真的不存在(OrderService.pay 与 AdminAuthInterceptor.page() 的当前状态) |
若仍在,任何能进后台的人都能造出「已支付」订单并进入结算统计 |
| 2 | 核销后交易确认在「商户被通道关停」下能否成功、钱是否还留在延迟户(closure-impact 写明「代码里看不出来,**需要实测**」) | 决定关停商户的钱往哪走 |
| 3 | 真机上核销码图片取不回来的根因(候选:「http 图片被微信真机拦掉」vs「图片请求 404」) | 决定现在是等后台切 HTTPS,还是另有 bug |
| 4 | provider_refund_no 之外还有没有别的「只在某一次回执里出现的字段」被无条件覆盖 |
已修一处,未做全局排查 |
| 5 | 进件的 store_address_code 与门店照片在真实通道上的接受度 |
audit 写明「未验证……不能用『模拟测试通过』代替」 |
| 6 | 业务开通的 micro_biz_type 是否与独立实名接口重复 |
audit 里「仍未官方确认」的唯一一条 |
| 7 | 补贴总额(subsidyAmountCents)口径是否有意不带核销条件 |
与交易总额口径不一致,需产品/结算确认(第 59 条同源) |
| 8 | DashboardSummaryService.summary() 死副本是否该删 |
文档说「谁把它接上去,这个 bug 就会回来」 |
| 9 | PaymentFundConfirmationRetry.enabled 的默认取值 |
影响资金确认补偿是否默认在跑 |
| 10 | 进件进度 sync_owner/sync_until 的 5 分钟租约与 capability_sync_until 的 5 分钟冷却是否必须同值 |
ADR-0002 只说「同量级」 |
| 11 | 五个回调地址当前在**通道侧**各注册的是什么 | HuifuCallbackUrlAudit 只能报「我们配了什么」,报不了「通道记住了什么」——必须在控台逐条比对并留档 |
| 12 | 通道 trans_log_result_list[].card_no 是明文还是掩码 |
本地未再脱敏,涉及日志与页面展示合规 |
| 13 | merchant_withdrawal 删除前的旧记录是否已完成人工收尾 |
退役链路的遗留 |
| 14 | POST /merchant-settlement/auto-withdrawal/run 是否还有仓库外的调用方 |
代码里零命中,但脚本/运维手册无法从仓库判断 |
| 15 | 旧提现文档 rencaika_merchant/docs/pages/13-商户提现.md 与 ?kind=withdrawals 旧链接是否要清理 |
文档层面会误导 |
| 16 | app.order.pending-expiry 那个到期清理任务的间隔是否符合预期 |
它没有 yml 条目、没有开关、也不在 PaymentSchedulingConfigurationTests 覆盖范围内,无任何钉住机制 |