StableOps

收银台

了解如何使用 StableOps 托管收银台创建一次性结账会话和可重复使用的付款链接,配置商户名称、图标、主题色与联系商户信息,查看支付转化漏斗,并通过经过验签的 Webhook 在链上最终确定后安全履约。

收银台适合想降低前端集成成本的场景:支付页由 StableOps 托管,负责展示链、资产、精确金额、收款地址和订单状态。商户可以从后端为每个业务订单创建一次性收银台会话,也可以在控制台创建一个可重复分享的付款链接;两种入口最终都会为每次付款生成独立支付订单,并通过同一套 Webhook 生命周期通知商户系统。

选择收款入口

入口适用场景公开地址每次付款发生什么
一次性收银台会话电商订单、发票、已经有内部订单号的业务/c/{sessionId}?client_secret=...商户后端先创建支付订单与会话,再把专属地址交给付款人
可重复使用的付款链接固定金额商品、活动报名、打赏与线下二维码/p/{slug},不包含 API 密钥或 clientSecret付款人进入支付时,系统创建新的收银台会话与独立支付订单

一次性会话可以把 merchantOrderId 和 metadata 直接绑定到现有业务对象,适合需要精确追踪某一订单的场景。付款链接保存的是一份可重复使用的收款配置,不是一个可以反复支付的订单;如果每位付款人需要不同金额、客户信息或内部订单号,应继续使用一次性会话。

一次性收银台会话

  1. 后端创建收银台会话:在你的服务端用 API 密钥调用 stableops.checkoutSessions.create,传入商户订单号、金额、可接受资产、展示标题、成功返回地址、取消返回地址,以及可选的 WalletConnect 项目 ID。
  2. 把用户跳转到收银台:创建成功后使用响应里的 checkout.url 做 303 跳转,或把 URL 返回给前端再 window.location.assign(checkout.url)。
  3. 用户在收银台付款:托管页面展示链、资产、精确金额和收款地址,并实时跟踪状态。用户可以通过浏览器钱包、手机钱包或手动转账支付。无论采用哪种方式,链上扫描器都使用相同规则匹配转账。
  4. 用 Webhook 完成业务动作:你的后端接收并验签 payment.confirmed / payment.finalized 等 Webhook 事件,再开通服务、入账或更新订单状态。不要只依赖用户跳回 successUrl,它只是前端体验,不是最终支付凭证。

你可以通过在收银台 URL 上添加 lang 参数控制页面语言,例如 ?client_secret=...&lang=es。支持的值包括 en、zh、zh-Hant、es、pt-BR、vi、id、ja。如果不传 lang,收银台会尽量匹配用户的浏览器语言,并兜底为英文。

可重复使用的付款链接

在控制台展开“收银台”菜单并打开“付款链接”页面,点击“新建付款链接”后会打开创建对话框。无需编写代码,只需填写:

  • 名称,以及可选的付款说明;
  • 固定基础金额;
  • auto 或 exact 金额分配方式;
  • 一组允许付款的链与资产,控制台会按当前沙盒或生产环境过滤可选项。

创建后,控制台会生成形如 https://pay.stableops.dev/p/{slug} 的稳定地址。你可以复制链接、在新窗口打开,或者把它编码成线下二维码。付款链接默认启用,也可以随时停用和重新启用。

管理、分享与付款人信息

在链接的“更多操作”中,可编辑名称、付款说明、跳转地址、单次支付有效期和付款人信息字段,也可复制配置创建新链接。编辑仅影响新订单;已有订单与会话保留原始配置。金额、金额分配方式和收款资产需要通过复制为新链接调整。

“高级设置”支持付款成功后跳转地址、取消付款返回地址,以及单次支付有效期:沙盒为 5–30 分钟,生产环境为 5–1440 分钟。该设置不会使可重复使用的链接本身过期。

商户可启用姓名、邮箱、业务编号和备注字段。启用后,付款人先看到选填表单,点击“继续付款”才创建订单;未启用时仍直接进入收银台。信息保存在订单的 metadata.payer 中,有填写信息的订单同时包含 metadata.payment_link_id。信息可在链接订单详情及携带订单元数据的 Webhook 中读取;开启 redact_metadata 的端点不会收到这些元数据。付款人填写的业务编号不代表身份已验证,不应据此直接授予账号权限。

