跳到正文

生产运营

安全处理 notify、恢复、终局验证、对账、密钥轮换和支付事件。

生产支付体验不能只依赖一次成功的 pay() 响应。履约逻辑必须能处理超时、重复请求、延迟确认和 webhook 丢失。

证据优先级

证据正确用途不能用于
付款客户端结果即时 UX 和上传证据单独触发不可逆履约
Notify 事件快速唤醒后端验证器财务终局性
Signed receipt验证网关输出并绑定上下文取代链上验证
链状态确认转账和终局性商户订单语义
商户数据库幂等履约与业务策略在没有证据时声明转账

恢复丢失的成功响应

TypeScript
import { recoverSettlement } from 'x402-paysdk/pay';const recovered = await recoverSettlement({ gateway: 'https://pay.example.com', refId, paymentPayload, txHash, signedOffer});if (recovered.recovered) { await submitEvidence(recovered.txHash, recovered.signedReceipt, recovered.receipt);}

恢复只检查链上证据并尝试重建收据,不会再次调用 /settle。原始 payment payload 属于可重放敏感数据,只能在必要的最短时间内保存,且绝不能进入日志。

从链历史对账

TypeScript
import { reconcile } from 'x402-paysdk/merchant';const report = await reconcile(merchant, { payTo, fromBlock: lastReconciledBlock, limit: 200, receipts: archivedPaymentReceipts, refundReceipts: archivedRefundReceipts, minConfirmations: 3, verifyChain: true});for (const anomaly of report.anomalies) { await incidentQueue.enqueue(anomaly);}

只有在报告和业务更新都完成持久化后,才能把 checkpoint 推进到 report.lastBlock

轮换凭据

TypeScript
import { rotateMerchantKey, revokeOldMerchantKey } from 'x402-paysdk/merchant';const rotated = await rotateMerchantKey(merchant, { keyType: 'notifyHmacKey' });await secrets.storeNotifyKey(rotated.keyId!, rotated.newKey);// 经过配置的重叠窗口后:await revokeOldMerchantKey(merchant, { keyType: 'notifyHmacKey' });

API key 与 notify key 必须独立轮换。Notify 重叠期应同时接受新旧 key id,随后显式撤销旧 key。

生产门槛

  • MerchantClient 只能存在于后端模块。
  • Notify 重放保护使用共享原子 nonce store。
  • 限制 /txs 范围、RPC timeout、响应大小和重试次数。
  • 只有同一精确支付上下文的重试才能复用 paymentId
  • 履约写入和支付结算分别重试。
  • 收据对、交易哈希和订单一起归档。
  • 监控无收据转账、无转账收据、上下文不匹配和退款累计不一致。
  • 没有事务型存储时不要启用 order mode。

证据发生冲突时应停止履约,保留 ref snapshot、收据对、交易哈希、订单预期上下文和有界链响应。不能通过接受 notify 数据或发起直接转账来“修复”问题。