Solana Pay 集成指南(2026):扫码收款、真实的坑,和 Finality 的捷径

·8 分钟

Solana Pay 是开放、零费用的扫码支付规范——但把它集成好,比 hello-world 难得多。一支在生产环境跑着它的团队写的指南:URI 格式、三个真会咬人的坑、二维码之后才开始的活,以及一次 API 调用的捷径。

本文目录
  1. 1Solana Pay 到底是什么
  2. 2构造 URI(真代码)
  3. 3三个真会咬人的坑
  4. 4教程都不写的部分:扫码之后
  5. 5捷径:一次 API 调用,二维码已含
  6. 6FAQ

先给答案:Solana Pay 是一个开放规范(Apache-2.0,零费用,无中间人),把一笔完整的付款——收款人、金额、代币、备注——编码进一个 URI,任何 Solana 钱包扫码即付。把 URI 拼出来是一个下午的事;把支付做出来——检测、金额匹配、对账、结算——才是真正的工程。这篇两头都讲实话:怎么自己把二维码这一侧建起来、我们在 Finality 生产环境里踩过的三个坑,以及那条捷径——一次 API 调用,返回一个自带 Solana Pay 二维码、支持交易所直付、链上分账已经做完的收银台。

Solana Pay 到底是什么

规范定义了两种请求类型,分清楚它们能省你一周:

商户收银选 Transfer Request 没有悬念:不需要服务器往返,印在纸上能用,显示在手机屏上能用,贴在邮件里也能用。

构造 URI(真代码)

规范里的格式:

code
solana:<收款地址>?amount=<小数金额>&spl-token=<mint>&label=<商户名>&message=<订单号>

一个生产形状的构造函数:

ts
export function buildSolanaPayUri(opts: {
  recipient: string;        // 收款地址
  amount: string;           // 人类可读小数: "49.00" —— 不是原子量
  splToken?: string | null; // SPL mint; 省略 = 原生 SOL
  label?: string;           // 显示在钱包确认界面
  message?: string;         // 比如你的订单号
}): string {
  const p = new URLSearchParams();
  p.set("amount", opts.amount);
  if (opts.splToken) p.set("spl-token", opts.splToken);
  if (opts.label) p.set("label", opts.label);
  if (opts.message) p.set("message", opts.message);
  return `solana:${opts.recipient}?${p.toString()}`;
}

把它渲染成二维码,主流 Solana 钱包(Phantom 打头)原生就能扫。省略 spl-token,钱包转原生 SOL;带上一个 mint(比如 USDC 的),钱包会自己处理代币转账,连关联代币账户(ATA)都自动派生。

三个真会咬人的坑

这些不是纸上谈兵——每一个都是我们踩过、或者亲眼看别人踩进去的 bug 类别:

一、amount 是小数,不是原子量。规范写得很明白:用 uiAmountString,不是原始代币数量。USDC 有 6 位精度——想编码 49.00 却写成了 49000000,钱包就会礼貌地请你的顾客确认一笔四千九百万美元的付款。真正危险的地方在于:EVM 那边的对应标准 EIP-681,恰恰完全相反——它要的是原子量(wei)。如果你的收银台两个生态都支持,这是全项目最容易写反的一处。

二、裸地址二维码是一个架构级的自相矛盾。偷懒的集成只编码地址,让顾客自己填金额。可只要你的订单模型要求精确金额——任何严肃的支付系统都要求——顾客手填差一分钱,订单就永远卡在待支付,钱躺在地址里动不了。一个对金额零容忍的模型,配一个不带金额的二维码,等于设计了一台客服工单制造机。永远编码完整 URI。

三、label 和 message 不是装饰。它们是顾客在钱包确认界面上看到的东西。一笔来自陌生地址、没有任何标识的付款请求,看起来就像钓鱼;带着商户名和订单号的,看起来才像结账。label 放店名,message 放订单号——顺便也让顾客自己的账单历史变得可读。

教程都不写的部分:扫码之后

诚实地把工程量摊开。URI 是最容易的那 10%。现在顾客把 49 USDC 转到了你的地址上——你的活才刚开始:

这些没有一样是做不出来的。但它们全都是和你的产品毫无关系的通用基础设施。

捷径:一次 API 调用,二维码已含

