docs(pay): attempt 带 expires_at(单次超时不关 order)+ 订单取消接口

- 超时挂 attempt(哪吒/crypto 各自),超时只弃本 attempt、order 仍 pending 可换渠道;
  order.expires_at 是整体购买窗口。一单只一个 attempt 成功(MarkOrderPaid 守卫 pending)。
- 加 POST /orders/{no}/cancel(pending→canceled),canceled 单在订单列表可见。
- P1 计划同步:pay_attempts 加 expires_at 列 + CancelOrder 方法 + 取消/列表测试。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
wangjia
2026-07-09 23:26:39 +08:00
parent bf058077cd
commit 127f09faaa
3 changed files with 77 additions and 21 deletions
+3 -2
View File
@@ -84,7 +84,7 @@
<div class="card">
<h3>Task 4 · <code>payorders</code> 数据访问</h3>
<p>新包 <code>server/internal/payorders</code><code>Order</code>/<code>Attempt</code> 结构 + <code>CreateOrder/GetOrder/ListOrders/CreateAttempt/AttemptByProviderRef</code> + 幂等 <code>MarkOrderPaid</code>(仅 <code>status='pending'</code> 才置 paid + 回填 subscription_id + attempt 置 paid paid 返回 false)。SQLite 内存实库测「建单→查单→标付→再标付幂等」。</p>
<p>新包 <code>server/internal/payorders</code><code>Order</code>/<code>Attempt</code> 结构 + <code>CreateOrder/GetOrder/ListOrders(全状态)/CreateAttempt/AttemptByProviderRef</code> + 幂等 <code>MarkOrderPaid</code>(仅 <code>status='pending'</code> 才置 paid + 回填 subscription_id + attempt 置 paid pending 返回 false —— 「一单只一个 attempt 成功」的守卫)+ <code>CancelOrder</code>pending→canceledcanceled 单仍在列表可见)。attempt 带自己的 <code>expires_at</code>(单次超时不关 order)。SQLite 内存实库测「建单→查单→标付→再标付幂等」「取消→再取消 false→列表可见」</p>
</div>
<h2>两张新表</h2>
@@ -94,7 +94,8 @@
· 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) · UNIQUE(provider,provider_ref) 幂等命门</pre>
(created|pending|paid|failed|expired) · expires_at(单次超时,不关 order)
· UNIQUE(provider,provider_ref) 幂等命门</pre>
<p style="margin-top:28px" class="path">相关:<a href="pay-orchestration-design.html">编排层设计</a> · 真相源 docs/superpowers/plans/2026-07-09-pay-orchestration-p1-schema-grant.md</p>
</div>