2026-07-09 · 阅读版 · 执行真相源 docs/superpowers/plans/2026-07-09-payment-clean-usdt-loop.md(带 checkbox)· #34(tier-1)
POST /v1/redeem(兑换,幂等+限频)、批次生成/导出、发卡店回调 /webhook/store/codes(HMAC+时间戳+nonce)都在。本方案新增核心只有一个后端端点(JIT 发码 /internal/codes/mint)+ 一个独立收款服务 pangolin-pay(TronGrid watcher + epay 支付口)。
买家 ──下单──▶ 独角数卡(门面, 独立 VPS)
│ 建单 + epay 跳转
▼
pangolin-pay(自建收款服务, 同 VPS)
├ 派生每单唯一 TRC20 收款地址 (watch-only, 只持 xpub)
├ TronGrid watcher 轮询到账 + 确认
└ 到账 ──epay notify──▶ 独角数卡「已支付」
│
▼ 独角数卡 API-提货
pangolin-pay /issue ──HMAC──▶ pangolin 控制面 POST /internal/codes/mint
└ 生成合法码 + 存 unused + 返回明文
│
▼ 独角数卡把码交付买家
买家 ──输码──▶ 客户端/用户中心 POST /v1/redeem ──▶ 订阅生效
pangolin-pay 只持 xpub 派生收款地址、绝不持私钥(能收不能转,脱库也转不走钱);② 私钥/助记词冷备 + Bitwarden,不入 git、不上热机;③ 收款终点=自托管钱包,变现经交易所出金 US LLC,记账走 accounting;④ 全程不碰跑分/中国支付。部署在独立海外小 VPS,不放 pangolin1(内存紧 + 风险隔离),只经 HTTPS+HMAC 与控制面 api.yanmeiai.com 通信。
| 能力 | 状态 |
|---|---|
POST /v1/redeem 兑换(幂等+限频+账户锁) | 已实现 |
| 批次生成/导出(Crockford Base32 75-bit 带校验位,只存 hash) | 已实现 |
发卡店回调 /webhook/store/codes(HMAC+时间戳+nonce) | 已实现(留给未来第三方发卡店) |
POST /internal/codes/mint JIT 发码 | 本轮新增 |
pangolin-pay:TronGrid watcher + epay 支付口 | 本轮新增 |
| 自托管 TRC20 HD 钱包 + 归集/变现 runbook | 本轮新增 |
先厘清:这套架构的「钱包」是两件事,别当成装一个 app。
所以「用哪个钱包」= 选 ① 主种子怎么冷存 + ② watcher 用哪个派生库。
| 方案 | 冷存安全 | xpub 导出 | 归集签名 | 结论 |
|---|---|---|---|---|
| 离线生成助记词 + 库派生 推荐 | 高(纸/钢板离线,永不联网) | 从种子导 account xpub | 离线机用库签 | 最贴合 watch-only 架构、最灵活 |
| Ledger 硬件钱包(可叠加) | 最高(私钥不出设备) | 可导 account 公钥(需工具) | 插 Ledger 签 | 想再加一层硬件冷存就用它兜底 |
| TronLink / imToken / Trust(手机热钱包) | 低(热钱包) | 不便批量派生 | app 内签 | 不推荐当收款主钱包 |
| 语言 | 库 |
|---|---|
| Go(与 server 同栈,推荐) | tyler-smith/go-bip39 + btcd/btcutil/hdkeychain(BIP32)→ 公钥转 TRON base58 地址;或成熟 TRON Go SDK |
| Python | tronpy + bip_utils(一步派生 TRON 地址) |
一套助记词派生无限个收款地址;热服务只拿 xpub 派生地址收款、拿不到私钥;私钥冷备用于归集。
m/44'/195'/0'/0/i(195=TRON)。工具:离线机 tronpy/tronweb 或硬件钱包(Ledger 导出 xpub),生成不联网。TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t,核对无误再写死)。pangolin-pay(自带轻量 SQLite)。pay_orders(order_no, sku, plan, duration_days, addr_index, address, expect_amount, status, tx_id, confirmations, created_at, expires_at) + addr_cursor(next_index)。m/.../0/next_index(最准,免金额撞车)。次选单地址+唯一金额。GET /v1/accounts/{addr}/transactions/trc20?only_confirmed=true&contract_address=<USDT>,比对 to/token/金额(含容差)。status=paid + 记 tx_id。expired、释放地址(不复用,避免串单)。POST /internal/codes/mint付款确认时即时生成一个合法码——这才是 webhook JIT 的落点:售出才产码、才有效。自建场景由 pangolin 产码(保证格式+校验位单源),比让外部产码更干净。
POST /internal/codes/mint # /internal 组, 无 JWT, HMAC 同 webhook
Headers: X-Pangolin-Signature: sha256=<hmac> · X-Pangolin-Timestamp(±5min) · X-Pangolin-Nonce
Body: { "plan":"pro", "duration_days":365, "order_ref":"<独角数卡订单号>" }
→ 200 { "code":"PGL-XXXX-...", "expires_at":"..." } # 以 order_ref 幂等, 同单返同码
codes.GenerateCode() 产码 + Store.CreateCode 存 unused(channel=ChannelStore)→ 返回明文。order_ref 为幂等键(存 order_ref→code_hash),同单重放返回同一码。server.env(CODES_MINT_HMAC_SECRET);main.go 挂路由。/webhook/store/codes 供未来第三方发卡店。/issue → 内部 HMAC 调 /internal/codes/mint 取码 → 交付买家。/v1/redeem→订阅生效、全端同步。go test ./internal/codes/... 含 mint 验签/幂等/格式全绿;pangolin-pay go test 含匹配/确认/超时/幂等/恢复;真机一笔真 USDT 小额单全通 + 异常逐条演练;安全逐项核对。
相关:支付渠道选型总览 · 方案A 自建发卡网细化 · 发卡+发货架构