维护说明:本文档已并入本站直接维护(单仓重构后原 backend/docs/*.md、前端 docs/*.md 不再随仓库发布)。
实现细节以 pay-unify 源码 为准,页面与源码的对应关系见相关资源。
统一支付接口说明
⚠️ 认证已迁移为 OAuth2:/api/v2/* 用 Bearer token(POST /oauth/token 换取),
/api/v1/* 用管理员 JWT。本文中的 GoAuth/X-Sign 示例均为旧写法,已替换。
功能概述
已将支付宝和微信的关闭订单、申请退款接口合并为统一接口,通过订单的支付方式自动路由到对应的处理逻辑。
优势
✅ 统一API设计 - 一个接口支持所有支付方式
✅ 自动识别 - 根据订单支付方式自动调用对应服务
✅ 向后兼容 - 保留原有专用接口
✅ 易于扩展 - 新增支付方式只需添加case分支
✅ 减少维护 - 统一的业务逻辑和错误处理
新增统一接口
1. 关闭订单(统一接口)
接口路径:
POST /api/v1/payment/close/{outTradeNo}
POST /api/v2/payment/close/{outTradeNo}
功能说明:
- 自动识别订单的支付方式(支付宝/微信)
- 调用对应的关闭订单接口
- 更新订单状态为已关闭
请求参数:
- Path参数:
outTradeNo - 商户订单号
请求头:
Authorization: Bearer <access_token>
响应示例:
1{
2 "code": 0,
3 "message": "success",
4 "data": {
5 "message": "订单关闭成功",
6 "orderNo": "202501091234567890",
7 "payWay": "alipay"
8 }
9}
2. 申请退款(统一接口)
接口路径:
POST /api/v1/payment/refund
POST /api/v2/payment/refund
功能说明:
- 自动识别订单的支付方式(支付宝/微信)
- 调用对应的退款接口
- 支持自定义退款金额
- 自动处理金额单位转换(微信分/支付宝元)
请求参数:
1{
2 "outTradeNo": "202501091234567890", // 商户订单号(必填)
3 "refundAmount": 0.01, // 退款金额-元(必填)
4 "refundReason": "用户申请退款" // 退款原因(可选)
5}
请求头:
Authorization: Bearer <access_token>
响应示例:
1{
2 "code": 0,
3 "message": "success",
4 "data": {
5 "message": "退款申请成功",
6 "orderNo": "202501091234567890",
7 "payWay": "alipay",
8 "tradeNo": "2025123122001234567890",
9 "refundAmount": 0.01,
10 "refundRequestNo": "R1234567890123456789",
11 "result": null
12 }
13}
旧专用接口(已下线)
早期版本提供的支付宝 / 微信专用接口(payment/alipay/*、payment/wechat/*)
已在当前实现中注释下线,路由不再注册。请统一使用上面的 payment/close、payment/refund 接口。
源码位置:backend/internal/handler/payment_handler.go(专用路由已被注释)。
实现原理
关闭订单流程
1. 验证应用身份
↓
2. 查询订单信息
↓
3. 检查订单状态
↓
4. 根据 payWay 字段判断
├─ alipay → 调用 AlipayService.TradeClose()
└─ wechat → 调用 WechatPayService.CloseOrder()
↓
5. 更新订单状态为已关闭
退款流程
1. 验证应用身份
↓
2. 查询订单信息
↓
3. 检查订单状态和退款金额
↓
4. 生成唯一退款请求号
↓
5. 根据 payWay 字段判断
├─ alipay → 调用 AlipayService.TradeRefund()
│ 参数:金额单位为元
└─ wechat → 调用 WechatPayService.Refund()
参数:金额单位为分(自动转换)
↓
6. 更新订单状态为已退款
核心代码
关闭订单
1// 根据支付方式调用不同的关闭接口
2switch order.PayWay {
3case "alipay":
4 err = h.alipayService.TradeClose(outTradeNo)
5case "wechat":
6 result := h.WechatPayService.CloseOrder(outTradeNo)
7default:
8 return error("不支持的支付方式")
9}
申请退款
1// 根据支付方式调用不同的退款接口
2switch order.PayWay {
3case "alipay":
4 // 支付宝:金额单位为元
5 tradeNo, err = h.alipayService.TradeRefund(AlipayRefundParams{
6 RefundAmount: req.RefundAmount, // 元
7 })
8case "wechat":
9 // 微信:金额单位为分,需要转换
10 refundFee := int(req.RefundAmount * 100) // 元转分
11 result, err = h.WechatPayService.Refund(WechatRefundParams{
12 RefundFee: refundFee, // 分
13 })
14}
使用示例
统一关闭订单
1# 先换 Bearer token
2TOKEN=$(curl -s -X POST http://localhost:8097/oauth/token \
3 -H 'Content-Type: application/json' \
4 -d '{"grant_type":"client_credentials","client_id":"your-client-id","client_secret":"your-secret"}' \
5 | jq -r .access_token)
6
7# 关闭支付宝订单
8curl -X POST 'http://localhost:8097/api/v2/payment/close/202501091234567890' \
9 -H "Authorization: Bearer $TOKEN"
10
11# 关闭微信订单(相同接口)
12curl -X POST 'http://localhost:8097/api/v2/payment/close/202501099876543210' \
13 -H "Authorization: Bearer $TOKEN"
统一申请退款
1# 支付宝退款
2curl -X POST 'http://localhost:8097/api/v2/payment/refund' \
3 -H 'Content-Type: application/json' \
4 -H "Authorization: Bearer $TOKEN" \
5 -d '{
6 "outTradeNo": "202501091234567890",
7 "refundAmount": 0.01,
8 "refundReason": "用户申请退款"
9 }'
10
11# 微信退款(相同接口,相同参数格式)
12curl -X POST 'http://localhost:8097/api/v2/payment/refund' \
13 -H 'Content-Type: application/json' \
14 -H "Authorization: Bearer $TOKEN" \
15 -d '{
16 "outTradeNo": "202501099876543210",
17 "refundAmount": 1.00,
18 "refundReason": "商品质量问题"
19 }'
接口对比
| 功能 |
旧专用接口(已下线) |
统一接口 |
说明 |
| 关闭支付宝订单 |
payment/alipay/close/:id |
payment/close/:id |
统一接口 |
| 关闭微信订单 |
payment/wechat/close/:id |
payment/close/:id |
统一接口 |
| 支付宝退款 |
payment/alipay/refund |
payment/refund |
统一接口 |
| 微信退款 |
payment/wechat/refund |
payment/refund |
统一接口 |
扩展支持新支付方式
如需添加新的支付方式(如PayPal),只需:
1. 在关闭订单接口添加case:
1case "paypal":
2 err = h.PaypalService.CloseOrder(outTradeNo)
2. 在退款接口添加case:
1case "paypal":
2 result, err = h.PaypalService.Refund(PaypalRefundParams{
3 OutTradeNo: req.OutTradeNo,
4 RefundAmount: req.RefundAmount, // 根据PayPal要求的单位
5 RefundReason: req.RefundReason,
6 })
注意事项
1. 金额单位处理
- 统一接口输入:金额单位为元(float64)
- 支付宝:金额单位为元,直接使用
- 微信:金额单位为分,需要转换(元 × 100)
2. 向后兼容
- 旧的专用接口仍然可用
- 建议新项目使用统一接口
- 逐步迁移旧项目到统一接口
3. 错误处理
- 统一的错误响应格式
- 详细的错误日志记录
- 返回支付方式信息便于调试
4. 权限验证
- 所有接口均需 OAuth2 Bearer 认证(
POST /oauth/token 换取,见认证体系)
- 自动验证订单归属权
- 只能操作本应用的订单
API文档
访问 Swagger 文档查看完整 API 定义:
- 开发环境:
http://localhost:8097/swagger/index.html
- 搜索关键词:
payment/close 或 payment/refund
相关文件
均在 backend/ 下:
internal/handler/payment_handler.go - 统一接口实现
internal/pkg/service/payment/alipay_service.go - 支付宝服务
internal/pkg/service/payment/wepay_service.go - 微信服务
更新日期: 2025-12-31
版本: v1.0
状态: 已完成并部署