链路总览与代码地图

适用提交: 6c42f8f | 最后验证: 2026-09-18 | 何时会失效: 新增端侧入口、新增通道能力、或闸门/资金链路的判定被改动时

这份文档回答三件事:**整条链路长什么样**、**代码在哪**、**我要改 X 该去哪**。末尾有本节最该记住的 6 条硬规定。


1. 端到端总览

flowchart TD
    subgraph ONBOARD["① 进件(商户端发起)"]
        A1["商户提交资料<br/>MerchantWorkController"] --> A2["MerchantSettlementService<br/>提交企业/个人进件"]
        A2 --> A3["汇付进件接入<br/>同步回 huifu_id / apply_no"]
        A3 --> A4["通道异步回调<br/>MerchantSettlementService.handleOnboardingCallback"]
        A4 --> A5["business_open_status<br/>分阶段:微信支付 → appId → 实名 → 延迟入账 → 自动结算"]
    end

    subgraph READY["② 收款就绪(闸门)"]
        B1["MerchantPaymentReadinessService<br/>唯一判定点"] --> B2{"本地快照 + 通道能力<br/>都正常?"}
        B2 -->|否| B3["拒绝下单<br/>同源同文案"]
        B2 -->|是| B4["允许下单"]
    end

    subgraph PAY["③ 支付"]
        C1["人才端下单<br/>PendingOrderPortalController"] --> C2["订单固定收款子商户<br/>collect_onboarding_id / collect_huifu_id"]
        C2 --> C3["HuifuPaymentService<br/>落 payment_transaction + 调网关"]
        C3 --> C4["微信收银台"]
        C4 --> C5["通道异步回调<br/>PaymentCallbackController"]
        C4 -.回调可能丢.-> C6["对账兜底<br/>PaymentReconciliationService<br/>每分钟一轮"]
        C5 --> C7["PaymentSettlementService<br/>唯一幂等结算入口"]
        C6 --> C7
    end

    subgraph FUND["④ 核销与资金"]
        D1["核销<br/>三条入口收敛"] --> D2["交易确认<br/>PaymentFundConfirmationService"]
        D2 --> D3["钱从延迟户进商户基本户<br/>funds_confirmation_status=confirmed"]
        D4["撤销核销"] --> D5["交易确认退款<br/>钱退回延迟户"]
    end

    subgraph SETTLE["⑤ 结算"]
        E1["斗拱按 settle_config 批次自动结算<br/>平台不生成提现记录"] --> E2["后台结算记录页<br/>实时查通道,本地无表"]
    end

    ONBOARD --> READY --> PAY --> FUND --> SETTLE
    PAY -.取消/关单.-> C8["关单 + 关单查询<br/>PaymentReconciliationService"]
    C8 -.悬账.-> C9["StrandedPaymentRefundRetry<br/>自动原路退回"]

图的文字兜底:商户先进件 → 通道异步回调推进「业务开通/实名/延迟入账/自动结算」五项能力 → 能力齐了才允许人才端下单 → 订单在创建时就**固定收款子商户**(防止支付请求漂移到别家门店)→ 支付成功靠回调推进,**回调丢了由每分钟一轮的对账兜底**(两者最终都走 PaymentSettlementService 这**唯一**的幂等结算入口)→ 核销时才把延迟户的钱确认给商户 → 撤销核销要把钱退回去 → 结算由斗拱按周期自动做,本地只有查询没有表。


2. 三端代码地图

2.1 后端 talent-card-server

这条链路**没有 MyBatis 实体与 Mapper**(mapper/ 目录只服务别的业务),全部用 JdbcTemplate 直接写 SQL。通道调用统一封在 business/payment/huifu/ 内。