“分享二维码”可选择支付页面语言、复制网址并下载二维码图片,二维码始终指向可重复使用的链接。“订单与付款人信息”可分页查看该链接的关联订单、按状态筛选,并查看已填写的信息、链上交易金额与交易哈希。关联交易可能仍在确认中或已回滚,只有 finalized 订单计入成功付款。

每次新的付款尝试都有独立订单

付款人打开 /p/{slug} 并提交已启用的信息表单(如有)后,公开页面会根据付款链接保存的配置创建一个新的收银台会话和支付订单,然后跳转到该会话的 /c/{sessionId} 页面。每次付款都有自己的:

  • 支付订单号、收银台会话号与 clientSecret;
  • 精确应付金额、候选链与收款地址;
  • 订单有效期、确认进度和最终状态。

同一浏览器标签页在当前会话有效期内刷新时,会复用该次创建请求,避免因为刷新重复占用地址。会话过期后再次打开链接,才会开始新的付款尝试。

停用付款链接只会阻止它继续创建新会话,不会取消已经生成的支付订单或收银台会话。若链接被公开传播、活动已经结束或出现异常流量,应及时停用,并检查每条链的收款地址池是否仍有足够容量。

amountMode: 'auto' 适合共享地址:只有基础金额在所有候选共享地址上都发生冲突时,系统才会按代币最小单位微调应付金额。exact 则始终使用固定金额;付款人仍必须支付页面返回的 order.amount,不能少付、多付或拆成多笔。

配置收银台

在控制台展开“收银台”菜单并打开“品牌配置”页面,可以配置以下品牌内容,并在保存前查看右侧的基础收银台预览:

设置在收银台中的用途
商户名称替换页首默认品牌名称
图标地址展示商户图标;地址必须能被付款人的浏览器公开访问
主色用于主要按钮、进度和重点交互
强调色用于悬停态及辅助品牌元素
联系商户网页地址会在新页面打开;多语言文案会按收银台当前语言通过对话框展示

多语言联系文案目前支持简体中文、繁体中文、英语、西班牙语、葡萄牙语、越南语、印度尼西亚语和日语。未填写付款人当前使用的语言时,收银台使用英文文案兜底;英文也未填写时不显示“联系商户”入口。

品牌设置按组织和环境隔离,沙盒与生产环境需要分别维护。无论会话来自后端 API 还是付款链接,创建时都会保存一份当时的品牌快照;以后修改品牌只影响新建会话,不会改变已经打开或仍在处理中的会话。将某一字段清空并保存,可以恢复该字段的默认显示。

查看收银台转化漏斗

“付款链接”页面顶部展示当前组织和环境最近 30 天的收银台漏斗。统计范围为最近 30 天创建的收银台会话,过程事件按收银台会话去重,依次包括:

  1. 打开页面:付款人打开收银台页面;
  2. 载入会话:页面成功读取收银台会话;
  3. 开始付款:付款人开始使用浏览器钱包、WalletConnect 或手动转账;
  4. 已提交交易:钱包已经提交链上交易;
  5. 完成付款:支付订单到达 finalized;
  6. 付款转化率:达到最终完成状态的订单对应会话数除以创建的会话数。

付款链接列表中的“生成会话”是该链接累计创建的会话数量,“转化率”则使用最近 30 天创建的会话及其订单当前完成状态。漏斗用于发现页面载入、钱包连接或付款提交环节的流失,不是财务账本,也不能代替 Webhook、支付订单列表与每日对账。

支持的钱包方式

收银台支付页支持以下三种支付方式,用户可根据场景自由选择。

浏览器钱包(桌面)

页面自动检测已注入的钱包提供者并连接,用户确认交易后发送。

  • EVM 链:支持 MetaMask、Rabby 等通过 window.ethereum 注入的钱包,共 12 条链。
  • Solana:支持 Phantom 等通过 window.phantom.solana 注入的钱包,主网 + devnet。
  • TRON:支持 TronLink 等通过 window.tronLink.tronWeb 注入的钱包,主网 + Nile。

手机钱包(WalletConnect)

收银台优先使用创建会话时传入的 walletConnectProjectId;未传入时,使用托管端配置的项目 ID。两者都未配置时,才不展示 WalletConnect 入口。启用后,用户从钱包列表选择钱包,通过二维码或深层链接连接并签名。支持 EVM、Solana 和 TRON 链;TRON 由钱包签名后,再由收银台广播交易。

