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): 添加称号效果参数验证测试
7.1 KiB
7.1 KiB
目标与范围
- 目标:落地微信小程序(JSAPI)支付,完善后台订单管理与退款闭环,支持对账与运营漏斗统计。
- 范围:预下单→前端调起→支付回调→订单状态推进→退款申请/执行→账单对账→后台运营管理。
背景与现状
- 已有:订单/订单项/积分流水/工作台漏斗统计与请求日志。
- 工作台漏斗接口:
internal/api/admin/dashboard_admin.go:754;路由:internal/router/router.go:72。 - 用户订单查询:
internal/service/user/orders_list.go:16/40;系统发放订单与订单号生成:internal/service/user/reward_grant.go:76/220。
- 工作台漏斗接口:
- 缺失:微信支付接入(预下单、SDK、证书/签名)、支付回调与幂等、退款接口与模型、对账流程、订单唯一约束与支付幂等、防重复回调处理。
总体架构
- 分层:Controller(HTTP) → Service(业务/状态机) → Repository(Gorm/DAO) → PayClient(微信支付SDK) → Infra(配置、证书、日志、幂等/锁)。
- 关键域:
- 订单域:
orders/order_items维持业务订单与行项目。 - 支付域:新增
payment_preorders/payment_transactions/payment_refunds/payment_notify_events/payment_bills。 - 记账域:
user_points_ledger扩展退款恢复落账。
- 订单域:
数据模型设计
payment_preorders预下单记录id、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。
payment_transactions支付成功交易id、order_id、order_no(唯一) 、channel、transaction_id(微信流水号唯一) 、amount_total、success_time、raw(JSON) 、created_at。
payment_refunds退款记录id、order_id、order_no、refund_no(唯一) 、channel、status(submitted/success/abnormal/closed) 、amount_refund(分/支持部分退款) 、reason、raw(JSON) 、created_at、success_time。
payment_notify_events回调事件id、notify_id(唯一) 、resource_type、event_type、summary、raw(JSON) 、processed(bool) 、created_at。
payment_bills/payment_bill_diff对账与差异bill_date、type(tradebill/refundbill) 、file_url、digest、imported;差异记录local_tx_id/wechat_tx_id/diff_type/diff_detail。
- 约束与索引:
orders.order_no唯一索引;payment_*关键幂等字段唯一索引;notify_id/out_trade_no/transaction_id/refund_no均唯一。
接口设计
- App(用户态)
POST /api/app/pay/wechat/jsapi/preorder:入参order_no/openid,出参timeStamp/nonceStr/package(pay=prepay_id)/signType/paySign。GET /api/app/orders/:order_no/payment:查询订单支付状态与交易详情。
- Pay通知(平台回调)
POST /api/pay/wechat/notify:验签/解密后入库payment_notify_events,幂等推进订单状态,写payment_transactions,更新orders.status=2/paid_at。
- Admin(运营态)
GET /api/admin/pay/orders:订单列表(筛选:状态、时间、渠道)。POST /api/admin/pay/refunds:创建退款,入参order_no/amount/reason;支持全/部分退款。GET /api/admin/pay/refunds/GET /api/admin/pay/refunds/:refund_no:查询退款状态。POST /api/admin/orders/:order_no/close:关闭未支付订单(同时调用微信close)。- 漏斗统计继续沿用现有接口,支付口径改为“支付交易成功”(来源于transactions)。
业务流程
- 预下单(JSAPI)
- 校验订单
status=1与金额,绑定openid→调用/v3/pay/transactions/jsapi→落库payment_preorders并返回客户端调起参数。参考“JSAPI预下单与签名串”[微信支付文档]。
- 校验订单
- 前端调起
- 小程序端
wx.requestPayment使用服务端返回的timeStamp/nonceStr/package/signType/paySign。
- 小程序端
- 支付回调
- 后端接收
notify→验签(平台证书)与解密→事件幂等检查(notify_id)→查询交易状态或直接推进→更新orders为已支付,写payment_transactions与触发履约逻辑(虚拟商品使用is_consumed)。
- 后端接收
- 失败重试
- 回调验签失败/解密失败→告警并拒收;订单未推进→后台定时查询
/v3/pay/transactions/out-trade-no/{out_trade_no}兜底。
- 回调验签失败/解密失败→告警并拒收;订单未推进→后台定时查询
- 退款
- 管理端创建退款→调用
/v3/refund/domestic/refunds→落库payment_refunds→回调/查询成功后更新为success并写user_points_ledger(action=refund_restore)与订单状态4已退款(支持部分退款:订单保持2已支付,以累计退款判断)。
- 管理端创建退款→调用
- 对账
- 每日拉取交易/退款账单→入库
payment_bills→与本地payment_transactions/payment_refunds比对→生成差异payment_bill_diff→运营报表与修复。
- 每日拉取交易/退款账单→入库
幂等与一致性
- 订单:
order_no唯一;预下单多次返回同一prepay_id;使用out_trade_no=order_no作为业务幂等键。 - 回调:
notify_id去重;状态推进使用原子事务与“当前状态→新状态”的校验。 - 退款:
refund_no唯一;重复请求直接返回现有状态。 - 事务:Service层统一开启Gorm事务;对并发推进加行级乐观锁或显式
UPDATE ... WHERE status=...。
配置与密钥管理
.env加载:WECHAT_APPID/WECHAT_MCHID/WECHAT_SERIAL_NO/WECHAT_PRIVATE_KEY_PATH/WECHAT_API_V3_KEY/WECHAT_NOTIFY_URL。- 证书:落盘PEM私钥与平台证书;SDK负责签名与应答验签。禁止将密钥提交仓库。
SDK选型与规范
- 后端Go采用官方
/wechatpay-apiv3/wechatpay-go(API v3,支持签名/验签/回调解密)。 - 按微信文档“JSAPI签名串四行格式与RSA签名”构造客户端参数。
安全与合规
- 验签必做;来源白名单;请求体原样落库审计。
- 金额单位统一“分”;防止小数误差;禁止信任前端金额。
- 日志与告警:失败重试/签名失败/金额不一致必须告警。
测试与验收
- 单元:签名参数构造、金额边界、幂等推进、退款部分/全额。
- 集成:模拟回调事件、订单查询兜底、对账导入与差异比对。
- 验收标准:
- 小程序端正常拉起并支付成功,后台订单状态正确推进;
- 管理端可发起退款并正确落账;
- 回调/对账全链路无漏处理且有幂等保障;
- 漏斗“支付用户/完成订单”口径与交易/发货一致。
实施步骤
- 引入微信支付Go SDK与配置加载,建立PayClient与证书管理。
- 建表与唯一索引:
orders.order_no、payment_*系列关键字段唯一。 - 实现预下单接口,返回前端调起参数并记录
payment_preorders。 - 实现支付回调路由:验签/解密→事件入库→幂等推进订单与交易记录。
- 实现退款接口与回调处理;联动
user_points_ledger落账。 - 实现对账拉取与差异比对;补充运营漏斗统计数据来源为交易表。
- 覆盖测试与监控告警;上线灰度并观察。
参考文档(已核对)
- JSAPI预下单与签名串、调起参数与
prepay_id有效期:/websites/pay_weixin_qq_doc_v3 - 官方Go SDK:
/wechatpay-apiv3/wechatpay-go