StableOps

收银台

用托管收银台承接稳定币支付,商户后端创建会话后将用户跳转到支付页。

收银台适合想降低前端集成成本的场景:你的后端创建收银台会话,然后把用户跳转到 StableOps 托管支付页;支付页展示链、资产、收款地址和订单状态。这样商户侧只需要处理 创建会话接收 webhook,不用自己拼支付 UI。

使用方式

  1. 后端创建收银台会话:在你的服务端用 API key 调用 stableops.checkoutSessions.create,传入商户订单号、金额、可接受资产、展示标题、成功返回地址和取消返回地址。
  2. 把用户跳转到收银台:创建成功后使用响应里的 checkout.url 做 303 跳转,或把 URL 返回给前端再 window.location.assign(checkout.url)
  3. 用户在收银台付款:托管页面展示链、资产、准确金额和收款地址,并实时跟踪状态。用户可以用浏览器钱包支付——页面连接已注入的钱包,支持自动或手动选择网络——也可以用手动转账复制地址,从任意钱包或交易所发送。两种方式 scanner 都按收款地址匹配入金。
  4. 用 Webhook 完成业务动作:你的后端接收并验签 payment.confirmed / payment.finalizedWebhook 事件,再开通服务、入账或更新订单状态。不要只依赖用户跳回 successUrl,它只是前端体验,不是最终支付凭证。

后端创建会话

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

const stableops = new StableOps({
  apiKey: process.env.STABLEOPS_API_KEY!,
})

const merchantOrderId = 'order_123'
const checkout = await stableops.checkoutSessions.create(
  {
    merchantOrderId,
    amount: '49.00',
    amountMode: 'auto',
    acceptedAssets: [{ chain: 'base-sepolia', asset: 'USDC' }],
    title: 'Acme Pro',
    successUrl: `https://app.example.com/success?orderId=${merchantOrderId}`,
    cancelUrl: `https://app.example.com/billing?orderId=${merchantOrderId}`,
  },
  { idempotencyKey: 'order_123' },
)

return Response.redirect(checkout.url!, 303)

参数建议

  • merchantOrderId:使用你系统里的订单号,并同时作为幂等键,避免重复创建。
  • amountMode: 'auto':让 StableOps 自动微调金额,降低共享收款地址下的撞单概率。
  • acceptedAssets:先从测试网资产开始;生产环境再切到你实际支持的主网资产。
  • successUrl / cancelUrl:只用于用户体验。最终业务状态以 webhook 为准。
  • metadata:可以放套餐、用户 ID、内部订单标签等,但公开收银台不会展示订单元数据。

在线测试

下面的测试面板会直接在浏览器里使用你的 sandbox API key 创建收银台会话,并跳转到公开收银台页面。你可以自定义商户订单号、金额、标题、描述、返回地址和订单元数据,方便验证商户侧参数会如何进入支付页。

仅用于文档测试,密钥只保存在当前浏览器。生产环境请在后端创建收银台会话。

安全注意

  • 这个面板只用于 sandbox 测试。生产环境请在你的后端创建收银台会话,不要在浏览器暴露 live API key。
  • clientSecret 是打开公开支付页的凭证,只应该发送给本次付款用户。
  • 收银台页面只读取公开会话,不需要 Clerk 登录,也不会暴露订单元数据。

处理 Webhook

收银台与 SDK 流程走的是同一套支付订单,支付状态始终通过 Webhook 到达——不要只信任 successUrl 跳转。

这篇文档怎么样?

最后更新

本页内容