01
验证原始 body
在 JSON 解析器改变格式或 key 顺序前,基于完整原始请求 body 字节计算 HMAC。
创建真实感 Webhook body,计算 HMAC-SHA256 签名,并复制可用于本地或预发环境的 cURL 命令。
检查项
原始 body 签名
检查项
HMAC-SHA256
检查项
可用 cURL
使用:HMAC_SHA256(timestamp + "." + rawBody, secret)
签名
9bb63da06ffb56bfd65d1eeb07c37ca52b895c13f1c377e472ac3e0b123a6faa
Body 状态
JSON body 有效
将该请求发送到你的 Webhook 接口。服务端应基于原始请求 body 验证签名,并且只在安全记录事件后返回 HTTP 2xx。
curl -X POST "https://merchant.example.com/webhooks/boltutil" \
-H "Content-Type: application/json" \
-H "X-Bolt-Webhook-Timestamp: 1784826915691" \
-H "X-Bolt-Webhook-Signature: 9bb63da06ffb56bfd65d1eeb07c37ca52b895c13f1c377e472ac3e0b123a6faa" \
--data '{
"externalOrderId": "ORDER_2026_001",
"status": "CONFIRMED",
"amount": "199.000000",
"currency": "USDT",
"network": "TRC20",
"txHash": "0x1abd1849cf65896b103d3a252849f9460fc45d86cb1031c9c36c0205b0a2913c",
"confirmations": 20,
"destinationAddress": "TMerchantSettlementWallet",
"paidAt": "2026-05-25 12:30:00",
"confirmedAt": "2026-05-25 12:35:00",
"metadata": {
"plan": "pro",
"userId": "u_123"
}
}'01
在 JSON 解析器改变格式或 key 顺序前,基于完整原始请求 body 字节计算 HMAC。
02
使用语言运行时提供的 constant-time 工具比较收到的签名和计算结果。
03
只有在记录事件或写入可靠内部队列后,才返回成功。
Webhook 排查
大多数 Webhook 问题来自签名验证、body 解析、重试处理,或在系统安全记录支付事件前就返回成功。
最常见原因是对解析后的 JSON 签名,而不是精确原始 body,或使用了与请求头不同的时间戳。
请使用商户回调地址配置的 Webhook 密钥。API Key 和 Webhook Secret 应视为不同凭证。
JSON 中间件可能重排或格式化 payload。校验 HMAC 前应先捕获原始 body。
BoltUtil 会把非 2xx 响应视为投递失败,并按配置的重试策略继续重试。
Webhook 重试可能多次投递同一事件。请保存事件 ID 或交易哈希,避免重复履约。
只有在事件写入数据库或队列后才返回 HTTP 2xx,否则服务崩溃可能丢失已完成支付通知。
常见问题
当支付已完成但应用没有按预期更新时,可以按这些检查项排查。
请验证精确原始请求 body、时间戳请求头和配置的 Webhook 密钥。对解析后的 JSON 或重新格式化后的 body 签名通常会得到不同 HMAC。
正常 HTTP 2xx 才是最重要的投递成功信号。接口可以返回简单 JSON,但投递系统应该依赖状态码判断成功。
让处理器保持幂等。在履约前保存唯一事件 ID、订单 ID 加状态,或交易哈希,然后安全忽略重复事件。
只有在支付事件被安全记录或进入队列后才返回 2xx。如果校验失败或无法持久化事件,请返回非 2xx 以便重试。