17 KiB
📝【契约纠正·管理后台】对公转账不需要代收人 (#5120)
变更性质:现有接口契约澄清 + 历史文档示例纠错|端类型:管理后台|更新日期:2026-07-21
本次没有发布新的后端字段、枚举或行为变更;下文说明接口已有的稳定契约。
1. 接口背景
管理后台在“登记线下收款”中选择“对公转账”后仍显示“代收人”,与当前接口契约不一致。对公转账不由某位员工代收,只需填写转账流水号;代收人仅在“报账人收款”渠道下需要选择。
2026-07-10 的历史通知曾在示例中给 BANK_TRANSFER.collectors 放入“公司账户”对象,该示例与实际响应不符,本次一并纠正为空数组。
2. 变更清单
| # | 方法 | 路径 | 通知类型 | 说明 |
|---|---|---|---|---|
| 1 | GET | /v3/admin/order/{orderId}/payment/manual-receipt/options |
契约澄清 | BANK_TRANSFER.collectors 始终为 [];各渠道使用各自的候选项 |
| 2 | POST | /v3/admin/order/{orderId}/payment/manual-receipt |
契约澄清 | collectorStaffId 仅对 DRIVER_CASH 条件必填;BANK_TRANSFER 条件必填 transferRef |
| 3 | 文档 | 2026-07/10_4884_线下收款代收人-修改接口-管理后台.md |
示例纠错 | 将对公转账的错误 collectors 对象改为 [] |
3. 接口详情
3.1 查询线下收款选项
- 方法与路径:
GET /v3/admin/order/{orderId}/payment/manual-receipt/options - 使用场景:打开登记线下收款表单时,查询当前订单可用的渠道、款项类型、代收人和收款方式。
- 认证:需要管理后台 JWT。
- 幂等性:幂等,只读查询。
- 限流:无接口专属限流规则。
3.2 登记线下收款
- 方法与路径:
POST /v3/admin/order/{orderId}/payment/manual-receipt - 使用场景:按 options 当前返回的可用渠道和款项类型登记一笔线下收款。
- 认证:需要管理后台 JWT。
- 幂等性:非幂等,每次成功请求会新增一条收款记录。
- 限流:无接口专属限流规则。
4. 接口入参
4.1 路径参数(两个接口通用)
| 字段 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
orderId |
Path | String(Long) | 是 | 订单 ID,按字符串处理 |
GET 接口无 Query 参数、无请求体。
4.2 POST 请求体
| 字段 | 类型 | 必填 | 说明 | 校验规则 |
|---|---|---|---|---|
channel |
String | 是 | 收款渠道 | DRIVER_CASH / BANK_TRANSFER / CONSULTANT_COLLECTION |
payType |
String | 是 | 款项类型 | 必须取 options 中当前渠道的 allowedPayTypes |
amount |
Decimal | 是 | 收款金额 | 最小 0.01,不能超过当前可收余额 |
receivedAt |
String(LocalDateTime) | 否 | 收款时间 | yyyy-MM-dd'T'HH:mm:ss;不传默认当前时间 |
transferRef |
String | 条件必填 | 对公转账流水号 | BANK_TRANSFER 必填,其他渠道不使用 |
receiptMethod |
String | 否 | 收款方式 | 取当前渠道 receiptMethods[].value;BANK_TRANSFER 为空 |
collectorStaffId |
String(Long) | 条件必填 | 代收人 assignmentId | 仅 DRIVER_CASH 必填,且必须取当前渠道 collectors[].collectorId |
collectorType |
String | 否 | 实际代收人类型 | 不传时按 channel 推导;如传入,必须与渠道匹配 |
voucherUrls |
Array | 否 | 凭证图片 URL 列表 | 可为空数组或不传 |
remark |
String | 否 | 备注 | 最长 500 字 |
4.3 渠道联动必填矩阵
channel |
collectorStaffId |
collectorType |
transferRef |
代收人规则 |
|---|---|---|---|---|
BANK_TRANSFER |
不需要;误传也不作为员工代收人处理 | 可不传;如传只能为 COMPANY_ACCOUNT |
必填 | 不选择任何员工,公司账户是收款归属而非代收人候选项 |
CONSULTANT_COLLECTION |
不需要 | 可不传;如传只能为 CONSULTANT |
不需要 | 使用订单定制师,不使用员工选择器 |
DRIVER_CASH |
必填 | 可不传;如传只能为 ORDER_STAFF |
不需要 | 仅能选当前订单 options 返回的有效报账人 |
5. 出参(响应)
5.1 通用响应包装
| 字段 | 类型 | 说明 |
|---|---|---|
code |
Integer | 200 表示成功,其他值为业务错误码 |
message |
String | 结果或错误说明 |
data |
Object/null | 业务数据;失败时通常为 null |
success |
Boolean | 是否成功 |
5.2 GET options 的 data
| 字段 | 类型 | 说明 |
|---|---|---|
channels |
Array | 当前订单的线下收款渠道列表 |
channels[].channel |
String | 渠道枚举值 |
channels[].channelText |
String | 渠道展示文案 |
channels[].allowedPayTypes |
Array | 当前订单状态下该渠道允许的款项类型;以本次响应为准 |
channels[].disabled |
Boolean | true 表示当前不可提交该渠道 |
channels[].disabledReason |
String/null | 禁用原因;可用时为 null |
channels[].collectors |
Array | 该渠道自己的代收人候选列表;BANK_TRANSFER 为 [] |
channels[].receiptMethods |
Array | 该渠道可选收款方式;BANK_TRANSFER 为 [] |
collectors[].collectorType |
String | 代收人类型 |
collectors[].collectorId |
String(Long) | ORDER_STAFF 为 assignmentId,CONSULTANT 为管理员 ID |
collectors[].collectorName |
String | 代收人姓名 |
collectors[].collectorRole |
String | 代收人角色值 |
collectors[].collectorRoleText |
String | 代收人角色文案 |
collectors[].defaultSelected |
Boolean | 是否默认选中 |
receiptMethods[].value |
String | 收款方式值 |
receiptMethods[].label |
String | 收款方式文案 |
receiptMethods[].defaultSelected |
Boolean | 是否默认选中 |
5.3 POST 的 data
| 字段 | 类型 | 说明 |
|---|---|---|
id |
String(Long) | 收款凭据 ID |
orderId |
String(Long) | 订单 ID |
channel / channelLabel |
String | 收款渠道值 / 文案 |
payType / payTypeLabel |
String | 款项类型值 / 文案 |
amount |
Decimal | 本次收款金额 |
receivedAt |
String(LocalDateTime) | 收款时间 |
collectorStaffId / collectorStaffName |
String(Long)/String/null | 仅 DRIVER_CASH 有值 |
collectorType |
String | 实际代收人类型 |
collectorAdminId |
String(Long)/null | CONSULTANT_COLLECTION 为定制师管理员 ID |
collectorName / collectorRole |
String | 代收归属快照名称 / 角色 |
transferRef |
String/null | 对公转账流水号,仅 BANK_TRANSFER 有值 |
receiptMethod / receiptMethodLabel |
String/null | 收款方式值 / 文案;BANK_TRANSFER 为空 |
voucherUrls |
Array | 凭证图片 URL 列表 |
remark |
String/null | 备注 |
operatorName |
String | 登记人姓名 |
createTime |
String(LocalDateTime) | 登记时间 |
voided |
Boolean | 是否已撤销;新登记为 false |
voidedByName / voidedAt / voidReason |
String/null | 撤销信息;新登记时为 null |
paidAmountAfter |
Decimal | 登记后订单累计已付金额 |
payStatusAfter |
String | 登记后订单支付状态 |
6. 枚举 / 数据字典
6.1 channel
所属字段:channel / channels[].channel|类型:String
| 值 | 中文 | 说明 |
|---|---|---|
BANK_TRANSFER |
对公转账 | 无员工代收人,必须填 transferRef |
CONSULTANT_COLLECTION |
定制师代收 | 使用订单定制师,不传 collectorStaffId |
DRIVER_CASH |
报账人收款 | 仅允许尾款,必须从本渠道 collectors 选择代收人 |
6.2 payType
所属字段:payType / channels[].allowedPayTypes[]|类型:String
| 值 | 中文 | 说明 |
|---|---|---|
DEPOSIT |
订金 | 是否可登记以 options 当前返回为准 |
FULL |
全款 | 是否可登记以 options 当前返回为准 |
BALANCE |
尾款 | 是否可登记以 options 当前返回为准;DRIVER_CASH 只允许此值 |
BANK_TRANSFER的通用契约可支持DEPOSIT/FULL/BALANCE,但具体订单当次能提交哪些值,必须以 options 的allowedPayTypes为准,不要将某个实例的BALANCE硬编码为全局规则。
6.3 collectorType
所属字段:collectorType / collectors[].collectorType|类型:String
| 值 | 中文 | 匹配渠道 |
|---|---|---|
COMPANY_ACCOUNT |
公司账户 | BANK_TRANSFER |
CONSULTANT |
定制师 | CONSULTANT_COLLECTION |
ORDER_STAFF |
订单工作人员 | DRIVER_CASH |
6.4 receiptMethod
所属字段:receiptMethod / receiptMethods[].value|类型:String
| 值 | 中文 | 说明 |
|---|---|---|
WECHAT_TRANSFER |
微信转账 | 人员代收渠道的当前默认字典值 |
CASH |
现金收款 | 人员代收渠道的当前默认字典值 |
BANK_TRANSFER.receiptMethods=[];该字典可扩展,实际可选值以 options 当次返回为准。
6.5 payStatusAfter
所属字段:POST 响应 payStatusAfter|类型:String
| 值 | 中文 | 说明 |
|---|---|---|
UNPAID |
未付款 | 尚未完成有效收款 |
DEPOSIT_PAID |
已付订金 | 订金已收 |
FULLY_PAID |
已付全款 | 应收金额已收齐 |
7. 错误码
| code | message / 含义 | 触发场景 |
|---|---|---|
520011 |
支付类型无效或与订单状态不匹配 | payType 不在当前 options 允许范围内 |
520401 |
收款渠道非法 | channel 不在三个渠道枚举中 |
520402 |
对公转账渠道必须填写转账流水号 | BANK_TRANSFER 未传 transferRef |
520403 |
报账人收款渠道必须指定代收人 | DRIVER_CASH 未传 collectorStaffId |
520404 |
代收人不属于本订单人员 | collectorStaffId 不是本订单有效人员 |
520407 |
订单已取消,不允许登记线下收款 | 已取消订单提交 POST |
520408 |
收款金额必须大于 0 | amount < 0.01 |
520409 |
线下收款代收人类型非法 | collectorType 与 channel 不匹配 |
520410 |
报账人收款只能登记尾款 | DRIVER_CASH 提交 DEPOSIT 或 FULL |
520411 |
报账人收款必须选择本订单报账人 | 选中的订单人员不是报账人 |
520412 |
订单没有可用定制师,不能登记定制师代收 | CONSULTANT_COLLECTION 无可用定制师 |
520413 |
本次收款金额超过当前可收余额 | amount 大于当前可收金额 |
8. 示例(典型 + 边界 + 异常)
8.1 典型:查询选项,对公转账无代收人
请求:
GET /v3/admin/order/2079454953641836546/payment/manual-receipt/options
Authorization: Bearer <admin-jwt>
无请求体
响应:
{
"code": 200,
"message": "操作成功",
"data": {
"channels": [
{
"channel": "CONSULTANT_COLLECTION",
"channelText": "定制师代收",
"allowedPayTypes": ["BALANCE"],
"disabled": false,
"disabledReason": null,
"collectors": [
{
"collectorType": "CONSULTANT",
"collectorId": "2037350531801993218",
"collectorName": "张三",
"collectorRole": "CONSULTANT",
"collectorRoleText": "定制师",
"defaultSelected": true
}
],
"receiptMethods": [
{"value": "WECHAT_TRANSFER", "label": "微信转账", "defaultSelected": true},
{"value": "CASH", "label": "现金收款", "defaultSelected": false}
]
},
{
"channel": "BANK_TRANSFER",
"channelText": "对公转账",
"allowedPayTypes": ["BALANCE"],
"disabled": false,
"disabledReason": null,
"collectors": [],
"receiptMethods": []
},
{
"channel": "DRIVER_CASH",
"channelText": "报账人收款",
"allowedPayTypes": [],
"disabled": true,
"disabledReason": "本订单暂无可代收报账人",
"collectors": [],
"receiptMethods": [
{"value": "WECHAT_TRANSFER", "label": "微信转账", "defaultSelected": true},
{"value": "CASH", "label": "现金收款", "defaultSelected": false}
]
}
]
},
"success": true
}
8.2 边界:对公转账不传代收人
场景说明:collectorStaffId 和 collectorType 都不传;仅提交 options 当前允许的款项类型与对公转账流水号。
请求:
POST /v3/admin/order/2079454953641836546/payment/manual-receipt
Authorization: Bearer <admin-jwt>
Content-Type: application/json
{
"channel": "BANK_TRANSFER",
"payType": "BALANCE",
"amount": 100.00,
"transferRef": "BANK202607210001",
"voucherUrls": [],
"remark": "客户对公转账"
}
响应:
{
"code": 200,
"message": "操作成功",
"data": {
"id": "2079600000000000001",
"orderId": "2079454953641836546",
"channel": "BANK_TRANSFER",
"channelLabel": "对公转账",
"payType": "BALANCE",
"payTypeLabel": "尾款",
"amount": 100.00,
"receivedAt": "2026-07-21T15:30:00",
"collectorStaffId": null,
"collectorStaffName": null,
"collectorType": "COMPANY_ACCOUNT",
"collectorAdminId": null,
"collectorName": "公司账户",
"collectorRole": "COMPANY_ACCOUNT",
"transferRef": "BANK202607210001",
"receiptMethod": null,
"receiptMethodLabel": null,
"voucherUrls": [],
"remark": "客户对公转账",
"operatorName": "管理员",
"createTime": "2026-07-21T15:30:00",
"voided": false,
"voidedByName": null,
"voidedAt": null,
"voidReason": null,
"paidAmountAfter": 1600.00,
"payStatusAfter": "DEPOSIT_PAID"
},
"success": true
}
8.3 异常:报账人收款未选择代收人
请求:
POST /v3/admin/order/2079454953641836546/payment/manual-receipt
Authorization: Bearer <admin-jwt>
Content-Type: application/json
{
"channel": "DRIVER_CASH",
"payType": "BALANCE",
"amount": 100.00,
"receiptMethod": "CASH"
}
响应:
{
"code": 520403,
"message": "报账人收款渠道必须指定代收人",
"data": null,
"success": false
}
9. 业务边界
collectors是每个 channel 自己的候选列表,不是所有渠道共用的必选列表。BANK_TRANSFER:collectors=[],不传collectorStaffId,必须传transferRef;即使误传collectorStaffId,响应中员工代收人 ID 仍为空。CONSULTANT_COLLECTION:不要提交collectorStaffId;当订单没有可用定制师时,渠道禁用。DRIVER_CASH:仅允许BALANCE,必须传当前订单有效报账人的 assignmentId。- options 的
allowedPayTypes随订单状态和可收余额变化。待支付订单中,对公转账/定制师代收可返回DEPOSIT、FULL;非待支付且仍有可收余额时可返回BALANCE。 - 渠道
disabled=true或allowedPayTypes=[]时,当前不可提交该渠道。 - 已取消订单、无可收余额的订单不能登记线下收款。
10. 修改前后对比
本节对比的是“错误理解 / 错误文档示例”与“正确的现有契约”,不表示后端今日发布了新的接口变更。
| 项目 | 错误理解 / 历史错误示例 | 正确契约 |
|---|---|---|
| 对公转账的代收人候选 | BANK_TRANSFER.collectors 含“公司账户”对象 |
BANK_TRANSFER.collectors=[] |
collectorStaffId 字段 |
所有渠道都要选代收人,或该字段已从后端删除 | 字段仍保留,仅 DRIVER_CASH 条件必填 |
| 对公转账必填项 | 代收人 | transferRef 转账流水号 |
| 定制师代收 | 复用员工代收人选择器并传 collectorStaffId |
不要传 collectorStaffId,使用订单定制师 |
| 对公转账款项类型 | 固定只能是某一种款项 | 以 options 当前返回的 allowedPayTypes 为准 |
11. 影响评估 / 回滚
11.1 影响评估
- 是否破坏向后兼容:否。后端字段、枚举和行为没有变更。
- 前端是否必须同步上线:是。已有页面在
BANK_TRANSFER下显示代收人,需要按正确契约纠正。
11.2 回滚说明
- 本次仅修正通知文档,不涉及后端接口回滚。
- 若前端回滚渠道联动修正,对公转账将再次错误显示代收人。
12. 注意事项
- 选中
BANK_TRANSFER时,隐藏代收人选择器,并清空从其他渠道切换前残留的collectorStaffId。 - 选中
BANK_TRANSFER时,显示并校验transferRef,不要根据统一响应结构中“存在collectors字段”就认定代收人必选。 - 仅
DRIVER_CASH把collectorStaffId设为必填,候选项取当前 channel 的collectors。 CONSULTANT_COLLECTION不要复用DRIVER_CASH的员工代收人校验。- 不要把测试订单中
BANK_TRANSFER.allowedPayTypes=["BALANCE"]固化为全局规则;每次均以 options 返回为准。
13. 关联 / 联系人
13.1 关联
- Issue:#5120
- 后端 PR:无(本次无后端代码变更)
- 后端 commit:无(本次无后端代码变更)
13.2 联系人
- 后端负责人:腰苏图