Solana API:通过 REST 进行 SOL 和 SPL 代币支付
用普通 REST 调用创建 Solana 地址并转移 SOL 和 SPL 代币。无需 web3.js,也无需安装任何 SDK。
一个 Solana API 不应该强迫你的后端使用 JavaScript SDK。Chaingateway 把 Solana 包装成普通的 REST:你用两次 POST 请求创建地址并发送 SPL 代币,一次 GET 请求返回当前区块高度。认证方式是 Authorization 头中的 Bearer 令牌。响应是 JSON。你的 PHP、Go 或 Java 后端与 Solana 通信的方式,和与其他任何 HTTP 服务通信一样。
试用期为 7 天,无需 KYC。创建 API 密钥,在下一个区块产生之前发出你的第一个请求。
每个接口对应一项能力
RPC 提供商按能力组织 Solana 文档:节点访问在这里,流式传输在那里,Webhook 又在别的地方。Chaingateway 的 Solana 接口面故意做得更小,因为它是一个支付 API,而不是一个通用节点服务。用同样的方式呈现,是这样的:
| 能力 | 接口 | 状态 |
|---|---|---|
| 创建地址 | POST /api/v2/solana/addresses | 已上线 |
| 发送 SOL | POST /api/v2/solana/transactions | 已上线 |
| 发送 SPL 代币 | POST /api/v2/solana/transactions/SPL | 已上线 |
| 查询余额 | GET /api/v2/solana/balances/{address} | 已上线 |
| 读取链上状态 | GET /api/v2/solana/blocks/number | 已上线 |
| 存款 Webhook | — | Solana 上尚未支持;见下方轮询方案 |
每个接口都使用同一个 Bearer 令牌,X-Network: testnet 请求头可以把任意请求切换到测试环境。请求和响应结构见API 参考文档。
简单的交易
用简单的 JSON payload 发送 SOL 和 SPL 代币。Solana 的出块速度远低于一秒,因此一笔付款通常在用户还盯着加载动画时就已经确认完成。
安全的地址处理
Solana 地址是以 base58 编码的 32 字节公钥,API 会在构建任何交易之前对其进行校验。架构是非托管的:你资金的密钥属于你自己。
解码后的查询
交易数据以结构化 JSON 返回,而不是 base64 编码的二进制块。代币转账无需接触原始指令数据即可读取。
Webhook(IPN)
先坦白:Solana 上目前还没有 Webhook。改用轮询来追踪存款;GET /api/v2/solana/blocks/number 会告诉你新区块何时到达,方便你控制检查节奏,GET /api/v2/solana/balances/{address} 则回答是否有资金到账。在 Ethereum、BSC、Polygon、Arbitrum、TRON 和 Bitcoin 上,存款 Webhook 今天就已经可用。
通过 REST 使用 Solana,无需 web3.js
进入 Solana 的官方途径是 JSON-RPC,文档见 solana.com/docs/rpc。它暴露的是节点协议本身:诸如 getLatestBlockhash 和 sendTransaction 之类的方法,外加一个让它们可用的客户端库。要以这种方式发送一笔 SPL 代币,你的代码需要在过期前获取一个最新的 blockhash,解析收款人的 associated token account(如果尚不存在则创建它),然后构建、签名并序列化交易。在 JavaScript 中,web3.js 和 spl-token 包会替你完成这些工作。在其他任何语言中,你基本上要靠自己。
Chaingateway 用一次 HTTP 调用取代了这一切。API 在服务器端解析 token account 并构建交易,你的后端完全不需要导入任何 Solana SDK。如果你需要原始的链上访问能力用于分析或自定义程序,RPC 提供商才是正确的工具。对支付而言,REST 更简短,而更短的代码出错的地方也更少。
Mint、Token Account 和 ATA:为什么 Solana 转账不一样
如果你来自 Ethereum、BSC 或 Polygon,Solana 中最可能咬你一口的部分不是速度,也不是手续费。而是账户模型。
EVM 模型
代币余额是代币合约自身存储内部的一条记录。你的地址「持有」USDT,是因为合约的内部表如此记载。把代币发送到一个全新的钱包,只是在那张表里新增一行;收款方并不需要以任何特殊方式在链上「存在」。
Solana 模型
Solana 把同样的概念拆分成独立的账户。一种代币由它的 mint 账户定义,其中存储着总供应量和小数位数。余额存放在 token account 中,每一种「钱包+mint」组合对应一个 token account,标准形式是 associated token account(ATA):它的地址由钱包地址和 mint 地址确定性推导得出。你的钱包本身并不包含 USDC。它拥有的是一个单独的、包含 USDC 的账户。
对支付的两个影响
- ATA 必须先存在,代币才能进入它。如果你的收款人从未持有过该代币,就需要在链上创建这个账户,而创建需要一笔押金,使其达到免租(rent-exempt)状态:截至 2026 年年中,按照 Solana 官方文档为 0.00203928 SOL。实际操作中,发送方的交易会创建并资助这个缺失的账户。
- 转账是在 token account 之间移动价值,而不是在钱包地址之间。天真地以钱包地址为目标的代码会失败,这也是为什么 SPL 转账指令需要同时提供两个 token account,加上 mint 及其小数位数用于校验。
这正是 Chaingateway 在服务器端处理的记账工作。你传入钱包地址和代币的 mint;API 会推导出 token account 并构建一笔有效的转账。你的后端永远不需要了解什么是 program-derived address——这正是它的意义所在。
REST 与 web3.js:同一笔转账,两种写法
以下是用 web3.js 和 spl-token 包发送 10 USDC 的样子:
import { Connection, PublicKey } from "@solana/web3.js";
import {
getOrCreateAssociatedTokenAccount,
transferChecked,
} from "@solana/spl-token";
const connection = new Connection("https://your-rpc-endpoint");
const usdc = new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
const senderAta = await getOrCreateAssociatedTokenAccount(
connection, payer, usdc, payer.publicKey
);
const recipientAta = await getOrCreateAssociatedTokenAccount(
connection, payer, usdc, new PublicKey(recipient)
);
await transferChecked(
connection, payer,
senderAta.address, usdc, recipientAta.address,
payer, 10_000_000, 6 // 10 USDC,6 位小数
);一次调用即可取代上面那套 ATA 记账工作——创建账户,在 devnet 上试一试。
快速入门:三次请求完成第一笔 SPL 转账
创建一个地址:
curl -X POST https://app.chaingateway.io/api/v2/solana/addresses \
-H "Authorization: Bearer $CHAINGATEWAY_API_KEY"curl https://app.chaingateway.io/api/v2/solana/blocks/number \
-H "Authorization: Bearer $CHAINGATEWAY_API_KEY"curl -X POST https://app.chaingateway.io/api/v2/solana/transactions/SPL \
-H "Authorization: Bearer $CHAINGATEWAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contractaddress": "TokenMintAddress",
"from": "YourSenderAddress",
"to": "RecipientAddress",
"amount": 10,
"privatekey": "YourSenderPrivateKey"
}'Solana 数据一览
以下数字已对照 Solana 官方文档核实,时间截至 2026 年 7 月初。
一个 slot——单个验证者可以产出一个区块的时间窗口——被设定为大约 400 毫秒,实际中大致在 400 到 600 毫秒之间波动。正是这个节奏,使得每一到两秒轮询一次存款,也不会明显落后于链的进度。
基础交易手续费为每个签名 5,000 lamports,即 0.000005 SOL。其中一半被燃烧,一半归出块者所有。在此之上还有一个可选的优先费,以每计算单元的微 lamport 计价;默认为零,在网络繁忙时可以购买调度优先权。对支付类负载而言,实际的结论很简单:手续费小到即使是一美元的交易,也会被你的利润率完全吸收。
在 Solana 上,确认(confirmation)和最终确定(finality)是两回事,这个区别对你如何为存款入账很重要。一笔交易通常在一到两秒内被确认,即绝大多数验证者已经对其所在区块投票。截至 2026 年年中,完全的最终确定大约需要 12.8 秒。计划于 2026 年末推出的 Alpenglow 共识升级,目标是把最终确定时间压缩到大约 100 到 150 毫秒;在它正式上线之前,请把这个数字当作已宣布的计划,而不是当前已实现的特性。今天合理的策略是:小额付款在确认时就入账,大额付款则多等那十几秒直到最终确定。
无需 Webhook 追踪存款
Chaingateway 的 API 目前还没有 Solana 存款 Webhook 接口。检测方式改为轮询两个接口:GET /api/v2/solana/blocks/number 用于追踪新区块,GET /api/v2/solana/balances/{address} 用于检查是否有资金到账。由于出块速度低于一秒,两秒的轮询间隔仍然能在几秒内把付款显示为已收到。
一个有纪律的轮询循环运行成本很低。记录你上次处理到的区块高度,每当它发生变化时,检查你的存款地址——或者用 GET /api/v2/solana/balances/{address}/tokens/{mint} 检查某个特定的 SPL 代币——并将发现的结果与未完成的订单匹配。
延迟的代价没有听起来那么大。Solana 的出块速度远低于一秒,因此即使是两秒的轮询间隔,也意味着客户在发送后几秒内就能看到「已付款」。整个循环在任何语言中都只是几十行代码,可以作为定时任务或后台工作进程运行。当你后续把同样的流程扩展到支持 Webhook 的链上时,记账逻辑保持不变;变化的只是触发方式,从拉取变为推送。
在 Solana 上接受 USDC:一个完整示例
USDC 是让 Solana 成为一个真正结算网络的支付渠道,因此它值得一个具体的实操讲解。主网上的 mint 地址是 EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v,由 Circle 发行;任何其他自称 USDC 的都不是。
接收端:当客户结账时,用 POST /api/v2/solana/addresses 创建一个全新地址,并将它存入该订单。展示地址和金额,让客户从任意钱包或交易所付款。你在前一节中构建的轮询循环会捕获这笔传入转账,把接收地址与订单匹配,并将其切换为已付款。在 400 毫秒的 slot 节奏下,「客户点击发送」和「你的数据库显示已付款」之间的间隔只有几秒钟,其中大部分时间是你自己设置的轮询间隔。
用唯一约束记录每一笔已入账存款的交易签名。轮询循环会被重启、回填、重新运行,而数据库层面的幂等性能确保这些操作都不会导致订单被重复入账。
付款端与之对称。一笔付款只需一次 POST /api/v2/solana/transactions/SPL 调用,contractaddress 填 USDC 的 mint,"amount": 10 用易读的数值表示;API 会替你应用 USDC 的六位小数。在发送地址上保留适量的 SOL 余额:每个签名 0.000005 SOL 用于手续费,每当需要为收款人创建 token account 时再加 0.00203928 SOL。这两个金额都足够小,一次充值就能覆盖数月的付款。
相比银行卡通道,你获得的是几秒内完成结算、没有拒付机制,而你放弃的是撤销错误操作的能力。API 在构建交易前执行的地址校验在这里能帮上忙,但你自己的确认页面同样重要。
Solana 上的任意代币,包括你自己的代币
SPL 是 Solana 的代币标准,API 对每一个 SPL mint 都一视同仁。USDC 和 USDT 开箱即用,自动应用小数位。如果你铸造了自己的代币,把它的 mint 地址传给同一个接口,它的表现会和主流代币一样。由于 Chaingateway 在各链上使用同一套接口结构,上面的 Solana 代码只需替换 URL 中的链名和代币后缀即可移植到 Ethereum、BSC 或 Polygon:/solana/transactions/SPL 变为 /ethereum/transactions/erc20。
为什么开发者选择 Solana
Solana 并行执行交易,而不是严格按顺序一笔笔处理,这正是其吞吐量的来源。手续费足够低,使得支付极小额款项依然划算,确认速度也足够快,收银页面可以直接等待它完成。Solana 上的 USDC 交易量已经把这条链变成了一个真正的结算网络,围绕它的开发者热度也在多个市场周期中保持了下来。
Testnet、Devnet 与 X-Network 请求头
Solana 有两个公共测试集群,它们的名字容易让人混淆。Devnet 是面向应用开发者的日常沙盒:可以从水龙头空投免费获取 SOL,其上的一切都没有实际价值。Testnet 主要供验证者和核心贡献者在负载下测试新版本使用。如果你用过以太坊的 Sepolia,Devnet 在精神上是最接近的等价物。
使用 Chaingateway 时,你完全不需要管理集群 URL。为任意请求添加 X-Network: testnet 请求头,它就会运行在测试环境中;去掉它,同样的请求就变成一次主网调用。不需要第二个 API 密钥,也不需要单独的账户。
把测试运行用在那些在主网上会让人痛苦的场景上:向一个从未持有过该代币的地址付款(涉及创建 token account 的路径)、在轮询循环运行中途重启它,以及重复提交同一笔付款。这些场景每一个都只需几分钟就能演练完成,而如果你第一次遇到它们是在生产环境中,那就会是一次真实的事故。
当请求失败时
API 用普通的 HTTP 状态码报告问题,因此你的错误处理逻辑不需要针对 Solana 做任何特殊处理。
401 表示 Bearer 令牌缺失或错误。4xx 范围内的错误属于校验失败,例如一个无法按 base58 解码的地址或缺失的字段;JSON 响应体会说明需要修正什么,在不改变 payload 的情况下重试没有意义。429 表示你已达到套餐的速率限制;放慢速度,并按区块高度的节奏而不是紧密循环来安排存款轮询。更高限额的套餐见定价页面。
5xx 范围内的服务器错误对读操作可以放心重试。对代币发送操作则要更谨慎:超时之后你无法确定交易是否已被广播,而 Solana 在这方面目前还没有 Webhook 记录可查。在重新提交之前,先检查你自己的记录以及该地址最近的转账情况,并为每一笔计划中的付款保留一条数据库记录,这样即使你的工作进程被重新运行,也不会重复发送。
把完整的响应体连同你的请求一起记录下来。每个接口的状态码和错误结构见API 参考文档。
覆盖各种应用场景
最常见的模式是接受支付:为每位客户分配一个存款地址,轮询传入的 SPL 转账,并将订单标记为已付款,几秒内即可结算,手续费小到在你的利润率计算中可以忽略。第二种模式是钱包运营:平台通过同一小组接口,为大量用户管理存款和提现。
同样这些基础构件也能处理空投和代币发行的付款自动化、订阅计费的周期性转账,以及跨境支付——在这些场景下,替代方案是一条要花上好几天、还会抽走一定百分比的代理银行链条。
三步完成集成
获取你的 API 密钥。注册后密钥会立即出现在你的仪表盘中。7 天试用无需 KYC。
发出你的第一个请求。快速入门指南涵盖了认证方式和你的第一次调用。
设置存款追踪并上线。在 Solana 上,这意味着按区块高度节奏轮询;在其他链上你可以切换到 Webhook。运行正常后,移除 X-Network: testnet 请求头,同一份代码即可运行在主网上。
各条链支持哪些功能
Solana 是目前唯一还没有存款 Webhook 的链,这也是本页下方该列显示破折号的原因。以下是全部七条链的完整接口能力对比。
| 链 | 地址 | 代币转账 | 存款 Webhook |
|---|---|---|---|
| Bitcoin | POST /api/v2/bitcoin/wallets/{wallet}/addresses | —(无代币标准) | GET /api/v2/bitcoin/webhooks/notifications |
| Ethereum | POST /api/v2/ethereum/addresses/import | ERC-20:POST /api/v2/ethereum/transactions/erc20 | GET /api/v2/ethereum/webhooks/notifications |
| TRON | POST /api/v2/tron/addresses/import | TRC-20 和 TRC-10:POST /api/v2/tron/transactions/trc20 和 .../trc10 | GET /api/v2/tron/webhooks/notifications |
| Solana | POST /api/v2/solana/addresses | SPL:POST /api/v2/solana/transactions/SPL | — |
| BNB Smart Chain | POST /api/v2/bsc/addresses/import | BEP-20:POST /api/v2/bsc/transactions/bep20 | GET /api/v2/bsc/webhooks/notifications |
| Polygon | POST /api/v2/polygon/addresses/import | ERC-20:POST /api/v2/polygon/transactions/erc20 | GET /api/v2/polygon/webhooks/notifications |
| Arbitrum | POST /api/v2/arbitrum/addresses/import | ERC-20:POST /api/v2/arbitrum/transactions/erc20 | GET /api/v2/arbitrum/webhooks/notifications |
正确理解此表需要两点说明。第一:TRON 是平台上集成最深的链。除上述路由外,参考文档还记录了质押(POST /api/v2/tron/freeze 和 /delegate)、链参数,以及一对自签名接口——/transactions/trc20/build 用于构建交易,/transactions/broadcast 用于提交本地签名后的交易。如果你的合规团队坚持要求私钥永远不离开你的服务器,这种 build-and-broadcast 模式就是你的方案。
第二:表格中的破折号表示当前参考文档尚未记录该单元格对应的 v2 路由,并不意味着该网络是二等公民。Bitcoin 没有代币标准,因此代币列为空——原生 BTC 通过自己的钱包模型运行:使用 POST /api/v2/bitcoin/wallets 创建密码加密的钱包,在其下派生存款地址,并通过 POST /api/v2/bitcoin/transactions 发送。Solana 的参考文档涵盖地址创建、SOL 和 SPL 转账,以及余额和区块查询,但尚无 Webhook。此处未列出的内容,请参阅 API 参考文档 获取当前状态。