--- schema: "hl-changelog/v2" ticket: "8815" title: "账户流水与微信商户对账双向查询关联(对账↔流水互查)" consumer: "admin" author: "yst" change_type: "新增接口" backend_status: "merged" gateway_status: "not_required" frontend_status: "implemented" frontend_owner: "hl-admin(claude)" frontend_ref: "be239b050946d54d74234a77fe1d7470c95c5c86" target_release: "v2.1" verified_at: "2026-10-10" status_note: "后端 PR #8816 已合并 dev-v3(squash aad53d1fa3)。A 方案纯只读查询,零写、无 DDL、不碰资金;新增 2 个互查接口(对账→流水、流水→对账),部署 order-v3 后可用。 / 前端已交付:对账抽屉加「关联流水」(复用 FlowDetailDrawer,null 显无关联流水),流水页加「关联微信账单」(LinkedWxBillsModal 多条列表,空数组显无关联微信账单);checkpoint 全量过" updated_at: "2026-10-10" base: "dev-v3" --- # 账户流水与微信商户对账双向查询关联 > 面向:管理后台前端(hl-admin) > 日期:2026-10-09 | 后端:order-v3,PR 已合并 dev-v3 > 关联契约(同仓):`changelogs-v2/2026-10/01_8690_微信商户对账-新增接口-管理后台.md`(本篇字段表自包含) ## 1. 接口背景 微信商户对账页(#8690)能看微信侧逐笔账单,账户流水页能看我方收款流水,但两边此前**互相不通**——对账发现差异时,财务要手工拿商户单号去流水里搜,或在流水里看到一笔收款想查微信侧原始账单也得手工翻。本次新增 **2 个只读查询接口**,实现双向跳转核对: - **对账 → 流水**:在对账页的账单记录上,一键查我方是否已记收款流水(接口 1)。 - **流水 → 对账**:在账户流水页的流水行上,一键查微信侧的原始账单记录(接口 2)。 关联链路:`wx_bill_record.out_trade_no → payment_transaction → transaction_id → fin_fund_flow.biz_id`(仅 biz_type=ORDER_PAY 的订单支付流水能关联),反向同理。两接口**纯只读**,零写、无 DDL、不碰资金。 ## 2. 变更清单 | # | 接口 | 方法 | 路径 | 变更类型 | 说明 | |---|------|------|------|----------|------| | 1 | 对账→流水:按账单记录查我方收款流水 | GET | /v3/admin/payment/wx-bill/records/{billRecordId}/fund-flow | 新增接口 | 单值对象,无关联时 data=null | | 2 | 流水→对账:按账户流水查微信侧账单记录 | GET | /admin/finance/fund-flows/{flowId}/wx-bill-records | 新增接口 | 列表(容错退款/部分支付多笔),无关联返回空数组 | ## 3. 接口详情 ### 3.1 对账→流水 GET /v3/admin/payment/wx-bill/records/{billRecordId}/fund-flow - **使用场景**:对账页逐笔账单记录行的「关联流水」操作,查我方账户是否已针对该笔微信收款记账。 - **认证**:需管理后台 JWT。 - **幂等性**:只读。 - **限流**:无。 ### 3.2 流水→对账 GET /admin/finance/fund-flows/{flowId}/wx-bill-records - **使用场景**:账户流水页的流水行「关联微信账单」操作,查该笔收款对应的微信侧原始账单记录(可能多笔:退款/部分支付场景)。 - **认证**:需管理后台 JWT。 - **幂等性**:只读。 - **限流**:无。 ## 4. 接口入参 ### 4.1 接口 1(对账→流水) | 字段 | 位置 | 类型 | 必填 | 说明 | 校验规则 | |------|------|------|------|------|----------| | billRecordId | 路径 | Long | 是 | 微信账单记录ID(wx_bill_record 主键) | 不存在则报 582407 | ### 4.2 接口 2(流水→对账) | 字段 | 位置 | 类型 | 必填 | 说明 | 校验规则 | |------|------|------|------|------|----------| | flowId | 路径 | Long | 是 | 账户流水ID(fin_fund_flow 主键) | — | 两接口均无 Query 参数、无请求体。 ## 5. 出参字段 统一 `Result` 包装。Long 主键以 **JSON 字符串**返回。 ### 5.1 接口 1 出参 WxBillRecordFundFlowRespVO(单值对象,无关联时 data=null) | 字段 | 类型 | 说明 | |------|------|------| | flowId | String(Long) | 账户流水ID | | flowNo | String | 流水号 | | amount | BigDecimal | 金额(元) | | fundAccountId | String(Long) | 资金账户ID | | fundAccountName | String | 资金账户名称 | | direction | String | 收支方向(如 IN 收 / OUT 支) | | flowAt | DateTime | 流水发生时间 | | bizType | String | 业务类型(关联场景为 ORDER_PAY) | | orderNo | String | 关联订单号 | **无关联时 `data` 为 null**(两类情况:billType=FUND_FLOW 的资金账单没有此关联;或微信有该笔账单但我方尚未记账)。前端据此显示「无关联流水」。 ### 5.2 接口 2 出参 FundFlowWxBillRecordRespVO(列表,无关联时 data=[]) | 字段 | 类型 | 说明 | |------|------|------| | billRecordId | String(Long) | 微信账单记录ID | | mchId | String | 微信商户号 | | billDate | Date | 账单日期 | | billType | String | 账单类型:TRADE / FUND_FLOW | | wxTransactionId | String | 微信支付单号 | | outTradeNo | String | 商户单号 | | tradeTime | DateTime | 交易时间 | | tradeType | String | 交易类型(如 JSAPI) | | tradeState | String | 交易状态(如 SUCCESS) | | amount | BigDecimal | 交易金额(元) | | appid | String,可空 | 微信公众账号ID(小程序 wx 前缀 / 企业微信 ww 前缀) | **返回列表**:退款、部分支付等场景同一笔流水可能对应微信侧多笔账单记录,故用数组。仅 **biz_type=ORDER_PAY 且有关联交易**的流水才有数据;其他业务类型流水(如调账、提现等)返回空数组 `[]`。 ## 6. 枚举 / 数据字典 - **本次无枚举/字典新增**。沿用对账模块既有值: - `billType`:TRADE(交易账单)/ FUND_FLOW(资金账单) - `direction`:IN(收)/ OUT(支) - `bizType`:关联场景为 ORDER_PAY(订单支付) ## 7. 错误码 | 错误码 | 触发场景 | 说明 | |--------|----------|------| | 582407 | 接口 1 的 billRecordId 非法/不存在 | 账单记录不存在 | 接口 2 无新增业务错误码;flowId 不存在等场景走统一响应。 ## 8. 示例 ### 8.1 接口 1 典型成功(交易账单已关联我方流水) ``` GET /v3/admin/payment/wx-bill/records/1976123456789012345/fund-flow ``` ```json { "code": 0, "data": { "flowId": "1977000111222333444", "flowNo": "LS20261008120001", "amount": 1280.00, "fundAccountId": "1976000000000000001", "fundAccountName": "微信商户-主账户", "direction": "IN", "flowAt": "2026-10-08 12:00:05", "bizType": "ORDER_PAY", "orderNo": "HL20261008120000123456" } } ``` ### 8.2 接口 1 边界情况(无关联,data=null) 资金账单(FUND_FLOW)或微信有账单但我方未记账时: ```json { "code": 0, "data": null } ``` 前端显示「无关联流水」。**注意 code 仍是 0**,判空看 data 是否为 null。 ### 8.3 接口 1 业务失败(billRecordId 不存在) ``` GET /v3/admin/payment/wx-bill/records/9999999999999999999/fund-flow ``` ```json { "code": 582407, "msg": "账单记录不存在", "data": null } ``` ### 8.4 接口 2 典型成功(流水关联到微信交易账单) ``` GET /admin/finance/fund-flows/1977000111222333444/wx-bill-records ``` ```json { "code": 0, "data": [ { "billRecordId": "1976123456789012345", "mchId": "1600000001", "billDate": "2026-10-08", "billType": "TRADE", "wxTransactionId": "4200001234202610081234567890", "outTradeNo": "HL20261008120000123456", "tradeTime": "2026-10-08 12:00:01", "tradeType": "JSAPI", "tradeState": "SUCCESS", "amount": 1280.00, "appid": "wx4711a76772deff36" } ] } ``` ### 8.5 接口 2 边界情况(无关联,返回空数组) 非 ORDER_PAY 类型的流水(如调账流水),或该流水无关联交易: ``` GET /admin/finance/fund-flows/1977000999888777666/wx-bill-records ``` ```json { "code": 0, "data": [] } ``` **注意 code 仍是 0**,判空看数组长度,前端显示「无关联微信账单」。 ### 8.6 接口 2 多笔关联(退款/部分支付场景) 同一笔流水可能对应微信侧多笔账单记录,列表会有多条元素,前端按列表渲染即可,勿假设只有一条。 ## 9. 业务边界 - **适用**:对账页账单记录 ↔ 账户流水页流水行的互相跳转核对。 - **不适用**:不用于触发任何资金/数据改动——两接口均为纯只读查询,不产生对账处理、不改流水状态。 - **关联范围有限**:只有 biz_type=ORDER_PAY(订单支付)且经由 payment_transaction 关联的流水才能查到微信侧账单;其他业务类型流水(调账、提现、盘盈亏等)接口 2 恒返回空数组。 - **资金账单无反向关联**:billType=FUND_FLOW 的微信账单记录调用接口 1 恒返回 data=null。 ## 10. 修改前后对比 新增接口类,跳过(无旧版本对比)。 ## 11. 影响评估 / 回滚 新增接口类,跳过。补充说明: - **破坏性**:无。纯新增 2 个只读端点,不改任何既有接口的入参/出参/枚举。 - **前端同步上线**:不要求。未接期间对账页/流水页维持现状即可。 - **回滚方案**:order-v3 回退到 #8816 之前版本即可,两新端点 404;前端按可空/兜底处理即可,无需配合回滚。 ## 12. 注意事项 1. **两个「无关联」都是成功响应**:接口 1 无关联返回 `code:0, data:null`;接口 2 无关联返回 `code:0, data:[]`。不要当成错误处理,也不要把 582407(记录不存在)与「无关联」混淆——前者是入参非法,后者是合法但无关联数据。 2. **接口 2 是列表**:即使常见场景只有一条,也必须按数组渲染(退款/部分支付会多条)。 3. **Long 主键字符串化**:flowId / fundAccountId / billRecordId 均为 JSON 字符串,勿当 number 处理。 4. **路径前缀不一致是有意的**:接口 1 在对账域 `/v3/admin/payment/wx-bill/*` 下,接口 2 在财务域 `/admin/finance/fund-flows/*` 下(两域各自的既有前缀),前端网关路由按各自前缀走。 5. 部署时序:需 order-v3 部署到本版本后两端点可用,未部署前调用会 404。 ## 13. 关联 / 联系人 - Issue:https://git.1814.love/wx/HL/issues/8815 - PR:https://git.1814.love/wx/HL/pulls/8816 - Commit:https://git.1814.love/wx/HL/commit/aad53d1fa3 - 后端负责人:腰苏图(yst)