From 5055afdbd71fe46ac6bd8da8084cc58c650b14b8 Mon Sep 17 00:00:00 2001 From: wangjia <809946525@qq.com> Date: Thu, 9 Jul 2026 14:44:22 +0800 Subject: [PATCH] =?UTF-8?q?docs(pay):=20=E5=9C=B0=E5=9D=80=E6=B1=A0?= =?UTF-8?q?=E6=94=B6=E6=AC=BE=E6=A8=A1=E5=9E=8B=20plan(=E6=8A=98=E4=B8=AD?= =?UTF-8?q?=E6=96=B9=E6=A1=88,#34/34A)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 从每单唯一 HD 地址改为地址池复用(池=峰值并行度、复用摊薄激活/归集)。规则:最小编号 idle 绑单/无 idle 派生/15min 超时释放/同用户单订单。核心安全点:地址复用迟到付款错配 → 匹配按 tx+金额+时间戳(晚于建单)、每单唯一金额、孤儿付款记录。双产物 md+html,登记 index。 待用户确认后执行(tier-1)。 Co-Authored-By: Claude Opus 4.8 --- docs/index.html | 30 +++++ docs/pay-address-pool-plan.html | 110 ++++++++++++++++++ .../plans/2026-07-09-pay-address-pool.md | 71 +++++++++++ 3 files changed, 211 insertions(+) create mode 100644 docs/pay-address-pool-plan.html create mode 100644 docs/superpowers/plans/2026-07-09-pay-address-pool.md diff --git a/docs/index.html b/docs/index.html index 2131854..a6d523f 100644 --- a/docs/index.html +++ b/docs/index.html @@ -44,6 +44,11 @@

设计方案 / Specs

+ +
支付落地方案 · 发卡/Reseller 收款 + 激活码自动发货 HTML
+
把「收钱」与品牌 VPN 主体解耦:收款外包给发卡平台/Reseller(他们承担支付宝/微信跑分、冻卡、跑路风险),你只交付「激活码」;客户端/用户中心只认码,codes 模块核销即生效。含完整流程图(钱流/码流/结算)、两种对接模型(A 预充卡密库存 / B API 实时签发 POST /v1/codes/issue)、三阶段落地节奏、对账与风险边界(主体永不碰跑分/中国支付)。灰产“付完秒发货”体验的合规化替身。
+
docs/payment-reseller-fulfillment-design.html
+
CI/CD 全流程(tag 触发编译/发版/部署)HTML
#30。参考 jiu 的 scripts/ci + .gitea/workflows:tag 触发(site-v*/server-v*/client-v*)→ 编译 → 测试 → Gitea release → 部署。runner 混合(nas=官网+服务端容器化 / mac=Android+macOS / windows=Windows)。服务端部署固化 F3/F4「备份→migrate→换二进制→重启→健康检查+回滚」;官网部署 pangolin.yanmeiai.com;客户端 apk/dmg/exe 挂 release 喂官网下载链接。密钥作用域:Apple/token 账户级、部署 key/Android keystore 仓库级。范围 A~F(排除 iOS/#26/#25)。
@@ -86,6 +91,26 @@

实现计划 / Plans

+ +
pangolin-pay 地址池收款模型(折中方案,#34/34A)HTML
+
阅读版;执行真相源 docs/superpowers/plans/2026-07-09-pay-address-pool.md(含 checkbox)。从"每单唯一 HD 地址"改为地址池复用:池大小=峰值并行度(初始 10,不够动态派生),地址复用摊薄激活/归集,归集成本 O(订单数)→O(池大小)。规则:最小编号 idle 绑单、无 idle 派生新址、15min 超时释放、同用户单订单。核心安全点:地址复用的迟到付款错配——匹配按"到账 tx+金额+时间戳(晚于建单)"、每单唯一金额、孤儿付款记录。5 Phase:数据模型→建单→watcher 匹配/释放/孤儿→归集(能量租赁)→并发/复用真链验证。
+
docs/pay-address-pool-plan.html · 真相源 docs/superpowers/plans/2026-07-09-pay-address-pool.md
+
+ +
pangolin-pay 加密货币交易引擎(#34 第一块,可独立验证)HTML
+
阅读版;执行真相源 docs/superpowers/plans/2026-07-09-crypto-tx-engine.md(含 checkbox)。#34 里"加密货币交易"核心的独立可执行件:钱包(两套助记词 A 运营/B 金库,离线生成、热服务只持 xpub)→ Go 服务 pangolin-pay HD 派生收款地址(对齐 Ian Coleman)→ TronGrid watcher 侦测 TRC20 到账(每单唯一地址+金额、确认、幂等)→ 归集 sweep(离线签名、TRON gas 两步/能量租赁)→ 真实 1 USDT 端到端验证。不含独角数卡/发码,跑通后再接门面。
+
docs/crypto-tx-engine-plan.html · 真相源 docs/superpowers/plans/2026-07-09-crypto-tx-engine.md
+
+ +
收款闭环 · 独角数卡 + 自托管 USDT(TRC20) + webhook JIT(#34)HTML
+
阅读版;执行真相源 docs/superpowers/plans/2026-07-09-payment-clean-usdt-loop.md(含 checkbox)。最干净长期方案:门面独角数卡(独立海外 VPS)+ 自托管 TRC20 HD 钱包(热服务只持 xpub、watch-only,绝不持私钥)+ 自建 TronGrid watcher(每单唯一地址侦测到账)+ webhook JIT 发码(新增控制面 POST /internal/codes/mint,HMAC,售出才产合法码)。复用已就绪 codes(redeem/批次/webhook)。6 Phase:钱包 → watcher → mint 端点 → 独角数卡 epay+API提货对接 → 部署/归集/变现/对账 → 端到端验证。全程无跑分、收款终点自托管、变现出金 US LLC。
+
docs/payment-clean-usdt-plan.html · 真相源 docs/superpowers/plans/2026-07-09-payment-clean-usdt-loop.md
+
+ +
方案A · 自建发卡网(独角数卡)落地细化 HTML
+
门面自建(独角数卡,独立 VPS 隔离部署)+ USDT 收款 + 激活码自动发货。关键:后端已就绪——发卡店回调 POST /webhook/store/codes(HMAC+时间戳+nonce 防重放)、兑换 POST /v1/redeem(JWT)、批次生成/导出/作废均在 server/internal/codes。含拓扑图、两种发货模型(A 预充卡密零胶水 / B webhook JIT 更安全,待补 /internal/codes/mint 单源产码)、SKU 映射、USDT 两条接入路子、落地步骤与风险边界。
+
docs/payment-a-selfhosted-store-plan.html
+
前端设计系统治理重构(ds-flow 全端)HTML
阅读版;执行真相源 docs/superpowers/plans/2026-07-07-frontend-ds-refactor.md(含 checkbox)。用 ds-flow 把 Flutter 五端 + 官网 + 用户中心收口到「设计单源·代码镜像·静态闸拦漂移·golden/fidelity 双级像素验收兜底」。非从零 bootstrap(已约 65% 达标):补原型三件套(atoms.css/icons.js/index.html 登记页)+ Web 共享原子层去重(各自实现+同源闸)+ 硬编码色/fidelity 闸 + 启用 pre-commit。6 阶段:CLAUDE.md → 原型单源 → Web token 同源 → Web 原子对齐 → Flutter golden 补齐 → 闸挂满。主题保持 light/dark。
@@ -128,6 +153,11 @@

知识库 / 调研

+ +
支付渠道选型总览 HTML
+
各支付渠道候选与甄别标准(研究起点,非背书)。核心心智:「发卡平台」= 门面 × 通道两层分离,灰/干净分水岭在通道不在门面。候选 A 自建发卡网(独角数卡/acg-faka/KamiFaka)· B 加密网关(NOWPayments/Cryptomus/CoinGate)· C 自建 USDT 监听(TronGrid)· D 官方鹅(TG Stars/IAP)· E 支付宝微信第三方(跑分层,不列名单)。含决策矩阵 + 尽调清单 + 推荐起步组合(独角数卡+USDT)。
+
docs/payment-channels-overview.html
+
前端全景(ds-flow 设计系统治理)HTML
Flutter 五端 + 官网 + 用户中心的设计系统治理全景:一次 UI 改动标准路径、目录地图、三层真相源模型、令牌 codegen、四道静态闸「违规谁拦」、像素验收(golden 双主题 + fidelity 待建)、响应式五端、规则速查。原型单源 design/prototype/(tokens/atoms/icons/index.html)、check-ds/check-l1-sync/check_ds_code/codegen-drift 四闸进 CI、golden 全量 34 绿含 CJK。
diff --git a/docs/pay-address-pool-plan.html b/docs/pay-address-pool-plan.html new file mode 100644 index 0000000..5193cfc --- /dev/null +++ b/docs/pay-address-pool-plan.html @@ -0,0 +1,110 @@ + + + + + +pangolin-pay 地址池收款模型 实现计划 + + + +
+← 文档索引 +

pangolin-pay 地址池收款模型

+

2026-07-09 · 阅读版 · 执行真相源 docs/superpowers/plans/2026-07-09-pay-address-pool.md · #34/34A 收款模型修订(折中方案)

+ +
+从"每单唯一 HD 地址"改为地址池复用:池大小 = 峰值并行度(初始 10,不够动态派生),地址复用摊薄激活/归集成本;仍多地址,避免并发订单金额撞、对账精确。归集成本从 O(订单数) 降到 O(池大小),激活一次/地址即长期复用。是"单地址(省钱撞单)"与"每单唯一(精确但贵)"的折中。 +
+ +
+核心风险 · 地址复用的迟到付款错配:地址回收后绑给新订单,若前一个用户超时后才付款,钱打到已绑新订单的地址上 → 可能误配。解法(必须):① 匹配按"到账 tx + 金额 + 时间戳(晚于建单)",不按余额、不只按地址;② 每单唯一金额(基准+唯一尾数);③ 匹配不到活跃订单的到账 → 记 orphan_payments 人工对账;④(可选)超时后地址冷却再重绑。 +
+ +

设计(规则 + 安全点)

+ + +

Phase A — 数据模型

+ + +

Phase B — 建单

+ + +

Phase C — watcher(匹配/释放/孤儿)

+ + +

Phase D — 归集

+ + +

Phase E — 测试 + 真链

+ + +

不在本轮 / 取舍

+ + +

相关:加密货币交易引擎(已实现钱包/tron/sweep) · #34 收款闭环全景

+ +
+ + diff --git a/docs/superpowers/plans/2026-07-09-pay-address-pool.md b/docs/superpowers/plans/2026-07-09-pay-address-pool.md new file mode 100644 index 0000000..5ed10ea --- /dev/null +++ b/docs/superpowers/plans/2026-07-09-pay-address-pool.md @@ -0,0 +1,71 @@ +# pangolin-pay 地址池收款模型(折中方案,取代"每单唯一 HD 地址") + +> #34/34A 收款模型修订。**Context**:每单唯一 HD 地址 → 每地址激活(~1 TRX)+ 归集(每笔一次转账)成本随 +> **订单总数线性增长**(#34 暴露的严峻成本)。改为**地址池复用**:池大小 = **峰值并行度**(初始 10,不够动态派生), +> 地址**复用**摊薄激活/归集;仍是多地址,**避免并发订单金额撞、对账精确**。这是"单地址(省钱但撞单)"与 +> "每单唯一(精确但贵)"的折中。 +> +> 归集成本从"O(订单数)"降到"O(池大小)";激活成本一次性(每个池地址激活一次即长期复用)。 +> +> **本 plan = 用户定的规则 + 补齐的安全点**(核心:地址复用的**迟到付款错配**)。已实现的 Phase B(钱包派生)、 +> tron(TronGrid 读到账/建/广播/签名)、cmd/sweep 复用;主要改 store / pay(建单)/ watcher(匹配)。 + +## 设计(规则 + 安全点) + +- **地址池**:HD 派生地址(路径 `m/44'/195'/0'/0/i`,与现有一致),各有状态 `idle | busy`。初始池 10。 +- **建单**:绑**最小编号的 idle** 地址 → 置 `busy`;**无 idle → 派生下一个新地址**(编号递增)入池并绑之。 +- **每单唯一金额** ⭐必需:基准价 + 唯一尾数(如按订单序号映射的微分),保证**当前活跃订单之间金额不撞**, + 且复用地址上"旧订单迟到付款"不会误配"新订单"。 +- **15 分钟超时**:超时 → `expired` → 地址回 `idle`(可选**冷却期**再重绑,降低迟到错配)→ 提示用户**重建订单**、用新订单地址付款。 +- **付款完成**:watcher 确认到账 → 订单 `paid` → 地址回 `idle`。**注意**:此时地址里**仍有 USDT**(待归集); + `idle` 只表示"可重绑",不代表钱清了。 +- **匹配规则(核心)**:watcher 找**到该地址、金额 == 该单唯一金额(或 ≥,带容差)、且到账区块时间晚于订单创建** + 的 TRC20 转入 **tx** → 匹配。**绝不按余额、不只按地址**(地址会累积余额、会复用)。 +- **同用户单订单**:同一用户同时只能有**一个**活跃(pending)订单。 +- **孤儿付款**:到账 tx 匹配不到任何活跃订单(迟到 / 欠额 / 误差)→ 记 `orphan_payments`,人工对账/补发。 +- **归集**:定期扫池内**有余额**的地址 → 冷钱包(**能量租赁** ~$0.1–1/笔);池 ~10 地址,**归集笔数有界**; + 归集与 `busy` 无关(随时可扫,不影响待付订单——到账是未来的独立 tx)。 +- **池增长上限**(可选):无空闲就新建,设上限防滥用无限增长(超限则排队/拒单)。 + +## Phase A — 数据模型改造 + +- [ ] `addresses` 表:`id / addr_index(唯一) / address / state('idle'|'busy') / activated(bool) / created_at`;初始不预建,按需派生入池。 +- [ ] `pay_orders` 改:加 `user_ref`(同用户单订单约束用)、`address_id`(绑定的池地址)、`expect_amount`(唯一金额,micro-USDT)、`matched_tx_id`;保留 status/created_at/expires_at。 +- [ ] `orphan_payments` 表:`tx_id(唯一) / address / value / block_ts / created_at / handled(bool)`。 +- [ ] 复用现有 `addr_cursor`(HD 派生游标)派生新池地址。迁移脚本 + 索引(status、address、user_ref)。 + +## Phase B — 建单(pay 服务) + +- [ ] `CreateOrder(userRef, sku)`:① 校验**同用户无活跃订单**(有则返回现有/拒);② **原子**选最小编号 `idle` 地址(事务 + 行锁)置 `busy`;③ 无 idle → `NextAddrIndex` 派生新地址(`AddressFromAccountXpub`)入池并绑;④ 分配**唯一金额**;⑤ 写 `pending` 单(TTL 15min)。 +- [ ] **唯一金额分配**:基准金额 + 唯一尾数,保证与**当前所有活跃订单**不撞(可用订单序号 → 尾数微分,micro-USDT 级);记录基准+尾数便于展示。 +- [ ] `GetOrder`;释放地址的公共方法 `releaseAddress(addrID)`(paid/expired 复用)。 + +## Phase C — watcher 改造(匹配 + 释放 + 孤儿) + +- [ ] **匹配**:对每个 `pending` 单,查其绑定地址的 TRC20 转入;筛 `value` 命中唯一金额(==,或 ≥ 带小容差)**且 `block_ts > order.created_at`** → `paid` + 记 `matched_tx_id`;**释放地址 → idle**。 +- [ ] **超时**:`pending` 过期 → `expired` + 释放地址 → idle(可选冷却期后才允许重绑)。 +- [ ] **孤儿**:遍历池地址的到账 tx,凡匹配不到任何活跃订单的转入 → 写 `orphan_payments`(去重 by tx_id)。 +- [ ] **幂等**(tx_id 全局去重,含 orphan)、崩溃恢复(从 DB pending + 池状态重建)。TronGrid 需能取到账时间戳(`block_timestamp`)用于时间过滤。 + +## Phase D — 归集(复用 cmd/sweep) + +- [ ] 扫池内**有余额**地址 → 冷钱包;接**能量租赁**(先手动 runbook,后续自动化);归集与订单状态解耦。 +- [ ] 归集不清空 `busy` 语义;只搬余额。runbook 写清"哪些地址、多久扫一次、能量怎么租"。 + +## Phase E — 测试 + 真链验证 + +- [ ] 单测:并发建单**不抢同址**(原子性)、地址**复用后旧订单迟到付款不误配新订单**(唯一金额+时间戳)、唯一金额不撞、超时释放、孤儿记录、幂等、崩溃恢复、同用户单订单约束。 +- [ ] 真链:两并发订单各绑不同地址各自付款到 paid;一单超时释放后新单**复用同址**,再对旧地址补一笔"旧金额"付款 → 应成**孤儿**、不误配新单;归集池地址到冷钱包。 + +## Verification / 判据 + +- `go test ./...`(store/pay/watcher 新逻辑全绿,重点覆盖复用错配)。 +- 真链:并发 + 复用 + 迟到付款三场景表现正确;归集笔数 = 有余额的池地址数(有界)。 +- 成本:激活一次/地址、归集 O(池大小);对小额高频订单不再被激活费线性拖累。 + +## 不在本轮 / 取舍 + +- GasFree(#35,免 TRX 但每笔固定 1 USDT,更适合少地址批量,另议)。 +- 能量租赁自动化(先手动)。 +- 池增长上限/排队(先不设,或设一个宽上限)。 +- 发货侧(独角数卡 + /internal/codes/mint)另排。