bindbox-game/.trae/documents/小程序支付与后台订单_退款设计.md
邹方成 6ee627139c
Some checks failed
Build docker and publish / linux (1.24.5) (push) Failing after 40s
feat: 新增支付测试小程序与微信支付集成
feat(pay): 添加支付API基础结构
feat(miniapp): 创建支付测试小程序页面与配置
feat(wechatpay): 配置微信支付参数与证书
fix(guild): 修复成员列表查询条件
docs: 更新代码规范文档与需求文档
style: 统一前后端枚举显示与注释格式
refactor(admin): 重构用户奖励发放接口参数处理
test(title): 添加称号效果参数验证测试
2025-11-17 00:42:08 +08:00

7.1 KiB
Raw Blame History

目标与范围

  • 目标:落地微信小程序(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 预下单记录
    • idorder_idorder_no(唯一) 、channel(wechat_jsapi)、prepay_idout_trade_no(唯一)、amount_total(分)、payer_openidstatus(created/expired/paid)、notify_urlcreated_atexpired_at
  • payment_transactions 支付成功交易
    • idorder_idorder_no(唯一) 、channeltransaction_id(微信流水号唯一) 、amount_totalsuccess_timeraw(JSON) 、created_at
  • payment_refunds 退款记录
    • idorder_idorder_norefund_no(唯一) 、channelstatus(submitted/success/abnormal/closed) 、amount_refund(分/支持部分退款) 、reasonraw(JSON) 、created_atsuccess_time
  • payment_notify_events 回调事件
    • idnotify_id(唯一) 、resource_typeevent_typesummaryraw(JSON) 、processed(bool) 、created_at
  • payment_bills/payment_bill_diff 对账与差异
    • bill_datetype(tradebill/refundbill) 、file_urldigestimported;差异记录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签名”构造客户端参数。

安全与合规

  • 验签必做;来源白名单;请求体原样落库审计。
  • 金额单位统一“分”;防止小数误差;禁止信任前端金额。
  • 日志与告警:失败重试/签名失败/金额不一致必须告警。

测试与验收

  • 单元:签名参数构造、金额边界、幂等推进、退款部分/全额。
  • 集成:模拟回调事件、订单查询兜底、对账导入与差异比对。
  • 验收标准:
    • 小程序端正常拉起并支付成功,后台订单状态正确推进;
    • 管理端可发起退款并正确落账;
    • 回调/对账全链路无漏处理且有幂等保障;
    • 漏斗“支付用户/完成订单”口径与交易/发货一致。

实施步骤

  1. 引入微信支付Go SDK与配置加载建立PayClient与证书管理。
  2. 建表与唯一索引:orders.order_nopayment_*系列关键字段唯一。
  3. 实现预下单接口,返回前端调起参数并记录payment_preorders
  4. 实现支付回调路由:验签/解密→事件入库→幂等推进订单与交易记录。
  5. 实现退款接口与回调处理;联动user_points_ledger落账。
  6. 实现对账拉取与差异比对;补充运营漏斗统计数据来源为交易表。
  7. 覆盖测试与监控告警;上线灰度并观察。

参考文档(已核对)

  • JSAPI预下单与签名串、调起参数与prepay_id有效期:/websites/pay_weixin_qq_doc_v3
  • 官方Go SDK/wechatpay-apiv3/wechatpay-go