business/
  payment/                                    支付链路编排层(与具体通道无关)
    PaymentCallbackController.java            汇付异步通知总入口,5 个回调端点
    HuifuPaymentService.java                  小程序下单:校验订单/幂等键、落 payment_transaction、调网关、状态映射
    HuifuPaymentCallbackService.java          支付回调:先验签、再解析、去重,交给 PaymentSettlementService
    PaymentSettlementService.java             ★ 唯一幂等结算入口(回调与查单都走这里,比对请求号/商户号/金额后才改本地状态)
    PaymentReconciliationService.java         第二确认路径:查单、关单、关单查询、取消前确认、退款收敛、问题记录
    PaymentReconciliationScheduler.java       对账定时任务(默认 1 分钟一轮)
    HuifuRefundService.java                   退款受理/查询/回调收敛,含悬账判定
    PaymentFundConfirmationService.java        延迟入账资金确认(核销时交易确认)与撤销核销的资金回退
    PaymentFundConfirmationRetry.java          资金确认补偿(已核销但资金未确认的订单)
    StrandedPaymentRefundRetry.java           悬账(订单已取消但通道收到钱)自动原路退回
    PaymentIssueRecorder.java                 差错台账 payment_reconciliation_issue
    HuifuCallbackUrlAudit.java                启动时逐个打印五个回调地址的结论
    huifu/                                    ★ 斗拱 SDK 封装层(唯一直连通道的地方)
      HuifuPaymentProperties.java             @ConfigurationProperties("app.payment.huifu")
      HuifuSignatureService.java              ★ 唯一的验签实现(SHA256WithRSA + 平台公钥)
      HuifuPayload.java                       回执统一解析:字段名、元→分、TransStatus、业务码语义
      HuifuMiniProgramPaymentGateway.java     下单 + 关单 + 关单查询 + 查单
      HuifuRefundGateway.java                 退款与退款查询
      HuifuDelayAccountGateway.java           延迟交易确认与交易确认退款(回退)
      HuifuMerchantCapabilityGateway.java     查商户状态/自动结算/取现开关
      HuifuSettlementRecordGateway.java       结算记录查询(pageSize 上限 50)
      Huifu*OnboardingGateway.java            企业/个人进件提交
      HuifuMerchantBusinessOpenGateway.java   商户业务开通(微信支付能力)
      HuifuMerchantWechatConfigGateway.java   微信商户配置下发
      HuifuMerchantRealnameGateway.java       微信实名认证申请
      HuifuPictureUploadGateway.java          ★ 唯一直接用 RestTemplate 出站的地方(图片取 file_id)
  merchant/
    MerchantSettlementService.java            商户端进件提交/刷新/业务开通/银行卡/回调处理的总编排
    MerchantOnboardingProgressService.java    六阶段进度模型 + 人工刷新
    MerchantPaymentReadinessService.java      ★ 唯一「这家商户能不能收款」判定点 + 能力快照读写
    MerchantPaymentCapabilityScheduler.java   能力快照定时刷新
    MerchantRealnameService.java              微信实名认证申请(法人路径)
    MerchantOnboardingSchemaInitializer.java  无 Flyway 部署的补列 best-effort
    MerchantWorkController.java               商户端入口
  admin/
    MerchantSettlementAdminService.java       后台进件/银行卡/结算记录查询、代发起实名、能力刷新
    AdminManagementController.java            后台管理端点入口
  order/
    OrderService.java                         订单写路径
    OrderFundBoundaryService.java             ★ 订单资金边界(核销/退款/提现锁定串行化,SELECT FOR UPDATE)
  portal/
    PendingOrderPortalController.java         人才端入口:支付、取消
    AppOrderPortalService.java                人才端创建订单(绑定收款子商户)

注意:后台**没有人工「进件审核」动作**。merchant_onboarding_application.status 的 approved/rejected 由**通道回调**写入;后台只有查看 + 刷新 + 代发起实名。

2.2 后台 talent-card-admin(Vue)

文件 作用
src/views/MerchantSettlementView.vue 核心页,3 个 tab:结算记录 / 商户进件 / 银行卡
src/views/MerchantOnboardingDetailView.vue 进件详情:进度、收款能力、实名、银行卡、二维码
src/views/OrderView.vue / OrderDetailView.vue 订单列表/详情,含「立即对账」
src/views/RefundRecordView.vue 退款记录与「刷新退款状态」
src/api/admin.ts、src/types/admin.ts 端点与类型

后台没有「支付对账问题台账」页面:GET/PATCH /api/admin/management/payment-reconciliation/issues 已实现,但前端只用了「立即对账」按钮——台账目前只能查库或直连接口。

2.3 端侧(uvue)

目录 端
rencaika_merchant/pages/merchant-onboarding/、merchant-onboarding-pending/、payment-capability/、bank-card-add/ 商户端:进件、待审、收款能力、银行卡
rencaika_merchant/services/merchant-management.uts、settlement.uts、onboarding-draft.uts 商户端服务层
rencaika/pages/pending-payment/ 人才端:待支付

2.4 ⚠️ 改前端前必读

uvue 客户端没有可编译的反馈回路(本机没有 HBuilderX / uni CLI),改前端**只能真机验证**。06 第 46 条那个「待支付页每秒闪一次」就是这么产生的——客户端 loadOrder ↔ checkPaymentStatus 互相触发形成无限循环,静态读代码看不出来。改这两端之前,先确认你有真机调试环境。


3. 我要改 X 该去哪

