跳转到主要内容

Webhook 概述

A55 在收款、订阅和支付状态变更时向您的服务器发送 HTTP POST Webhook(网络钩子)。Webhook 支持实时响应,无需轮询。


为什么使用 Webhook

方式延迟可靠性A55 负载
Webhook(推送)秒级至少一次投递 + 重试极低
轮询(拉取)取决于间隔不会遗漏(可追赶)较高

以 Webhook 作为主要通知渠道,轮询作为对账兜底。


配置方式

在收款请求中设置 webhook_url,或在 A55 控制台配置默认 URL。

参数范围说明
收款请求中的 webhook_url单笔收款仅接收该笔收款的事件
控制台中的默认 URL账户级别当未提供 webhook_url 时使用

投递详情

属性
方法POST
Content-Typeapplication/json
超时30 秒
TLS仅 HTTPS(拒绝 HTTP)

HMAC 签名验证

A55 使用 HMAC(基于哈希的消息认证码)-SHA256 对每个 Webhook 签名。处理前务必验证。

请求头内容
X-Webhook-Signaturesha256={hex_signature}
X-Webhook-TimestampUnix 时间戳(秒)

验证步骤

  1. 提取 X-Webhook-SignatureX-Webhook-Timestamp 请求头
  2. 如果时间戳超过 5 分钟则拒绝(防重放)
  3. 构建签名载荷:{timestamp}.{raw_body}
  4. 使用您的 Webhook 密钥计算 HMAC-SHA256
  5. 使用时间安全比较进行校验
  6. 仅在签名匹配时处理事件
import hmac, hashlib, time

def verify_webhook(payload: bytes, signature: str, timestamp: str, secret: str) -> bool:
"""验证 Webhook HMAC-SHA256 签名。"""
if abs(time.time() - int(timestamp)) > 300:
return False
signed_payload = f"{timestamp}.".encode() + payload
expected = hmac.new(secret.encode(), signed_payload, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature.removeprefix("sha256="))
安全警告

切勿在未验证 HMAC 签名的情况下处理 Webhook。攻击者可能伪造未经验证的 Webhook。


重试策略

投递失败后将在 24 小时内以指数退避方式重试:

尝试次数延迟累计时间
1立即T+0
21 分钟T+1m
35 分钟T+6m
430 分钟T+36m
52 小时T+2h 36m
66 小时T+8h 36m
724 小时T+32h 36m

经过 7 次失败尝试后,事件在控制台中标记为失败

触发重试的条件

响应是否重试?原因
200–299投递成功
400–499客户端错误——重试无效
500–599服务端错误——暂时性
超时(>30 秒)端点响应过慢
连接被拒绝端点不可用

幂等处理

Webhook 使用至少一次投递。同一事件可能多次到达。您的处理器必须保证幂等。

def handle_webhook(event):
"""幂等处理 Webhook 事件。"""
event_id = event["id"]
if db.webhook_events.find_one({"event_id": event_id, "status": "completed"}):
return Response(status=200)
db.webhook_events.upsert({"event_id": event_id, "status": "processing"})
process_event(event)
db.webhook_events.update({"event_id": event_id, "status": "completed"})
return Response(status=200)
快速响应

收到事件后立即返回 HTTP 200。将耗时逻辑放到后台任务中处理,避免超时。


事件类型

领域事件
收款charge.authorizedcharge.capturedcharge.failedcharge.refundedcharge.cancelledcharge.chargeback
PIXpix.receivedpix.expiredpix.refunded
Boletoboleto.paidboleto.expiredboleto.cancelled
订阅subscription.createdsubscription.renewedsubscription.failedsubscription.cancelled

详见收款 Webhook 了解载荷详情。


测试

工具适用场景
webhook.site可视化查看载荷
ngrok转发到本地开发环境
A55 沙箱生产级测试事件