Blizzard
|
3a4e1d53a5
|
refactor(payment): 渠道抽象成 Channel 接口 —— 接新渠道=加 adapter 不动骨架
PAYMENT_DESIGN §3 承诺的 internal/payment/channel.go 适配器接口此前不存在,微信硬编码在
manager/handler 里。补齐抽象:
- channel.go:Channel 接口(Name/CreatePay/QueryOrder/VerifyCallback)+ 统一 PayIntent/PayResult
+ 渠道名常量。入参用基本类型不吃 *store.PaymentOrder,payment 包不反依赖 store。
- Wechat 实现 Channel(编译期断言 var _ Channel);QueryResult 归一为 PayResult;CreatePay 返回 PayIntent。
- Manager 从「持一个 *Wechat」改为渠道注册表:Get(name)/Available()/Status(name)/ReloadWechat;
按渠道名持有已装配实例,热重载不变。
- 回调路由收敛 /billing/callback/wechat → /billing/callback/:channel 按名路由(旧 notify URL 仍匹配);
查单/掉单补偿据 order.Channel 路由,不再写死微信。下单支持可选 channel(缺省 wechat)。
- 支付宝/Stripe 现在真·只差一个 adapter+注册。唯一未泛化:回调 ack 应答格式(现微信态,注释标明)。
- payment 包首个测试:Manager 注册表 4 用例(空/注册摘除/空配置/配置不全)。build/vet/test/lint 全绿。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-07-18 13:56:24 +08:00 |
|
Blizzard
|
3db2de1ef6
|
feat(billing): 支付 P5.3 —— 掉单补偿定时器 + admin 订单流 + 日终对账
支付线封口。此前 pending 单只在「用户开着账单页轮询」时才查单确认——用户扫完码
关页面,钱付了、积分永不到账。
- 掉单补偿定时器(payment_reconcile.go):gateway 内每分钟扫 pending 微信单,
逐单 reconcileOrder 主动查单落态。把「用户在不在场」从入账链路摘掉。
reconcileOrder 从 BillingOrderStatus 抽出、前端轮询与定时器共用一份幂等
落态逻辑(不重蹈 GenerateReport/SubmitTask 的漂移)。渠道未配置时空转不炸。
- admin 订单流 GET /admin/orders(状态计数+全平台订单,可筛)。
- 日终对账 GET /admin/orders/reconcile:paid 单 ↔ 账本 grant 分录逐单比对,
抓 order_without_ledger(钱到了积分没给,最严重)/ ledger_without_paid_order。
- admin 计费页「充值订单与对账」块:计数卡片+订单流+一键对账。
⚠️ live 抓到并修掉一个真 bug:OrderStats 复用同一个 gorm.DB 链式 Count 三次,
WHERE 累加成 status=A AND status=B → 恒 0(订单流显示 2 单但计数全 0)。
改成每次起新 query builder。—— 又一次只有 live 才暴露的。
验证:go 6 包测试+tsc+41 vitest 全绿;live 造差异单对账正确抓出
order_without_ledger、清账后回零差异;补偿器启动日志+渠道未配置空转不炸;
浏览器验订单流卡片+一键对账绿条。TTL 过期路径需真渠道触发,部署后自然覆盖。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-07-18 11:25:37 +08:00 |
|