我想改… 去哪 顺带看
进件表单字段/校验 rencaika_merchant/pages/merchant-onboarding/ + MerchantSettlementService 06 §2
进件后要开哪些能力 MerchantSettlementService + MerchantOnboardingProgressService.LABELS 06 第 28 条(加第 7 项会破坏完成判定)
谁能收款(闸门) MerchantPaymentReadinessService 01 §4 硬规定第 1 条;ADR-0002
下单/支付参数 HuifuPaymentService + HuifuMiniProgramPaymentGateway 05 §2.1 签名规则
支付回调校验 PaymentSettlementService 01 §4 硬规定第 5 条
关单/取消 PaymentReconciliationService 06 第 36/38/39/40/41/42/43 条一串
退款 HuifuRefundService + OrderFundBoundaryService 06 第 56/57 条
核销与资金确认 PaymentFundConfirmationService + OrderFundBoundaryService 06 第 60/64/66 条
结算记录页 MerchantSettlementAdminService + MerchantSettlementView.vue 06 第 67/68/69 条
对账节奏/开关 PaymentReconciliationScheduler + application.yml 08-上线与环境.md
通道配置/费率/CID application.yml 的 app.payment.huifu 05 §3 第 18/19 条;reference/official/wx-fee-rule-id.xlsx
差错台账 PaymentIssueRecorder + payment_reconciliation_issue 06 第 53 条
排查线上问题 07-排障手册.md + talent-card-server/scripts/probes/ —

4. 硬规定

这六条**不是在描述现状,是在约束改动**。它们各自都有一次踩坑换来。

1. 页面判定与下单闸门必须同源同文案(ADR-0002)

商户端页面说「能收款」、下单却被拒——这个 bug 出现过一次,根因是两处读了不同的数据。**任何新增「能不能收款」的展示,都必须调 MerchantPaymentReadinessService 的同一个入口,不许另写一份判定。** 有测试 merchantViewReusesTheGateMessage 钉住。

2. 可复用集合只含 PREPAY_CREATED + CANCEL_UNCONFIRMED

一单一活预支付单。这个集合**已经改过四轮**(PREPAY_CREATED → +CLOSING → 只留 PREPAY_CREATED → +CANCEL_UNCONFIRMED),每次都是因为把「关单可能已生效」和「关单明确没生效」混在一起:

  • CLOSING = 关单**可能**已生效 → 不可复用
  • CANCEL_UNCONFIRMED = 通道明确说这次关单**没生效**(拒绝关单,或关单请求本身失败 90000000)→ 凭证**还活着**,**正是最该复用的一张**

3. 先判业务码,再判交易状态

通道的 23000003 会**同时带 trans_stat=F**,但它在交易确认路径上是**幂等成功**(「已无未确认金额」)。先看交易状态再看返回码,必然把幂等成功判成失败——补偿任务会每隔几分钟无意义地打一次通道,永远不自愈。见 HuifuDelayAccountGateway.java:223-239。

4. LABELS 同时是展示列表与完成判定的键集

MerchantOnboardingProgressService.LABELS 既驱动进件页的六项阶段展示,**又是完成判定的键集**。往里加第 7 项(例如把 bank/merchantNormal 加进去)会两次破坏完成判定:这些是布尔值,而其余六项必须等于字符串 "confirmed",加进去进件会**永远无法 approved**。ADR-0002 的「考虑过但没选的」记的就是这条。

5. 通道状态必须存在不依赖回调的查询路径(ADR-0004)

回调会丢、会重、本地与无公网环境根本收不到。 任何一个「只有回调能推进」的状态都是 bug。新增通道能力时,必须同时回答:「回调丢了,谁把它推进?」ADR-0004 里那张「谁触发查询」的边界表,每次新增能力都要补一行。

6. 通道侧的收款能力以快照为唯一口径(ADR-0002)

不看 merchant_stat 的实时值做业务判定,也不把它混进六项阶段——一律读能力快照,与下单闸门同源。快照的时效靠定时核实 + 手动刷新冷却来保证,见 02-进件与收款能力.md。


5. 相关文档

文档 讲什么
README.md 导航、术语对照、权威来源地图、维护契约
02-进件与收款能力.md 进件、业务开通、实名、能力快照、收款闸门
03-支付与资金.md 下单、回调、关单、取消、延迟入账、交易确认、退款
04-结算与对账.md 斗拱自动结算、结算记录页、差错台账、退役提现
05-汇付对接注意事项.md 汇付侧协议契约与 28 条反直觉行为
06-踩坑清单.md 96 条我方踩坑 + 待确认清单
07-排障手册.md 症状 → 排查路径 → 探针
08-上线与环境.md 环境、凭据、回调地址、开关、上线验收、迁移规约
docs/adr/0001~0004 四份架构决策记录
docs/agents/testing.md 测试环境与测试库纪律
talent-card-server/docs/huifu-payment-integration.md 附录 A:英文实现说明,细节细节以它为准