Some checks failed
Build docker and publish / linux (1.24.5) (push) Failing after 40s
feat(pay): 添加支付API基础结构 feat(miniapp): 创建支付测试小程序页面与配置 feat(wechatpay): 配置微信支付参数与证书 fix(guild): 修复成员列表查询条件 docs: 更新代码规范文档与需求文档 style: 统一前后端枚举显示与注释格式 refactor(admin): 重构用户奖励发放接口参数处理 test(title): 添加称号效果参数验证测试
6.1 KiB
6.1 KiB
目标
- 以微信支付 API v3 的真实流程实现:小程序 JSAPI 预下单→前端调起→支付回调验签与解密→订单推进→退款(全额/部分)→账单拉取与对账→管理端完整的订单/退款展示与操作。
- 严格按金额单位“分”、幂等与安全规范落地;所有敏感配置走环境变量与证书文件。
架构与分层
- Controller:
internal/api/*(app 用户态、admin 运营态、pay 通知态) - Service:
internal/service/pay/*(支付域核心:预下单、推进、退款、对账、状态机与幂等) - Repository:
internal/repository/mysql/*(新增支付域模型与 DAO,扩展索引) - PayClient:
internal/pkg/pay/*(微信官方 Go SDK client 初始化、回调验签与解密、账单下载) - Infra:配置与证书、日志、告警、幂等键与重试策略。
数据模型(新增表与索引)
payment_preorders
idPK、order_id、order_no(唯一)、channel(wechat_jsapi)、prepay_id、out_trade_no(唯一)、amount_total(分)、payer_openid、status(created/expired/paid)、notify_url、created_at、expired_at- 索引:
order_no唯一、out_trade_no唯一
payment_transactions
idPK、order_id、order_no(唯一)、channel、transaction_id(微信流水号唯一)、amount_total、success_time、raw(JSON)、created_at- 索引:
transaction_id唯一、order_no唯一
payment_refunds
idPK、order_id、order_no、refund_no(唯一)、channel、status(submitted/success/abnormal/closed)、amount_refund(分)、reason、success_time、raw(JSON)、created_at- 索引:
refund_no唯一、order_no索引
payment_notify_events
idPK、notify_id(唯一)、resource_type、event_type、summary、raw(JSON)、processed(bool)、created_at- 索引:
notify_id唯一
payment_bills/payment_bill_diff
- 账单拉取与差异记录,支持日级对账
- 订单表约束
orders.order_no唯一索引;基于现有字段建立缺失索引
配置与证书
- 环境变量:
WECHAT_APPID/WECHAT_MCHID/WECHAT_SERIAL_NO/WECHAT_PRIVATE_KEY_PATH/WECHAT_API_V3_KEY/WECHAT_NOTIFY_URL - 证书路径:
./configs/cert/apiclient_key.pem(商户私钥);平台证书走 SDK 自动下载与缓存(WithWechatPayAutoAuthCipher),无需入库 - 不提交任何密钥与证书文件到仓库
SDK与真实流程
- 预下单(JSAPI):
- 初始化 client:
option.WithWechatPayAutoAuthCipher(mchid, serial_no, private_key, api_v3_key) - 调用
services/payments/jsapi.JsapiApiService.Prepay(或PrepayWithRequestPayment)生成prepay_id - 使用四行签名串 RSA-SHA256 构造小程序
wx.requestPayment参数 - 落库
payment_preorders与out_trade_no=order_no幂等
- 支付回调(notify):
- 使用
notify.NewNotifyHandler(api_v3_key, NewSHA256WithRSAVerifier(certificateVisitor))验签并解密得到payments.Transaction - 幂等:
notify_id去重;如已处理直接 ACK - 状态推进:
WHERE status=1条件更新订单为已支付,写入payment_transactions,记录交易时间与原始报文 - 失败场景兜底:按
out_trade_no定时查询交易状态
- 退款(真实):
- 管理端创建退款:生成
refund_no并调用 SDKservices/refunddomestic(具体路径以官方包为准),成功回写payment_refunds与回调推进;支持部分/全额退款 - 数据还原:积分恢复按策略记录
user_points_ledger(action=refund_restore);订单全额退款置status=4,部分退款保持status=2并维护累计退款 - 幂等:
refund_no唯一;重复请求返回已有结果
- 对账:
- 下载交易/退款账单
GET /v3/bill;入库payment_bills;比对本地payment_transactions/payment_refunds生成payment_bill_diff;支持导出与修复流程
后端接口(最终版)
- App:
POST /api/app/pay/wechat/jsapi/preorder(真实预下单,返回调起参数)GET /api/app/orders/:order_no/payment(查询支付状态)
- Pay通知:
POST /api/pay/wechat/notify(真实验签与解密,推进订单与交易)
- Admin:
- 订单列表/详情/备注/取消/履约(已实现基础版,依据真实交易补充支付字段)
POST /api/admin/pay/refunds(真实退款)/查询退款列表与详情- 导出与对账入口:
GET /api/admin/pay/orders/export、POST /api/admin/pay/bills/import
前端管理端(orders模块)
- 列表与详情中文枚举显示(已完成基础);补充:展示真实
transaction_id、refund_no、channel、支付方式 - 退款入口:支持部分退款(金额/原因),显示可退余额;展示退款记录(来源
payment_refunds) - 对账入口:载入对账结果与差异列表
幂等与安全
- 业务幂等键:
order_no(预下单/订单推进)、notify_id(回调)、refund_no(退款) - 事务:Service 层统一事务包裹;状态推进以条件更新控制并发
- 日志与告警:回调验签失败、金额不一致、退款异常、对账差异均告警
测试与验收
- 单元:签名参数构造、金额边界、幂等推进、退款全额/部分、回调解析
- 集成:模拟回调事件、订单查询兜底、账单导入与差异比对
- 验收标准:
- 小程序支付全链路通;订单与交易记录准确;
- 管理端退款成功并正确落账与还原;
- 对账拉取与差异比对可用;
- 漏斗“支付用户/完成订单”口径对齐真实交易。
实施阶段
- 数据库与DAO:新增
payment_*表与索引;生成模型与DAO - SDK接入:统一初始化 client;预下单返回参数;notify 验签与解密;退款API封装
- 业务实现:订单推进、幂等、退款落账与数据还原
- 前端完善:展示交易/退款字段、可退余额、退款记录;对账入口
- 测试与联调:完成单元与集成测试;灰度上线观测
依赖
- 官方 Go SDK:
github.com/wechatpay-apiv3/wechatpay-go(API v3) - 证书:商户私钥 PEM;平台证书自动下载与缓存