## 目标 - 以微信支付 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:配置与证书、日志、告警、幂等键与重试策略。 ## 数据模型(新增表与索引) 1) `payment_preorders` - `id` PK、`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` 唯一 2) `payment_transactions` - `id` PK、`order_id`、`order_no`(唯一)、`channel`、`transaction_id`(微信流水号唯一)、`amount_total`、`success_time`、`raw`(JSON)、`created_at` - 索引:`transaction_id` 唯一、`order_no` 唯一 3) `payment_refunds` - `id` PK、`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` 索引 4) `payment_notify_events` - `id` PK、`notify_id`(唯一)、`resource_type`、`event_type`、`summary`、`raw`(JSON)、`processed`(bool)、`created_at` - 索引:`notify_id` 唯一 5) `payment_bills` / `payment_bill_diff` - 账单拉取与差异记录,支持日级对账 6) 订单表约束 - `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与真实流程 1) 预下单(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` 幂等 2) 支付回调(notify): - 使用 `notify.NewNotifyHandler(api_v3_key, NewSHA256WithRSAVerifier(certificateVisitor))` 验签并解密得到 `payments.Transaction` - 幂等:`notify_id` 去重;如已处理直接 ACK - 状态推进:`WHERE status=1` 条件更新订单为已支付,写入 `payment_transactions`,记录交易时间与原始报文 - 失败场景兜底:按 `out_trade_no` 定时查询交易状态 3) 退款(真实): - 管理端创建退款:生成 `refund_no` 并调用 SDK `services/refunddomestic`(具体路径以官方包为准),成功回写 `payment_refunds` 与回调推进;支持部分/全额退款 - 数据还原:积分恢复按策略记录 `user_points_ledger(action=refund_restore)`;订单全额退款置 `status=4`,部分退款保持 `status=2` 并维护累计退款 - 幂等:`refund_no` 唯一;重复请求返回已有结果 4) 对账: - 下载交易/退款账单 `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 层统一事务包裹;状态推进以条件更新控制并发 - 日志与告警:回调验签失败、金额不一致、退款异常、对账差异均告警 ## 测试与验收 - 单元:签名参数构造、金额边界、幂等推进、退款全额/部分、回调解析 - 集成:模拟回调事件、订单查询兜底、账单导入与差异比对 - 验收标准: - 小程序支付全链路通;订单与交易记录准确; - 管理端退款成功并正确落账与还原; - 对账拉取与差异比对可用; - 漏斗“支付用户/完成订单”口径对齐真实交易。 ## 实施阶段 1) 数据库与DAO:新增 `payment_*` 表与索引;生成模型与DAO 2) SDK接入:统一初始化 client;预下单返回参数;notify 验签与解密;退款API封装 3) 业务实现:订单推进、幂等、退款落账与数据还原 4) 前端完善:展示交易/退款字段、可退余额、退款记录;对账入口 5) 测试与联调:完成单元与集成测试;灰度上线观测 ## 依赖 - 官方 Go SDK:`github.com/wechatpay-apiv3/wechatpay-go`(API v3) - 证书:商户私钥 PEM;平台证书自动下载与缓存