docs(changelog): 账户流水与微信商户对账双向查询关联(#8815,PR #8816)
changelog-filename-gate / validate (push) Failing after 2s

新增 2 个只读接口:对账→流水(/v3/admin/payment/wx-bill/records/{billRecordId}/fund-flow)
与流水→对账(/admin/finance/fund-flows/{flowId}/wx-bill-records),管理后台目录 changelogs-v2。
这个提交包含在:
yaosutu
2026-10-09 17:55:39 +08:00
父节点 90b18a1594
当前提交 c87e079286
@@ -0,0 +1,259 @@
---
schema: "hl-changelog/v2"
ticket: "8815"
title: "账户流水与微信商户对账双向查询关联(对账↔流水互查)"
consumer: "admin"
author: "yst"
change_type: "新增接口"
backend_status: "merged"
gateway_status: "not_required"
frontend_status: "pending"
frontend_owner: ""
frontend_ref: ""
target_release: "v2.1"
verified_at: ""
status_note: "后端 PR #8816 已合并 dev-v3(squash aad53d1fa3)。A 方案纯只读查询,零写、无 DDL、不碰资金;新增 2 个互查接口(对账→流水、流水→对账),部署 order-v3 后可用。"
updated_at: "2026-10-09"
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)