加密支付 Webhook:工作原理与构建方法
本文说明加密支付 Webhook 如何检测充值、如何校验签名、如何处理重试与重复事件,并介绍上线前如何测试接收端点、监控失败通知,同时说明为何轮询只应作为低频的兜底手段,以及在 Chaingateway 中的具体设置步骤。
审核: Maurice Sobiera

加密支付 Webhook 是区块链服务在链上发生某事时向您的服务器发送的 HTTP 请求,例如客户地址收到一笔充值。您无需每隔几秒询问网络是否有付款到账,只需向服务商提供一个 URL,由服务商回调您。
要在生产环境中运行,您需要四样东西:一个公开的端点、签名校验、对重复事件的幂等处理,以及针对漏送投递的备用机制。本指南逐一介绍这些内容。
要点速览
- 当付款或钱包事件发生时,Webhook 会向您的服务器推送事件,您因此无需持续轮询,也就减少了对系统造成的负载。
- 在信任请求中的任何字段之前,先校验其签名。使用 Chaingateway 时,签名只覆盖交易 ID,因此金额和收款方需要您自行核对。
- 尽快返回 2xx 响应,然后在后台任务中完成实际工作。
- 假定每个事件都可能重复送达:保存事件 ID,并让订单更新具备幂等性。
- 为待处理付款保留一个低频的对账任务。Chaingateway 不会自动重试失败的通知,否则一次漏送就会让订单卡住。
什么是加密支付 Webhook?
Webhook 就是回调。您注册一个 URL,并告诉服务商您关心哪些事件。事件发生时,服务商会发送一个 POST 请求,其 JSON 正文描述该事件。对于加密支付,这些事件通常是转入受监控地址的转账、转出转账,或合约上的代币转账。

