本页涵盖所有 webhook 事件,跨越多个平台领域(交易活动、存款、小部件流程以及 OAuth 账户关联),并不隶属于某个单一功能。
工作原理
- 在开发者门户为你的应用注册一个 webhook URL。
- 选择要监听的事件类型(或订阅全部事件)。
- 当匹配事件发生时,Fluz 会向你的 URL 发送一个带签名的 JSON 负载的 HTTP
POST请求。 - 你的服务器验证签名,以
2xx确认并处理事件。
按应用类型划分的 Webhooks
事件如何路由到你的应用取决于你的应用模型。私有应用 — 你的自有账户
Webhooks 针对你的自有账户的活动触发。你所拥有账户上的任何交易、拒付或存款,都会触发注册在你应用上的 webhooks。 常见用例: 虚拟卡交易授权或清算的通知;对拒付的实时告警;监控消费账户的存款与余额变动。公共应用(OAuth)— 代表用户操作
Webhooks 针对已授权你的应用的账户活动触发。当用户通过 OAuth 授予你的应用访问权限时,他们的事件会路由到你注册的 webhooks——前提是该用户的 OAuth 授权包含所需的 scopes。无论用户通过你的直连 API 集成还是嵌入式小部件交互,此机制均适用;关键在于用户与应用之间存在 OAuth 关系。 常见用例: 知晓用户已将其账户与应用关联(或重新关联);监控已连接账户的虚拟卡支出;实时拒付通知;跟踪存款完成;接收 KYC 状态更新。小部件应用
小部件应用是特殊的公共应用。事件路由方式相同(基于 OAuth 关系),并且小部件应用还支持特定于小部件的事件,例如转账完成与礼品卡购买。事件类型
仅当你的应用——以及对于公共/OAuth 应用,单个用户的 OAuth 授权——具有所需 scopes 时,Fluz 才会投递事件。没有所需 scopes 的事件(例如OAUTH_USER_LINKED)会投递给任何已订阅的公共/OAuth 应用。
交易事件
覆盖完整的交易生命周期。适用于所有应用类型。存款事件
OAuth 事件
适用于公共/OAuth 与小部件应用。OAUTH_USER_LINKED 仅投递给公共/OAuth 应用类型——私有应用的订阅者不会接收。由于它没有 scope 要求,你会接收每位用户与应用关联或重新关联的事件,无论其授予了哪些 scopes。使用它来配置或更新你本地的已连接用户记录,捕获授予的 scope 集合,并通过 externalReferenceId 映射你的用户标识符。
小部件特定事件
适用于用户通过 Fluz 嵌入式流程进行交互的小部件与 OAuth 集成。📘 命名说明:WIDGET_DEPOSIT_COMPLETE与WIDGET_WITHDRAW_COMPLETE描述的是客户↔应用之间的_转账_;DEPOSIT/WITHDRAW的措辞是历史遗留。将“deposit”视为“客户 → 应用”,“withdraw”视为“应用 → 客户”。
设置 webhooks
1. 打开开发者门户
前往 Developer Portal 并选择你的应用。2. 打开 Webhooks 区域
- OAuth 应用: OAuth 选项卡 → Webhook URLs。
- 小部件应用: Widget 选项卡 → Webhook URLs。
- API / 私有应用: 应用设置中的 Webhook URLs 区域。
3. 添加一个 webhook URL
点击 Add new URL 并输入你的 HTTPS 端点(例如,https://api.yourapp.com/webhooks/fluz)。
4. 选择事件
选择你希望接收的事件类型。5. 保存
点击 Create Webhook。你的端点会立即开始接收事件。管理 webhooks
- 多个端点 — 你可以为每个应用注册多个 webhook URL。
- 更改订阅的事件 — 删除该 webhook 并使用新的事件选择重新创建。
- 移除一个 webhook — 点击其旁边的 Remove。该 webhook 会被立即归档并停止接收事件。
接收 webhooks
请求格式
每个 webhook 都以 HTTPPOST 形式投递,并包含以下请求头:
请求体是一个 JSON 对象,每个负载都包含一个标识事件的
eventType 字段。
端点要求
- 仅限 HTTPS — 纯 HTTP 端点会在注册时被拒绝。
- 可公共访问,并能够接收
POST请求。 - 在 30 秒内以
2xx响应。 非2xx或超时将触发重试。 - 验证每次请求的 HMAC 签名。
验证签名
每次投递都包含X-HMAC-Signature 请求头——这是以你应用的 API key 对原始 JSON body 进行 HMAC-SHA256 计算得到的哈希。请务必在信任负载之前进行验证。
⚠️ 请针对原始请求体进行验证。 使用 Fluz 发送的精确字节计算 HMAC——不要对已解析的 JSON 重新序列化。重新字符串化可能会改变键顺序或空白,从而导致有效签名验证失败。下面的示例会捕获原始请求体,正是出于这个原因。
Node.js (Express)
Python (Flask)
响应 webhooks
你的端点必须:- 在 30 秒内以
2xx状态响应。 - 快速返回——先确认,再异步处理事件。
- 可通过 HTTPS 访问。你的端点不得:
- 返回重定向(
3xx)。 - 对有效的 webhooks 返回
4xx/5xx(这会触发重试)。
重试策略
一旦你的端点恢复,新的事件会自动恢复投递。若需重新发送已耗尽重试次数的事件,请联系支持并提供相关的
X-Event-ID。
幂等与顺序
Webhooks 可能会被重复投递,且不保证投递顺序。- 使用
X-Event-ID请求头进行去重。在生产环境中将已处理 ID(如存入 Redis 或数据库)持久化,并跳过已处理的事件。 - 按数据而非到达顺序排序。 若顺序很重要,请依据负载中的时间戳(
createdAt、updatedAt、transactionDateTime)与事件 ID 排序。
识别应用与用户
- 用户:
userId是 Fluz 用户 ID。对于 OAuth/小部件事件,externalReferenceId对应于通过 OAuth 流程映射到_你的_用户标识符。 - 应用: 交易负载包含
connectedAppId与connectedAppName。如果你将多个应用路由到同一端点,请基于connectedAppId分流。对于OAUTH_USER_LINKED,应用由appId标识。
负载参考
每个负载都包含一个eventType。字段可用性会因事件而异;为保持前向兼容,处理程序应忽略未识别字段。
📘 关于status值的说明。 对于创建/更新的交易,status字段取PENDING、SETTLED或FAILED之一。被拒绝的交易的status为DECLINED(或FAILED)。早期版本曾展示过COMPLETED状态——该值不会被发出;请使用SETTLED来判断交易已最终完成。
交易已创建(TRANSACTION_CREATE)
在任意新交易(虚拟卡购买、存款、转账等)时触发。
交易已更新(TRANSACTION_UPDATE)
当交易状态或详情发生改变时触发——例如挂起授权清算时。
TRANSACTION_CREATE 对齐(在存在时),并额外包含 updatedAt(ISO 8601),标记变更发生时间。userId、connectedAppId 与 connectedAppName 的传递方式与 TRANSACTION_CREATE 一致,因此你可以在整个生命周期中一致地识别用户与应用。status 转变为 SETTLED 是此前挂起交易已最终完成的信号。
交易被拒(TRANSACTION_DECLINE)
当一笔交易被拒绝时触发。包含结构化的拒绝原因,便于你的应用采取行动。
根据交易不同,可能还会出现其他可选字段(例如
merchantId、merchantCity、merchantState、merchantCountry、cardDisplayName、virtualCardProgram、channel、bankAccountNickname、bankAccountLastFour)。忽略你未使用的字段即可。
存款完成(DEPOSIT_COMPLETE)
当从资金来源到消费账户的存款完成时触发。
OAuth 用户已关联(OAUTH_USER_LINKED)
当用户完成与你应用的 OAuth 关联时触发——既包括初次关联,也包括后续更新(例如用户以不同 scope 集重新授权)。仅适用于公共/OAuth 与小部件应用。接收此事件不需要任何 scope。
由于
OAUTH_USER_LINKED 会在重新关联/更新时再次触发,请将其视为 upsert:首次接收时创建已连接用户,后续投递时刷新存储的 scope 集。
启动 KYC(WIDGET_KYC_INITIATION)
当用户开始身份验证时触发。仅适用于公共/小部件应用。
转账完成 — 客户到应用(WIDGET_DEPOSIT_COMPLETE)
当用户向你的应用转入资金时触发。
转账完成 — 应用到客户(WIDGET_WITHDRAW_COMPLETE)
当你的应用向用户转出资金时触发。
礼品卡购买(WIDGET_PURCHASE_GIFT_CARD)
当通过小部件完成礼品卡购买时触发。
userId(Fluz 用户 ID)、accountId(Fluz 账户 ID)、externalReferenceId(通过 OAuth 流程传入的你的用户标识符),以及在适用时的 amount。
最佳实践
- 快速响应,稍后处理。 立即返回
200,并异步处理事件,以避免超时与不必要的重试。 - 验证每个请求。 使用你的 API key 基于原始请求体验证
X-HMAC-Signature后再处理。 - 使用事件 ID 去重。 追踪
X-Event-ID,以应对重试/重复投递。 - 将类枚举字段视为开放字符串。 新的
transactionType、channel与declineCategory值可能随时间增加;仅分支你关心的值并容忍未知项。 - 对
OAUTH_USER_LINKED执行 upsert。 它对同一用户可能多次触发;每次都刷新存储的 scope 集,而不是假定仅首次关联。 - 接受未知字段。 负载可能随时间新增字段;忽略未识别字段,而不是因此失败。
- 监控你的端点。 对连续非
2xx响应进行告警——在 5 次尝试失败后,该事件的投递会被放弃。
故障排除
需要帮助?
- 技术问题: 检查你的端点日志,并附上
X-Event-ID联系支持。 - scope 相关问题: 参见 Application Scopes 与 Decline Codes。