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): 添加称号效果参数验证测试
4.0 KiB
4.0 KiB
目标
- 按真实微信支付流程完善一个完整的支付体系:持久化预下单/交易/退款/通知/对账,统一金额/积分口径,优化退款恢复与幂等,前后端一致展示。
数据库与模型
- 新增表(均使用“分”为金额单位):
- payment_preorders(id, order_id, order_no[UNIQUE], channel, prepay_id, out_trade_no[UNIQUE], amount_total, payer_openid, status(created/expired/paid), notify_url, created_at, expired_at)
- payment_transactions(id, order_id, order_no[UNIQUE], channel, transaction_id[UNIQUE], amount_total, success_time, raw(JSON), created_at)
- payment_refunds(id, order_id, order_no, refund_no[UNIQUE], channel, status(submitted/success/abnormal/closed), amount_refund, reason, success_time, raw(JSON), created_at)
- payment_notify_events(id, notify_id[UNIQUE], resource_type, event_type, summary, raw(JSON), processed(bool), created_at)
- payment_bills(id, bill_date, type(tradebill/refundbill), file_url, digest, imported(bool), created_at)
- payment_bill_diff(id, bill_date, diff_type(missing/amount_mismatch/extra), local_tx_id, wechat_tx_id, detail, created_at)
- 订单唯一索引:orders.order_no[UNIQUE]
- 迁移:生成/应用 GORM 迁移脚本;保持向后兼容(不破坏现有数据)。
Repository/DAO
- 生成 gorm/gen DAO 与 model 文件;在 internal/repository/mysql/dao, model 下新增 payment_* 的 gen 文件。
Service 逻辑
- 预下单:
- 校验订单 status=1、金额与归属;调用 jsapi.Prepay,落库 payment_preorders(out_trade_no=order_no, prepay_id),回填 orders.pay_preorder_id;返回调起参数(RSA-SHA256 四行签名)。
- 支付通知:
- 验签解密 payments.Transaction;幂等(notify_id 去重)入库 payment_notify_events;写入 payment_transactions(transaction_id/raw/success_time);orders 条件推进 status:1→2,写 paid_at。
- 退款:
- 管理端主动退款:生成 refund_no 并调用 refunddomestic.Create,入库 payment_refunds(refund_no/amount/status/raw);
- 积分恢复(统一口径):
- 部分退款按比例恢复:恢复积分 = (订单积分抵扣分 × 退款分 ÷ 实付分) ÷ 100,累计不超过订单抵扣积分;全额退款一次性恢复剩余积分;幂等校验(累计已恢复积分 vs 目标)。
- 订单状态:全额退款置 4已退款;部分退款维持 2已支付,并维护累计已退款金额(聚合 payment_refunds)。
- 对账:
- 每日下载交易/退款账单(依 SDK);入库 payment_bills;比对 payment_transactions/payment_refunds 生成 payment_bill_diff;提供导出与差异修复入口。
Admin 接口
- 订单详情:增加展示字段 transaction_id、累计已退款、每笔退款(refund_no/amount/status/时间/原因);可退余额=实付-累计退款。
- 退款列表与详情:GET /api/admin/pay/refunds, GET /api/admin/pay/refunds/:refund_no;
- 对账:POST /api/admin/pay/bills/import(上传账单并入库);GET /api/admin/pay/bills/diffs(差异列表)。
前端
- 金额统一格式化为“元”展示(两位小数),内部接口仍用“分”;
- 订单详情页增加 transaction_id/refund_no/channel/支付方式;展示累计已退款与可退余额(元);
- 退款记录表展示 refund_no/金额(元)/原因/时间;
- 保持中文枚举一致(状态/来源/发货/抽奖)。
幂等与安全
- 幂等键:order_no(预下单/推进)、notify_id(回调)、refund_no(退款);
- 唯一索引:预下单/交易/退款/通知表关键字段;
- 条件更新:WHERE status=... 控制并发;
- 日志与告警:验签失败、金额不一致、退款异常、对账差异。
测试与验收
- 单元:分↔积分换算、部分/全额退款恢复、幂等重复;
- 集成:真实预下单→回调→主动退款→详情一致;
- 对账:拉取账单并生成差异;
- 验收:管理端全链路可用、金额与积分口径一致、数据持久化完整。