使用原来的 request_id 和完全相同的订单参数重试。不要因为连接超时就生成新请求键。NotPanel 可以返回已接受的订单,也可能在请求仍在处理时要求等待。
客户只购买了一次。如果请求发给面板后响应丢失,下一步应找回这次购买的结果,而不是把未知结果当作再次购买的理由。
超时后存在三种可能
- 请求没有到达,订单尚未被接受。
- 订单已被接受,但响应丢失了。
- 请求仍在处理,结果暂时未知。
超时无法区分这些情况。HTTP 本身不会让创建订单的 POST 自动变得可安全重试;保护来自 API 的具体约定。参见 RFC 9110, §9.2.2.
NotPanel 如何识别重试
request_id 是可选字段,不能为空,最长 128 个字符。idempotency_key 是兼容别名;同时提供时,以 request_id 为准。重试应保留相同账户、请求键及全部订单参数。已接受的订单会返回原订单 ID;用相同键发送不同参数会被拒绝。
不提供这两个字段时,NotPanel 会对同一账户的相同 add 请求提供 60 秒保护。较晚的重试不应依赖这个短窗口。结果未确定的请求在核查期间仍受保护。
这个窗口也会合并两次有意提交的相同购买。如需立即创建两个独立订单,请为每笔新购买分配不同的 request_id。不要为了绕过未知结果而更换请求键。
超时后保留原来的 request_id。
使用相同请求键和不变的订单详情重试。
保存找回的订单 ID;如果结果仍未确定,则继续等待。
发送前先保存购买标识
假设购买编号 8427 有一个订单行。在第一次网络请求前保存 request_id 和完整参数。下方为使用占位符和换行的示意请求;实际表单应正常编码。仅在确实要创建付费订单时发送真实参数。
POST https://notpanel.com/api/v3
Content-Type: application/x-www-form-urlencoded
key=YOUR_API_KEY
&action=add
&service=YOUR_SERVICE_ID
&link=YOUR_TARGET_URL
&quantity=YOUR_VALID_QUANTITY
&request_id=checkout-8427-line-1超时后,使用 checkout-8427-line-1 重发相同服务、目标、数量和可选字段,应用重启后也一样。收到订单 ID 后将其保存到该购买记录,再通过 status 查询。request_id 标识下单请求,不能替代 status 所需的订单 ID。
根据完整响应决定下一步
- 超时、连接中断或结果不明
- 保留原请求键和参数。限制重试次数、间隔重试,并遵守 Retry-After。次数耗尽后仍应保留未解决记录。
- REQUEST_PROCESSING 或 REQUEST_UNCONFIRMED
- 等待后只重发原请求,不要换键创建替代订单。
- REQUEST_ID_CONFLICT
- 比对已保存的参数。用原参数找回原订单;只有明确的新购买才使用新键。
- 参数、认证或请求频率错误
- 读取 error_code 和 retryable,修正参数或凭据并遵守等待时间。不要对所有错误无限自动重试。
接收客户订单前测试恢复流程
先在自己的测试环境使用模拟 API,不需要真实购买或特殊的 NotPanel 测试密钥。
- 模拟订单已接受但响应丢失,确认重试键和参数完全相同。
- 在两次尝试之间重启客户端,确认能恢复已保存的请求标识。
- 先模拟处理中响应,再模拟成功,确认只保存一个订单 ID。
- 模拟请求键冲突或不可重试的校验错误,确认自动重试停止。
- 为两笔有意提交的相同购买分配不同键。后续如需真实测试,只提交确实需要的订单,并核对订单和钱包记录。
常见问题
超时是否代表扣款两次?
不是。它只表示应用没有收到可用响应。在判定重复扣款前,应核对找回的订单和钱包记录。
NotPanel 强制要求 request_id 吗?
不要求。request_id 和 idempotency_key 都是可选字段。未提供时,同一账户的相同 add 有 60 秒保护。显式请求键让应用为每笔购买指定身份。
每次重试都应该生成新键吗?
不应该。第一次尝试前保存一个键,在订单参数不变的情况下重复使用。只有新购买才分配新键。
能用 request_id 查询 status 吗?
status 需要订单 ID。使用相同键和参数重发原 add 来找回 ID。若结果仍不确定,保存详细信息用于联系支持,不要创建另一个订单。
继续阅读: API 集成指南 · Webhook 与状态轮询 · 错误参考.



