如何在服务器上确认稳定币支付
要确认稳定币支付,请让您的服务器依据 Cosmos Pay 的签名 Webhook 采取行动,而不是依据客户看到的页面。网络确认支付后,Cosmos Pay 会向您的端点发送 PAYMENT_INTENT_SUCCEEDED,并以该端点的签名密钥签名。请验证签名,以 2xx 状态码响应,并且每个事件只交付一次订单。

为什么要靠服务器,而不是浏览器
显示“已支付”的收银台,只是客户浏览器上显示的内容。标签页可能在返回您的网站之前就被关闭,任何人也都可以手动打开您的成功页面。让支付成为最终结果的,是网络的确认。
Cosmos Pay 替您监控网络,并在支付获得确认时通知您的服务器。将订单标记为已支付并交付订单,应当在您的服务器上完成。
Cosmos Pay 发送什么
- 向您注册的端点发送一个 HTTPS POST 请求,附带一个 JSON 事件:id(以 evt_ 开头)、type、createdAt 和 data。对于支付,data 就是该笔支付,包括其状态、金额、资产、网络和交易。
- X-Cosmos-Signature 请求头:t=<Unix 时间>,v1=<签名>。签名是以端点的签名密钥为密钥,对 t、一个句点和原始请求体计算的 HMAC-SHA256,以十六进制表示。
- 您选择的事件类型,例如 PAYMENT_INTENT_SUCCEEDED、PAYMENT_INTENT_FAILED 或 ZK_PAYMENT_SUCCEEDED。请按原样匹配:大写字母加下划线。
- X-Cosmos-Event、X-Cosmos-Event-Id 和 X-Cosmos-Delivery 请求头,用于标明事件和投递。
一步步设置 Webhook
添加端点
在控制台中打开“Webhook”,添加您服务器上某个路由的 HTTPS 地址。选择要接收的事件;PAYMENT_INTENT_SUCCEEDED 默认已选中。该地址必须是公开地址:私有地址和本地地址会被拒绝。
保存签名密钥
控制台只会显示一次端点的签名密钥(以 whsec_ 开头)。请将其保存在服务器的环境变量中,切勿放在网页里。
验证每个请求
在任何 JSON 解析器处理之前读取原始请求体,并据此校验 X-Cosmos-Signature。使用 TypeScript SDK 时,Webhooks.constructEvent 会校验签名,默认拒绝超过五分钟的签名,并返回事件。
先快速响应,再处理
签名校验通过后立即以 2xx 状态码响应,发送邮件、更新库存等耗时工作放到之后再做。
每个事件只处理一次
保存您处理过的每个事件的 id,遇到已处理过的事件就跳过:重试或重新投递会再次发送同一个事件。
发送测试
在端点上使用“发送测试”接收一个 ping 事件,然后在沙箱中完成一笔测试支付,并在端点的列表中查看其投递情况。
当您的服务器没有响应时
只有 2xx 响应才算投递成功,且不会跟随重定向。投递失败时,Cosmos Pay 会以逐渐拉长的间隔最多重试三次,之后在后续轮次中再次重试,每次尝试中事件的 id 都保持不变。
在控制台中,每个端点都会列出其投递记录,并可筛选失败的投递,您可以重新发送其中任意一条。Cosmos Pay 会将投递的请求体保留 30 天,请在此期间内重新投递。
或者自行核查支付
您也可以查询单笔支付:按 ID 获取它以读取其状态,或将其交易哈希(在 Solana 上为交易签名)发送到 POST /v1/payment-intents/:id/validate。请将其作为备用手段,例如客户在 Webhook 到达之前就已返回时;Webhook 仍是主要信号。
控制台显示的是 payment_intent.succeeded。事件实际使用哪个名称?
事件的 type 是 PAYMENT_INTENT_SUCCEEDED,大写字母加下划线。控制台只是以更短的形式显示它。
轮换签名密钥后会怎样?
新密钥立即生效,旧密钥立即失效,因此轮换后请马上更新您的服务器。
如果我的服务器宕机了怎么办?
Cosmos Pay 会重试失败的投递,您也可以在 30 天内从控制台重新发送任何一次投递。
可以有多个端点吗?
可以。每个端点都有自己的地址、事件和签名密钥,每个事件都会发送到订阅了它的每个端点。