控制台创建的付款链接不提供 WalletConnect 项目 ID 输入项,但生成的会话同样可以使用托管端配置。是否显示手机钱包入口取决于部署配置与订单支持的链,不能仅根据付款链接没有项目 ID 输入项判断。自行部署收银台时,可通过 VITE_WALLETCONNECT_PROJECT_ID 配置,兼容读取 NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID。

在手机上选择钱包后,按页面提示打开钱包并确认连接或交易,再返回原收银台查看状态。钱包未自动打开时,可使用页面提供的打开钱包入口或二维码;具体可用方式取决于所选钱包。钱包显示已发送或页面重新打开都不代表付款完成,不要因此重复转账,应等待收银台确认或由商户查询订单状态。

兼容的钱包:MetaMask、Trust Wallet、Coinbase Wallet、OKX、Binance Wallet、TokenPocket、TronLink、Rainbow、Zerion、Ledger Live,以及任意 WalletConnect 兼容钱包。收银台会按订单的链族过滤钱包;TRON 订单展示支持 TRON 的钱包:Trust Wallet、TokenPocket、TronLink。

Solana 和 TRON 的钱包支付需要 RPC 节点来构造并广播转账交易,收银台已自动处理:主网订单经 StableOps 后端 RPC 代理转发,但测试网订单(Solana Devnet、TRON Nile)直连公共 RPC 节点,免费但偶尔可能限流,如果测试网支付构造失败,稍候重试即可。

手动转账

任何场景都可用。用户从页面上复制收款地址,在自己选择的任意钱包或交易所发送,链上扫描器按收款地址匹配入金。

后端创建会话

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' }],
    expiresAt: new Date(Date.now() + 30 * 60 * 1000).toISOString(),
    title: 'StableOps Starter Plan',
    successUrl: `https://stableops.dev?result=success&orderId=${merchantOrderId}`,
    cancelUrl: `https://stableops.dev?result=canceled&orderId=${merchantOrderId}`,
    walletConnectProjectId: process.env.WALLETCONNECT_PROJECT_ID,
  },
  { idempotencyKey: 'order_123' },
)

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

参数建议

  • merchantOrderId:使用你系统里的订单号,并同时作为幂等键,避免重复创建。
  • amountMode: 'auto':让 StableOps 自动微调金额,降低共享收款地址下的撞单概率。
  • acceptedAssets:先从测试网资产开始;生产环境再切到你实际支持的主网资产。
  • successUrl / cancelUrl:只用于用户体验。最终业务状态以 Webhook 为准。
  • walletConnectProjectId:可选,可在 Reown Cloud 免费注册获取。传入后,收银台展示手机钱包入口,EVM、Solana 和 TRON 链均通过 WalletConnect 二维码或深链连接手机钱包签名:
    • EVM 和 Solana 链:MetaMask、Trust Wallet、Coinbase、OKX、Binance Wallet、Rainbow、Zerion、Ledger Live 及通用 WalletConnect。
    • TRON 链:Trust Wallet、TokenPocket、TronLink。钱包通过 WalletConnect 对转账交易签名,收银台再广播上链。
    • 不传时使用托管端项目 ID;两处都未配置时不展示 WalletConnect 入口,用户仍可用浏览器注入钱包或手动转账支付。
  • metadata:可以放套餐、用户 ID、内部订单标签等,但公开收银台不会展示订单元数据。

在线测试

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

请使用 sandbox key;它只保存在你的浏览器并直接发送给 API。生产环境请在服务端调用 API,不要在浏览器中调用。

开启时会在创建会话前为本订单导入一个确定性 burner 地址,适合 org 还没有任何收款地址的场景。若只想使用自己管理的地址,请关闭。

本收银台组件源码托管在 GitHub:github.com/StableOps/stableops-playground,欢迎下载、试用与反馈。

安全注意

  • 这个面板只用于沙盒测试。生产环境请在你的后端创建收银台会话,不要在浏览器暴露生产 API 密钥。
  • clientSecret 是打开公开支付页的凭证,只应该发送给本次付款用户。
  • 收银台页面只读取公开会话,不需要 Clerk 登录,也不会暴露订单元数据。
  • 付款链接本身不包含 API 密钥或 clientSecret,但它是公开且可重复使用的入口;任何拿到地址的人都可以发起新的付款尝试。只在预期渠道分享,并监控地址池容量与转化漏斗。
  • 停用付款链接不能撤销已经生成的支付订单。需要停止一笔现有订单时,应按支付订单自身的状态和取消规则处理。

处理 Webhook

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

这篇文档怎么样?

最后更新

本页内容