执行真相源 docs/superpowers/plans/2026-07-10-pay-v2-p7-codes-lib.md(含 - [ ] checkbox)。设计见 pay v2 统一支付网关设计 §9/§9.1/§9.2/§12。参考实现:pangolin/server/internal/codes/(只读,移植 canonical 部分)。
| 选项 | 结论 |
|---|---|
pay 仓内 pkg/codes | 不采用 —— pay 依赖很重(gin/GORM/alipay/wechatpay-go),codes 与支付管线正交,放进 pay 逻辑/依赖两维度都错 |
| pangolin 仓内保留、jiu 抄一份 | 不采用 —— 违反"共享库"目标,退化两份漂移代码 |
| 独立仓库 + 独立 module | 已定 —— 新仓 ~/code/codes,module github.com/wangjia/codes;核心包零第三方依赖(仅 stdlib),可选 Redis 能力隔离进 codes/redisx 子包 |
落地约定:源码 ~/code/codes,remote ssh://git@git.51yanmei.com:2222/wangjia/codes.git(需先在 Gitea 建仓)。pangolin/jiu 迁移到 import 本库是后续独立工作,不在本计划内。
Entitlement{Kind,Payload} 通用权益描述符(duration={plan,days} / quota={resource,amount}),替代硬编码 plan_id+duration_days;Status 三态 unused/redeemed/void;哨兵错误。internal/idgen 的 Crockford 部分(15 数据字符+1 mod-37 校验字符,crypto/rand 防偏抽样),根包薄封装 GenerateCode/Canonicalize/Hash。embed.FS + 零依赖 ApplyMigrations,也可接 golang-migrate iofs);Store 的 CreateBatch/CreateCode/FindByHash(ForUpdate)/MarkRedeemed/Void/WriteAudit,哈希唯一约束防重码。CreateBatch 逻辑),明文码只在返回值出现一次,从不落库/落日志。Redeem[T any](ctx, store, tx, codeHash, redeemerRef, grant GrantFunc[T])——宿主开事务传入、锁(FindByHashForUpdate+dialect)+CAS(MarkRedeemed 条件 UPDATE)+幂等(同 redeemerRef 短路)+审计,grant 回调在同一 tx 内执行宿主的权益写入,失败整体回滚——落地"码表与宿主表同库=本地事务"的方案 A 前提。另有 VoidCode。NoopRateLimiter/InMemoryNonceChecker);GuardedRedeem[T] 包一层失败锁定,失败计数、成功清零。SET NX 原子去重,miniredis 测试免 docker。system+timestamp+nonce+body 一并入 MAC 的双向签名惯例,而非 pangolin 原版 body-only HMAC)+ 去重 + 通用权益负载 MintPayload → 调 Mint。| 决策 | 说明 |
|---|---|
| 同库本地事务 | Redeem[T] 接收宿主已开的 *sql.Tx——码状态翻转与宿主 grant 回调写同一事务,要求宿主权益表与 codes 表在同一个 *sql.DB 下(设计文档 §9.1 方案 A 前提) |
| 通用权益描述符 | Entitlement{Kind,Payload} 库只做信封校验,从不解释业务字段——宿主 GrantFunc 才解释,对应设计文档 §12 可扩展性验证 |
| Redis 可选 | 核心包零 Redis 依赖;codes/redisx 子包才 import go-redis,不 import 就不产生依赖 |
| webhook 签名升级 | 从 pangolin 的 body-only HMAC 改为 pay-contract 的 system+timestamp+nonce+body 一并入 MAC,防头部篡改,统一多产品 webhook 验签心智模型 |
| redeemerRef 不透明 | 字符串("user:123"/"shop:9"),库不关心归属维度——设计文档 §9.1"归属维度留给各产品"的落地 |
admin_support.go/export.go,宿主可自行在 Store 基础方法上拼)相关:pay v2 设计 · P1 核心数据模型 · P2-P8 依赖 DAG · 真相源 docs/superpowers/plans/2026-07-10-pay-v2-p7-codes-lib.md