这一层正是 Finality 卖的东西,所以把话说直白。一次调用:

bash
curl -X POST https://finality.money/v1/intents \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "chain": "solana",
    "token": "USDC",
    "amount": "49.00",
    "merchant_order_id": "ORD-3141"
  }'

返回一个专属收款地址和一个托管收银台,正确的 Solana Pay URI(小数金额、对的 mint、你的标识)已经渲染好——顾客要是选了 EVM 链,同一个收银台自动换成 EIP-681 二维码,因为它本来就覆盖五条链。然后是那些你不想自己造的部分:

而且因为金库和结算规则都活在链上,这里存在两样自己集成(或任何别家网关)给不了的东西:Solana 上真正自动扣款的订阅——计费条款焊死在顾客自控金库的地址里,不发续费邮件(架构)——以及在顾客付款交易内部直接切给分销商钱包的佣金。

FAQ

哪些钱包支持 Solana Pay 二维码?

主流 Solana 钱包基本全支持,Phantom 排第一。这个 URI 方案在手机上也可以作为深链直接点开。

顾客压根没有钱包怎么办?

一单一个专属地址意味着:交易所提现就是一次付款——顾客从币安/Coinbase 账户像普通转账一样发出来就行。在 Finality 这是开箱即用的,扫不扫码都一样。

能不花真钱测试吗?

能——用 sk_test_ 密钥建一笔沙盒付款,点"模拟支付",完整排练检测-结算-webhook 全流程,二维码也包括在内。

一次集成能顺便覆盖 EVM 链吗?

在 Finality 可以——收银台在 Solana 上吐 Solana Pay URI,在 Ethereum、Base、BNB Chain 上吐 EIP-681 URI,小数与原子量的相反约定已经替你处理好。这半句话的价值比听起来大,见第一个坑。

一段话说清 Solana Pay 是什么?

一个 URI 方案:目的地、金额、代币、label、message——编码成钱包能扫描、预填、一个动作发出的形态。它是金额进码规则的正式文法;付款本身是一笔普通的 Solana 转账。

Solana Pay 二维码怎么生成?

把 URI 编好、渲染成二维码——或者跳过手工组装:每笔 Finality 付款自带二维码,地址、金额、你的店名标签都已编入,坑也提前填了。

Solana Pay 只能收 SOL,还是也支持 USDC?

任何 SPL 代币,走 spl-token 参数——实践里的流通货币是 USDC。参数省略等于请求原生 SOL;收银台永远该写明白。

Solana Pay 付款多快确认?

它底下就是普通 Solana 转账——亚秒检测,实测。顾客手机还没放下,已支付状态已经翻过来了。

Solana Pay 交易有什么费用?

顾客付网络费——几厘钱,我们实测优先费中位数为零。商户侧是网关的份额;这里是固定 1%。

怎么验证一笔 Solana Pay 付款真的结算了?

不是信钱包的成功页——是盯链:把转账和专属地址、金额匹配上,然后对着签名的 payment.settled webhook 行动。检测才是这套集成的正活。

Solana Pay 能处理退款吗?

这个方案只负责请求付款;退款是你主动发起的普通转账——老规矩,注意交易所地址。把"退款时收集钱包地址"设计进流程。

Solana Pay 适合线下收银吗?

可以说是最合身的——柜台指南整个建在它上面:打印或屏显二维码、顾客的手机当终端、你的控制台一秒左右出确认。

Solana Pay 的 transaction request 模式是什么?

在静态转账 URI 之外,规范还支持一种服务器往返:钱包去取一笔待签交易——复杂流程里强大,收银台上过度。支付形状的集成很少需要;简单 URI 就罩得住整家店。

做 Solana Pay 检测要自己跑 RPC 节点吗?

玩具流量,公共 RPC 凑合能撑;真金流水,检测可靠性就是产品本身——我们为什么自营节点讲的就是这件事,用网关等于继承它的基础设施,而不是自建你的。

想练手就自己把 URI 拼一遍,想收款就直接跳到结果:建一笔沙盒订单,15 分钟扫出你的第一个 Solana Pay 二维码——检测、结算、webhook 都已接好,钱落在只有你能控制的钱包里。完整参考在文档和 API 测试台。

相关文章