另一种方式是轮询。您的服务器按计时器调用 API,并将结果与上一次看到的内容进行比较。轮询编写简单,但运行起来十分浪费。每个返回空结果的请求都会消耗速率限制、计算资源和延迟,而付款与您做出反应之间的延迟,就等于您设定的时间间隔。在多条链和成千上万个客户地址的情况下,请求数量会迅速成倍增长。
Webhook 则反转了方向。服务商监控链上数据,将交易与您订阅的地址进行匹配,并只通知您一次。反应时间缩短到几秒,而您自己的基础设施在有事情需要处理之前保持空闲。我们在如何自动处理充值的 Webhook 文章中对这一论点有更详细的阐述。
Webhook 与轮询一览
| 比较项 | 轮询 | Webhook |
|---|---|---|
| 由谁发起交换 | 您的服务器 | 服务商 |
| 反应时间 | 与您的时间间隔一样慢 | 接近实时 |
| 浪费的请求 | 大部分请求 | 没有 |
| 成本随以下因素增长 | 地址数量乘以频率 | 实际事件的数量 |
| 故障模式 | 发现过晚 | 漏送或重复送达 |
| 最佳用途 | 对账与安全兜底 | 主要信号 |
最后一行给出了实际的答案。Webhook 应作为主要信号,而轮询应作为低频的兜底,只检查仍处于待处理状态的付款。轮询只针对仍待付款的账单进行检查,这样漏送的投递可以在几分钟内被发现,请求数量也保持在较低水平。
Webhook 如何检测加密支付?
服务商一侧是您看不到的部分,但理解它有助于解释您在测试中遇到的大部分行为。
- 订阅。您创建钱包或注册地址,然后通过服务商的 API 为其注册 Webhook。该订阅包含您的回调 URL,以及发送方、接收方、合约地址和交易类型等过滤条件。
- 监控。服务商为每条受支持的链运行节点,并读取每一个新区块。每笔交易都会与订阅进行匹配;对于代币,则与合约转账日志进行匹配。
- 解码。原始链上数据并不便于使用。以太坊上的代币转账是一条经过编码的日志条目,而比特币使用的是输入与输出,而非发送方与接收方。服务商会将其转换为可读的负载。
- 投递。服务商将负载发送到您的 URL。如果您的服务器未能返回成功状态码,接下来会发生什么取决于服务商。有些服务商会按计划重试。Chaingateway 不会自动重试:它会列出失败的通知,由您逐一请求重新发送。
Chaingateway 的通知包含以下字段:id、webhook_id、from、to、blocknumber、datetime、type、contractaddress、tokenid、txid 和 amount。以太坊、BNB Smart Chain、Polygon、Arbitrum 和 Tron 使用相同的字段名称。比特币 Webhook 仅按发送方和接收方过滤。Solana 不提供 Webhook。支持 ERC-20、BEP-20 和 TRC-20 等代币标准,这一点很重要,因为现实中的大多数付款是稳定币转账,而非原生币。
值得订阅的事件
先从窄范围开始。在 Chaingateway 中,Webhook 由过滤条件定义,因此每种事件类型都对应一组过滤条件组合:
- 转入客户充值地址的转账使用
to。这是为账户入账或将账单标记为已付款的核心事件。 - 转出转账使用
from,例如用于查看付款或归集何时上链。 - 代币转账使用
type(如ERC20或TRC20)加上contractaddress。 - NFT 转账使用
token_id字段,并搭配 ERC721 或 TRC721 类型。 - 可选的
reference字段最多可包含 255 个字符,让您能够将 Webhook 与自己系统中的订单或客户关联。
通知表示已看到符合过滤条件的交易。您是否将其视为最终到账,由您自己的策略决定,确认深度一节对此有所说明。
我们关于无需轮询的 Polygon Webhook的文章展示了单条链上的具体做法。
如何设置并处理 Webhook 接收端点?
接收端点就是您服务器上的一条普通 HTTPS 路由。演示与生产环境处理程序之间的区别,主要体现在几个习惯上。
端点要求
该 URL 必须能通过 HTTPS 从公共互联网访问。本地地址和私有网络无法接收调用,因此在开发阶段,您需要一个能暴露本地端口的隧道。该路由应专用于 Webhook,只接受 POST 请求,并且不要将其置于会拒绝来自机器请求的登录页面或 CSRF 中间件之后。
处理程序应快速响应。常见的做法,例如 Stripe 的 Webhook 文档所建议的,是在任何可能超时的复杂逻辑之前,尽快返回成功的状态码。这里的成功指 RFC 9110 定义的 2xx 状态码。加密事件同样适用这一规则。如果您在响应之前需要更新数据库、发送邮件并调用会计系统,那么某个缓慢的下游服务就可能让服务商将本次投递视为失败。
一种可靠的模式如下:
- 读取请求正文。
- 校验签名。
- 将事件及其 ID 写入队列或事件表。
- 返回 200。
- 由工作进程处理排队中的事件。
如何校验 Webhook 签名?
任何找到您 URL 的人都可以向其发送 JSON。如果您的处理程序因为某个请求声称有充值到账而为账户入账,那么伪造的请求就等同于盗窃。签名校验可以关闭这扇门。
典型方案是 HMAC,由 RFC 2104 定义。服务商使用一个只有您和它知道的密钥计算哈希值,并将结果放在请求头中发送。您重新计算哈希并进行比对。有三个细节容易出错:
- 明确签名的内容。许多服务商对整个请求正文进行签名,这意味着您必须对原始字节进行校验,而不是对重新序列化的 JSON 进行校验。Chaingateway 只对交易 ID 签名。
- 以恒定时间比对。使用您所用语言的安全比较函数,而不是普通的相等判断。
- 如果方案提供了时间戳,就检查它。拒绝过旧的时间戳可以限制被截获请求的重放。Chaingateway 的方案没有时间戳,因此应以交易 ID 进行去重。
在您的个人资料中设置个人密钥后,Chaingateway 会在 X-Signature 请求头中发送签名。其值是以该密钥对 txid 字段计算的 HMAC-SHA256 再经 Base64 编码的结果。签名校验指南提供了可运行的 Node.js 处理程序,文档则提供了 Python、Java 和 PHP 版本。由于只对 txid 签名,有效的签名并不能证明 amount 或 to 未被更改。在入账之前,请将它们与您的账单或链上数据进行核对。
请将密钥保存在环境变量或密钥管理器中,切勿放入代码仓库;如果它曾出现在日志中,请重新生成。重新生成的密钥会立即生效。
如何处理重试、重复和缓慢的确认?
网络会出故障,部署也会重启服务器。您的处理程序最终一定会两次收到同一个事件,例如在重新发送之后,有时事件还会乱序到达。从一开始就应为此进行设计。
让处理具备幂等性
每个事件都带有能够标识它的信息。在 Chaingateway 的通知中,这就是 txid 连同 webhook_id。在采取行动之前,先用唯一约束保存这一标识。如果由于该键已存在而插入失败,说明您已经处理过该事件,可以直接返回 200,无需执行任何操作。
然后让业务操作本身可以安全地重复执行。“将账单 1042 标记为已付款,交易为 X”是幂等的。“将余额增加 50”则不是。优先采用前一种形式,或者将余额变动与唯一的事件记录放在同一个数据库事务中。

