← 返回文档索引

统一支付编排层 · P1 数据层 + 开通重构 (阅读版)

执行真相源 docs/superpowers/plans/2026-07-09-pay-orchestration-p1-schema-grant.md(含 - [ ] checkbox,勿改)。设计见 统一支付编排层设计

P1 目标:给控制面加支付订单数据层(pay_orders 业务订单 + pay_attempts 支付尝试),并把「开通订阅」从 codes 抽成可复用、可传 sourcesubscription 包,subscriptions.source 枚举加 'pay'只覆盖数据层 + 开通原语,HTTP/adapter/客户端在 P2+。

7 阶段路线图

阶段内容本计划
P1schema(pay_orders/pay_attempts)+ subscription 开通重构(source=pay migration)+ payorders 数据访问本页
P2Provider 抽象/注册表 + Order/Attempt service + 客户端 REST(methods/orders/get/list/retry)+ 统一开通管线 + Query 轮询 worker(fake provider 测)待细化
P3crypto adapter(包裹 pangolin-pay)+ pay-server 出站 webhook + /v1/webhooks/pay/crypto待细化
P4哪吒 adapter(RSA 签/验、GET 回调、查单;密钥 Bitwarden nzzf)+ /v1/webhooks/pay/nazha待细化
P5四端 Flutter 支付页(方法选择器 + render_type 分发 + 轮询)+ 接购买入口待细化
P6用户中心订单历史页(读 GET /v1/pay/orders;return_url 跳此)待细化
P7端到端联调(两轨小额真链/真单)待细化

各阶段落地前逐一细化成独立计划,让接口以真代码为准、不臆测。

P1 任务(4 个,TDD bite-sized)

Task 1 · 迁移 000022(双引擎)

pay_orders + pay_attempts,并给 subscriptions.source'pay'。SQLite 列级 CHECK 不能 ALTER → 重建表(rename→建新→复制→drop→重建索引);MySQL ALTER TABLE subscriptions MODIFY source ENUM('trial','code','pay')。up/down 各 4 文件,临时 sqlite 库跑 up/down 验证。

Task 2 · subscription 包抽出开通原语

新包 server/internal/subscriptionGrant(ctx, tx, userID, planID, days, source) → (subID, expiresAt) 复刻现规则(同 plan 有活跃订阅→延长;否则→新建),source 写进新行。SQLite 内存实库测「新建→续期叠加、只 1 行、source=pay」。

Task 3 · codes 委托 subscription.Grant(行为不变)

codes.Service.applySubscription 改为调 subscription.Grant(..., "code"),跑通现有 codes 全套测试证明零行为变化。删除 codes.Store 里迁走的重复方法(若无其他调用者)。

Task 4 · payorders 数据访问

新包 server/internal/payordersOrder/Attempt 结构 + CreateOrder/GetOrder/ListOrders(全状态)/CreateAttempt/AttemptByProviderRef + 幂等 MarkOrderPaid(仅 status='pending' 才置 paid + 回填 subscription_id + attempt 置 paid;非 pending 返回 false —— 「一单只一个 attempt 成功」的守卫)+ CancelOrder(pending→canceled,canceled 单仍在列表可见)。attempt 带自己的 expires_at(单次超时不关 order)。SQLite 内存实库测「建单→查单→标付→再标付幂等」「取消→再取消 false→列表可见」。

两张新表

pay_orders   业务订单/购买账本:order_no(唯一幂等) · user_id/user_uuid · sku · plan_code
             · duration_days · amount_minor(int64) · currency · status
             (created|pending|paid|expired|canceled) · subscription_id(开通回填)
             · created_at/paid_at/expires_at
pay_attempts 支付尝试/收款账本:order_no · method · provider · provider_ref
             · render_type · amount_minor · currency · status
             (created|pending|paid|failed|expired) · expires_at(单次超时,不关 order)
             · UNIQUE(provider,provider_ref) 幂等命门

相关:编排层设计 · 真相源 docs/superpowers/plans/2026-07-09-pay-orchestration-p1-schema-grant.md