跳转到主要内容
使用 Webhook 来响应异步的变更。投递采用至少一次(at-least-once)语义,因此重复、延迟以及乱序的事件都是正常现象。

只订阅您需要的事件

使用 POST /v3/webhooks 创建一个端点。仅订阅您集成中真正需要处理的、有文档记录的事件。以下示例订阅 transfer.state_changed。
Create webhook endpoint
将响应的 data.id 保存为 WEBHOOK_ID。使用具有 webhooks:write 的 API 密钥从 GET /v3/webhooks/portal 请求门户 URL,获取该端点的签名密钥,并将其与 API 密钥分开存放在密钥管理系统中。门户 URL 本身即可授予访问权限,并会在一小时后过期,因此请每次都请求新的 URL,不要存储或分享它。 管理入口按资源对 v3 事件进行分组:Customers、Capabilities、Accounts、Recipients、Transfers 和 API。每个事件都会展示其载荷结构和一个示例。旧版事件会被标记为已弃用,并列在单独的 Legacy 分组中。如果您的端点已订阅某个旧版事件,它会继续接收该事件。新的订阅请选择 v3 事件名称。

更改端点的事件

使用 GET /v3/webhooks/{webhookId} 读取单个端点。响应中的 events 结构与 GET /v3/webhooks 相同。响应中从不包含签名密钥。读取需要 webhooks:read 权限,对于未知的端点 ID 会返回 404 not_found。 使用 PATCH /v3/webhooks/{webhookId} 更新端点。请发送 Idempotency-Key 请求头。更新需要 webhooks:write 权限。
  • 仅发送 events,可保留当前的 URL。
  • 仅发送 url,可保留当前的事件选择。
  • events 会替换整个选择。请先读取该端点,并包含您仍需要的每个事件。
  • 新的订阅必须使用 v3 事件名称。
  • 如果端点已订阅某个旧版事件名称,您可以保留它。添加新的旧版名称会返回 400 validation_error。
以下请求体保留 URL 并替换事件选择:
Request body

在解析前先校验

Swipelux 通过 Svix 投递新的 Webhook 集成。请使用您的端点签名密钥与以下请求头,对原始请求体进行校验:
  • svix-id
  • svix-timestamp
  • svix-signature
在校验通过之前,请勿解析 JSON,也不要产生任何副作用。
Verify signature
对缺少或非法签名的请求请直接拒绝。在校验完成之前,请始终保留原始请求体。

先持久化,再确认,最后处理

请在信封的 id 上加上唯一性约束。先持久化经过验证的信封,及时返回 2xx,然后再异步处理。 如果事件 ID 已经存在,请仅确认投递,不要重复执行已经完成的副作用。通过您自己的重试队列继续处理挂起或失败的本地任务。切勿将信封的 attempt 字段用作去重键或传输层的重试计数器。

重新获取当前状态

Webhook 的顺序并不是资源历史的权威依据。请使用 resource.type 和 resource.id 定位对象,并在更新您的系统之前先获取其当前状态。 对于转账事件,请调用 GET /v3/transfers/{transferId}:
Refetch transfer
请根据当前的 API 响应驱动面向客户的状态和下游动作。请把副作用设计成:即便两个 worker 以不同顺序处理相关事件也保持安全。

恢复投递

使用 GET /v3/webhooks/portal 打开投递日志。具有 webhooks:write 时,您还可以重试失败的投递或启动一次人工重放。仅具有 webhooks:read 的密钥打开的门户会显示投递记录,但无法重试、重放投递,也无法显示签名密钥。 每次重放都必须经过同样的签名校验和持久化的收件箱。当服务中断后,请重放受影响的时间窗口,并重新获取每个引用的资源。已完成的事件 ID 仍然视为无操作;未完成的记录会异步继续处理。 接下来,请在沙盒中验证重复与乱序投递,然后完成上线清单。