尊重确认深度
交易出现在区块中,并不等同于可以据此发货的付款。不同的链在区块变得不太可能被回滚的速度上有所不同,合适的阈值取决于金额和资产。请按链和订单规模制定策略,并保存每笔付款的状态:已检测、确认中、已确认、失败。宣告检测到付款的 Webhook 应将订单推进到“已看到付款”,而不是“已履约”。
少付、多付与错误代币
客户发送错误金额的情况比人们预期的更为常见。您的处理程序应将收到的金额和资产与账单进行比较,并分别处理:完全一致、少付、多付,或出现意外代币。应事先决定是否自动入账差额、转入人工复核,还是退款。将资产和金额作为独立字段的解码负载,可以把这种比较简化为几行代码,而不是一项解析工作。
保留安全网
投递可能失败,而 Chaingateway 不会重试。失败的通知会出现在 GET /api/v2/<chain>/webhooks/notifications/failed 中,您可以使用 POST /api/v2/<chain>/webhooks/notifications/{id}/retry 逐一重新发送。每隔几分钟运行一次定时任务,检查该列表,并查看超过合理时间仍处于待处理状态的账单。当它发现 Webhook 从未报告的付款时,将其送入相同的处理路径。两种来源共用一条代码路径,也就只需维护一套缺陷。
如何测试与监控 Webhook 接收端点?
分层建立信心:
- 本地测试。编写一个小脚本,使用测试密钥对示例负载签名,并将其发送到您的端点。确认有效签名能够通过,而修改过的
txid会失败。 - 测试网运行。使用请求头
X-Network: testnet在测试网上创建钱包,注册 Webhook,并从水龙头发送一笔小额转账。您将看到真实的事件顺序,包括通知出现前的延迟,这是任何示例负载都无法体现的。 - 重复演练。将同一个有效事件发送五次。您的账单应只改变一次,日志中则应显示四次被跳过的重复事件。
- 故障演练。故意让处理程序返回 500。然后在失败列表中找到该通知,恢复处理程序并重新发送。它应只被处理一次。
上线后,记录每个收到的事件 ID、校验结果、处理结果以及耗时。针对三类情况设置告警:签名失败(密钥配置错误或存在攻击者)、队列不断增长(工作进程落后),以及账单待处理时间远超正常水平(无声的投递问题)。
常见问题及其通常原因:
| 症状 | 可能原因 |
|---|---|
| 签名始终不匹配 | 密钥错误或已重新生成,或哈希计算的内容有误(应为 txid,而非整个正文) |
| 没有收到任何事件 | URL 无法公网访问、防火墙拦截、地址未订阅、网络选择错误 |
| 同一事件被处理两次 | 事件 ID 上没有唯一约束 |
| 通知出现在失败列表中 | 处理程序响应缓慢,或返回了非 2xx 状态码 |
| 付款入账过早 | 业务逻辑基于检测结果而非确认结果执行 |
如何在 Chaingateway 中开始接收付款事件?
只需一个请求即可创建 Webhook:POST /api/v2/<chain>/webhooks。下面的示例注册了一个 TRC20 充值监听器,并附带您的订单引用:
curl -X POST https://app.chaingateway.io/api/v2/tron/webhooks \ -H "Authorization: Bearer $CHAINGATEWAY_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "to": "TWrTTVizHkF3LxTiWE9vCnhWC7CBpNXe22", "contractaddress": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", "type": "TRC20", "url": "https://shop.example.com/hooks/crypto", "reference": "order-10442" }'Chaingateway Webhooks 与 Blockchain API 协同工作,因此告知您充值已到账的事件,与将其继续转发的调用,都位于同一个账户之下。

套餐价格公布在价格页面上:Plus 每月 €49,Pro 每月 €99,Premium 每月 €249,Enterprise 每月 €499;按年计费时分别为每年 €490、€990、€2,490 和 €4,990。7 天免费试用无需银行卡,也无需 KYC,因此您可以先接好端点,再进行上述演练。
常见问题
使用 Webhook 后还需要轮询吗?
需要,但只需少量轮询。以 Webhook 作为主要信号,并定期检查仍待付款的订单,避免从未送达的投递让订单卡住。该检查发现的任何付款,都应通过与 Webhook 事件相同的处理代码进行处理。
如何确认 Webhook 确实来自服务商?
使用共享密钥校验签名请求头,并拒绝未通过校验的请求。对于 Chaingateway,即校验 X-Signature 请求头,即对 txid 计算的 HMAC,以及您在个人资料中设置的个人密钥。即使 URL 是保密的,也绝不要信任未签名请求的内容。
我的端点应返回什么?
在完成校验并保存事件后,立即返回 2xx 状态码。将邮件、账本更新和第三方调用等耗时操作放到后台工作进程中处理。响应缓慢或失败会使通知进入失败列表,之后重新发送时会再次投递。
一套 Webhook 配置能否覆盖多条区块链?
如果服务商对数据进行了标准化,就可以。Chaingateway 在以太坊、BNB Smart Chain、Polygon、Arbitrum 和 Tron 上使用相同的通知字段,因此一个处理程序即可处理来自所有这些链的事件,并在您自己的逻辑中设置各链的确认规则。比特币 Webhook 仅按发送方和接收方过滤,而 Solana 不提供 Webhook。
资料来源
推荐阅读
准备好自己动手构建了吗? 获取你的 API key — 7 天试用,无需信用卡 — 或查看 区块链 API 获取完整的 endpoint 参考。