StableOps
SDK

TypeScript API SDK

瞭解如何安裝和設定 @stableops/api-sdk,在 TypeScript 伺服器端安全初始化用戶端,建立與查詢付款訂單,管理收款地址和 Webhook,並正確設定超時、重試、冪等鍵與錯誤處理,以型別安全的方式呼叫 StableOps 介面。

安裝

pnpm add @stableops/api-sdk

預設 API Client 面向 Node 18+ 與提供全域性 fetchAbortControllercrypto.randomUUID 的 Edge Runtime。Webhook 驗籤與 Mock Server 是 Node.js 專用入口。

想看可執行的完整示例?

Playground 在瀏覽器裡串起「建單 → 錢包支付 → 確認 → finalized」全流程,並附帶可閱讀的原始碼。

設定

import { StableOps } from '@stableops/api-sdk'

const client = new StableOps({
  apiKey: process.env.STABLEOPS_API_KEY!,
  // 可選。注入自定義 fetch(msw、undici、edge fetch 等)。
  fetch: globalThis.fetch,
})

付款訂單

const order = await client.paymentOrders.create(
  {
    merchantOrderId: 'sub_89231_2026_06',
    amount: '49.00',
    acceptedAssets: [
      { chain: 'base', asset: 'USDC' },
      { chain: 'tron', asset: 'USDT' },
    ],
    // 30 分鐘後未支付自動過期,訂單進入 expired 並釋放地址。
    expiresAt: new Date(Date.now() + 30 * 60 * 1000).toISOString(),
  },
  { idempotencyKey: crypto.randomUUID() },
)

await client.paymentOrders.retrieve(order.id)
await client.paymentOrders.list({ status: 'detected', limit: 50 })
await client.paymentOrders.cancel(order.id)

paymentOrders.create 始終需要 idempotencyKey。建議用訂單 id 派生的 UUID, worker 重試時落到同一記錄。amount 是人類可讀的十進位制字串(例如 "49.00"), 應保持字串形式或使用十進位制定點庫處理,不要直接用 Number(amount)

可選 amountMode: 'auto' 讓伺服器端把金額微調到唯一(SHARED 地址免手動錯開金額)。 settlementAsset 由伺服器端按 acceptedAssets 推導,建立時無需傳入。

Checkout Sessions(託管結帳頁)

checkoutSessions.create 返回一個託管支付頁(WalletConnect),把使用者跳轉到 session.url 即可。

const session = await client.checkoutSessions.create(
  {
    merchantOrderId: 'sub_89231_2026_06',
    amount: '49.00',
    acceptedAssets: [{ chain: 'base', asset: 'USDC' }],
    expiresAt: new Date(Date.now() + 30 * 60 * 1000).toISOString(),
    title: 'Pro 方案',
    successUrl: 'https://your-app.example.com/pay/success',
    cancelUrl: 'https://your-app.example.com/pay/cancel',
  },
  { idempotencyKey: crypto.randomUUID() },
)

console.log(session.url) // 跳轉使用者到此連結完成支付

Webhook 端點

const endpoint = await client.webhooks.createEndpoint({
  url: 'https://your-app.example.com/hooks/stableops',
  enabledEvents: ['payment.detected', 'payment.confirmed', 'payment.finalized'],
})

// endpoint.secret 只在建立/輪換時出現一次,請妥善儲存。
await client.webhooks.rotateSecret(endpoint.id)

投遞與重放:client.webhooks.listDeliveries(...)replay(endpointId, eventId)replayDelivery(deliveryId)replayDeadLetters({ endpointId, limit })

錯誤

所有非 2xx 都會拋 StableOpsError,帶 .status / .code / .message / .details

import { StableOpsError } from '@stableops/api-sdk'

try {
  await client.paymentOrders.create(input, { idempotencyKey: key })
} catch (err) {
  if (err instanceof StableOpsError && err.status === 409) {
    // Idempotency-key 被相同 key 不同 body 複用
  }
  throw err
}

本地 Mock 服務

SDK 自帶一個程序內 Mock,適合契約測試與文件示例:

import { StableOps } from '@stableops/api-sdk'
import { MockServer } from '@stableops/api-sdk/mock'
import { verifySignature } from '@stableops/api-sdk/webhooks'

const mock = new MockServer()
const { url } = await mock.listen()

const client = new StableOps({ baseUrl: url })
const order = await client.paymentOrders.create(
  {
    merchantOrderId: 'mock-order-1',
    amount: '49.00',
    acceptedAssets: [{ chain: 'base', asset: 'USDC' }],
    expiresAt: new Date(Date.now() + 30 * 60 * 1000).toISOString(),
  },
  { idempotencyKey: 'mock-order-1' },
)

const endpoint = await client.webhooks.createEndpoint({
  url: 'https://example.com/webhooks/stableops',
  enabledEvents: ['payment.detected'],
})

const fixture = mock.buildSignedFixture(endpoint.id, 'payment.detected', {
  id: order.id,
})
verifySignature({
  secret: fixture.secret,
  header: fixture.header,
  rawBody: fixture.rawBody,
})

await mock.close()

Mock 只實現 SDK 契約測試所需的最小介面:payment orders、webhook endpoints、 以及簽名 fixture 構造。

這篇文件怎麼樣?

最後更新

本頁內容