本页作为 Webhooks 的顶层章节,因为 webhook 事件跨越多个平台领域(小部件流程与交易活动),而不隶属于单一功能。
工作原理
- 你在开发者门户为你的应用注册一个 webhook URL。
- 选择要监听的事件类型(或订阅全部事件)。
- 当匹配的事件发生时,Fluz 会向你的 URL 发送带签名的 JSON 负载的 HTTP
POST。 - 你的服务器验证签名、以
2xx确认并处理事件。
FAILED。
按应用类型的 Webhooks
事件如何路由到你的应用取决于你的应用模型。私有应用 — 你的自有账户
Webhooks 针对你自己的账户活动触发。你所拥有账户上的任何交易、拒绝或存款,都会触发注册在你应用上的 webhooks。 常见用例: 当虚拟卡交易被授权或结算时的通知;实时拒绝警报;监控你的消费账户上的存款与余额变动。公共应用(OAuth)— 代表用户操作
Webhooks 针对已授权你的应用的账户活动触发。当用户通过 OAuth 授权你的应用时,其事件会被路由到你注册的 webhooks——前提是用户的 OAuth 授权包含所需的权限范围(scopes)。无论用户是通过你的直接 API 集成还是嵌入式小部件交互都适用;关键在于用户与应用之间存在 OAuth 关系。 常见用例: 监控已连接账户的虚拟卡消费;实时拒绝通知;跟踪存款完成;接收 KYC 状态更新。小部件应用
小部件应用是一类特殊的公共应用。事件的路由方式相同(基于 OAuth 关系),并且小部件应用还支持小部件特定事件,如转账完成与礼品卡购买。事件类型
仅当你的应用——以及对于公共/OAuth 应用,单个用户的 OAuth 授权——拥有所需的权限范围时,Fluz 才会投递事件。交易事件
覆盖完整的交易生命周期。适用于所有应用类型。存款事件
小部件特定事件
适用于用户通过 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 请求头——这是对原始 JSON 请求体,使用你应用的API key计算的 HMAC-SHA256。务必在信任负载之前进行验证。
⚠️ 基于原始请求体进行验证。 使用 Fluz 发送的精确字节计算 HMAC——不要对解析后的 JSON 重新序列化。重新字符串化可能会重排键或改变空白,导致有效签名验证失败。下列示例都捕获原始请求体,正是出于此原因。
Node.js (Express)
Python (Flask)
响应 webhooks
你的端点必须:- 在 30 秒内以
2xx状态响应。 - 快速返回——先确认,再异步处理事件。
- 可通过 HTTPS 访问。
- 返回重定向(
3xx)。 - 对有效的 webhooks 返回
4xx/5xx(这会触发重试)。
重试策略
一旦你的端点恢复,新的事件将自动恢复投递。若要重新发送已达到
FAILED 的事件,请联系支持并提供相关的 X-Event-ID。
事件状态生命周期
幂等性与顺序
Webhooks 可能会被多次投递,并且不保证投递顺序。- 使用
X-Event-ID请求头进行去重。持久化已处理的 ID(生产环境使用 Redis 或数据库),跳过已处理的事件。 - 按数据排序,而非到达顺序。 如果顺序很重要,请按照负载时间戳(
createdAt、updatedAt、transactionDateTime)和事件 ID 排序。
识别应用与用户
- 用户:
userId是 Fluz 用户 ID。对于 OAuth/小部件事件,externalReferenceId映射为你在 OAuth 流程中的用户标识符。 - 应用: 交易负载包含
connectedAppId与connectedAppName。如果你将多个应用路由到同一个端点,请基于connectedAppId分支处理。
负载参考
每个负载都包含eventType。字段可用性因事件而异;为前向兼容,处理程序应忽略未识别字段。
交易已创建(TRANSACTION_CREATE)
针对任何新交易触发——虚拟卡购买、存款、转账等。
交易已更新(TRANSACTION_UPDATE)
当交易的状态或详情发生变化时触发——例如,待授权交易结算时。
TRANSACTION_CREATE 对应处一致,并新增 updatedAt(ISO 8601)指明变更发生时间。
🚧 一致性检查: 请确认TRANSACTION_UPDATE(以及TRANSACTION_DECLINE)上均包含userId与connectedAppId/connectedAppName,以便使用方在整个生命周期中一致地识别用户与应用。
交易被拒绝(TRANSACTION_DECLINE)
当交易被拒绝时触发。包含结构化的拒绝原因,你的应用可以据此采取行动。
存款完成(DEPOSIT_COMPLETE)
当从资金来源到消费账户的存款完成时触发。
启动 KYC(WIDGET_KYC_INITIATION)
当用户开始身份验证时触发。仅限公共/小部件应用。
转账完成 — 客户到应用(WIDGET_DEPOSIT_COMPLETE)
当用户向你的应用转入资金时触发。
转账完成 — 应用到客户(WIDGET_WITHDRAW_COMPLETE)
当你的应用向用户转出资金时触发。
礼品卡购买(WIDGET_PURCHASE_GIFT_CARD)
当通过小部件完成礼品卡购买时触发。
🚧 待完善。 添加 WIDGET_PURCHASE_GIFT_CARD 的负载示例与字段表(例如:商户、金额、礼品卡标识符)。
常见小部件负载字段: userId(Fluz 用户 ID)、accountId(Fluz 账户 ID)、externalReferenceId(你在 OAuth 流程中的用户标识符),以及在适用时的 amount。
最佳实践
- 快速响应,稍后处理。 立即返回
200,并异步处理事件,避免超时与不必要的重试。 - 验证每个请求。 使用你的 API key 对照原始请求体校验
X-HMAC-Signature后再处理。 - 用事件 ID 去重。 跟踪
X-Event-ID以处理重试/重复投递。 - 接受未知字段。 负载可能随时间增加字段;忽略未识别字段而不是失败。
- 监控你的端点。 针对连续的非
2xx响应发出警报——在 5 次失败后事件会被标记为FAILED。
疑难排解
需要帮助?
- 技术问题: 检查你的端点日志,并连同
X-Event-ID联系支持。 - 权限范围问题: 参见 Application Scopes 与 Decline Codes。