Files
junhong_cmp_fiber/openspec/changes/agent-recharges-payment-voucher/design.md
huang 6e15e1b853
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m26s
docs: 更新 OpenAPI 文档及提案任务清单,新增 payment_voucher_key 字段
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-17 18:29:42 +08:00

58 lines
2.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## Context
`POST /api/admin/agent-recharges` 是平台管理员为代理商创建线下充值订单的接口。当 `payment_method=offline` 时,代表平台已收到代理商的线下转账,此时应同步录入支付凭证(如银行转账截图的对象存储 key以便后续对账审计。
充值流程分两个阶段:
1. **创建阶段**`POST /api/admin/agent-recharges`):平台录入充值单 + 上传凭证
2. **确认阶段**`POST /api/admin/agent-recharges/:id/offline-pay`):财务二次确认,凭证已在创建时录入,无需重复上传
凭证文件本身通过已有的 `/storage/upload-url` 预签名 URL 上传至对象存储OSS后端仅存储 `file_key`
## Goals / Non-Goals
**Goals:**
- `Create` 接口在 `payment_method=offline` 时强制要求传入 `payment_voucher_key`
- 凭证 key 随充值记录一起写入数据库
- 响应 DTO 返回凭证 key 供前端展示
- `OfflinePay` 接口不做任何凭证相关改动
**Non-Goals:**
- 不涉及文件上传本身OSS 预签名链路已有)
- 不修改 `OfflinePay` 接口(财务确认流程独立于凭证管理)
- 不做凭证有效性验证(文件是否真实存在于 OSS
- `payment_method=wechat``payment_voucher_key` 无需传,应忽略
## Decisions
### 决策1凭证在创建时收集而非确认时
**选择**:在 `Create` 时收集凭证,因为平台管理员在录入线下充值单时就已持有转账凭证。
**理由**:线下充值的业务含义是"平台已收到转账,现在录入系统"。凭证是这次录入的必要信息。`OfflinePay` 是财务的二次确认操作,凭证应已在录入时保存,财务只负责审核确认。
### 决策2字段命名与 orders 保持一致
**选择**:使用 `payment_voucher_key`,与 `order.payment_voucher_key` 完全一致。
**理由**:统一命名降低认知负担,前端可复用同一组件。
### 决策3`wechat` 支付方式时字段可选
**选择**`payment_voucher_key` 使用 `validate:"omitempty,max=500"`,仅在 Service 层对 `offline` 方式做非空校验。
**理由**:微信在线支付无需凭证,不应因为加了字段就破坏微信支付的调用契约。
### 决策4凭证随 Create 直接写入
**选择**:在 `Create` 方法构建 `AgentRechargeRecord` 时直接赋值 `PaymentVoucherKey`,与记录创建同一个 `agentRechargeStore.Create()` 调用写入。
**理由**:凭证是充值记录的组成部分,不需要单独事务,最简路径。
## Risks / Trade-offs
**[风险] 历史记录无凭证**
→ 历史已创建的线下充值记录 `payment_voucher_key` 为空,属正常情况,不补录。
**[风险] 数据库迁移**
→ 新列 `VARCHAR(500)` 允许 NULL兼容历史数据新接口 Service 层对 `offline` 方式强制非空。迁移简单,无需锁表。