StableOps
概念

Payment Orders

支付单的资源模型与生命周期。

支付单(payment order)表示「请客户向某条链上的指定地址打一笔具体金额」。 StableOps 负责分配地址、监听链上、追踪确认数、并在每次状态变化时发出签名 Webhook。

生命周期

created -> detected -> confirmed -> finalized
   |          |            |
expired   reverted     reverted
   |
canceled
  • created:地址已分配,等待入账。
  • detected:链上看到匹配的转账。
  • confirmed:达到该链的确认阈值。
  • finalized:达到 finality 阈值,履约最稳的节点。
  • expired:超过过期时间仍未匹配到转账。
  • canceled:仍处于 created(尚未检测到任何入账)时被人工取消。
  • reverted:receipt 失败,或 block hash 不再与存储的事件匹配。

创建订单

const order = await client.paymentOrders.create(
  {
    merchantOrderId: 'order_123',
    amount: '10.00',
    settlementAsset: 'USDC',
    acceptedAssets: [
      { chain: 'base', asset: 'USDC' },
      { chain: 'ethereum', asset: 'USDC' },
    ],
    expiresAt: new Date(Date.now() + 30 * 60 * 1000).toISOString(),
    metadata: { customerId: 'cus_123' },
  },
  { idempotencyKey: 'order_123:create-payment-order' },
)

console.log(order.paymentInstructions)
// [
//   { chain: 'base', asset: 'USDC', address: '0x...' },
//   { chain: 'ethereum', asset: 'USDC', address: '0x...' },
// ]

amount 是资产单位的十进制字符串。链上事件携带最小单位的整数字符串,StableOps 在 内部按代币的 decimals 转换后再做匹配。

地址分配

单地址(single)模式:每个未结订单独占一个可用地址,直到 finalized / reverted / expired / canceled。 共享(shared)模式:一个地址可同时供多个未结订单使用,按 链 + 资产 + 组织 + 环境 + 金额 精确匹配。

创建订单时,StableOps 会按 acceptedAssets 里的每条 (链, 资产) 组合各预分配一个 可用候选地址,写进 paymentInstructions。订单进入终态(finalized / reverted / expired / canceled)时,仍未被使用的候选地址会被释放回池子。

取消订单

只有 created 状态的订单可以调用 cancel。一旦订单进入 detected / confirmed / finalized 就不能再取消——退款必须走线下流程。取消会把订单上仍占用的候选 地址释放回 available

幂等与唯一性

Idempotency-Key 控制请求重放;merchantOrderId 是独立的业务引用,在组织 + 环境内必须 唯一。用同一个 merchantOrderId 配新的 idempotency key 再开单会得到冲突,而不是上一次的响应。

Webhook

常见事件类型:

  • payment_order.created
  • payment.detected
  • payment.confirmed
  • payment.finalized
  • payment.expired
  • payment.reverted

除非业务明确接受 payment.confirmed 后还可能发生回滚的风险,否则请在 payment.finalized 完成履约。

本页内容