本页涵盖所有 webhook 事件,跨越多个平台领域(交易活动、存款、组件流程以及 OAuth 账户关联),不隶属于单一功能。
工作原理
- 在开发者门户为你的应用注册一个 webhook URL。
- 选择要监听的事件类型(或订阅全部事件)。
- 当匹配的事件发生时,Fluz 会向你的 URL 发送带签名的 JSON 负载的 HTTP
POST请求。 - 你的服务器验证签名,返回
2xx确认,并处理该事件。
按应用类型区分的 Webhook
事件如何路由到你的应用取决于你的应用模型。私有应用 — 你的自有账户
Webhook 针对你的自有账户的活动触发。任何你所拥有账户上的交易、拒付或存款,都会触发注册在你应用上的 webhook。 常见用例: 当虚拟卡交易被授权或结算时发送通知;实时拒付告警;监控存款与消费账户的余额变动。公共应用(OAuth)— 代表用户行动
Webhook 针对已授权你的应用的账户活动触发。当用户通过 OAuth 授予你的应用访问权限时,只要该用户的 OAuth 授权包含所需的 scope,事件就会被路由到你注册的 webhook。不论用户是通过你直接的 API 集成还是通过嵌入式组件进行交互,只要用户与应用之间存在 OAuth 关系即可。 常见用例: 知道用户何时已将账户与应用关联(或重新关联);监控已连接账户的虚拟卡消费;实时拒付通知;跟踪存款完成;接收 KYC 状态更新。组件应用(Widget apps)
组件应用是一种特殊的公共应用。事件的路由方式相同(基于 OAuth 关系),并且组件应用还支持组件特有的事件,例如转账完成与礼品卡购买。事件类型
仅当你的应用——以及对于公共/OAuth 应用,具体用户的 OAuth 授权——拥有所需的 scope 时,Fluz 才会投递该事件。无所需 scope 的事件(例如OAUTH_USER_LINKED)会投递给任何已订阅的公共/OAuth 应用。
交易事件
覆盖完整的交易生命周期。适用于所有应用类型。存款事件
OAuth 事件
适用于公共/OAuth 与组件应用。OAUTH_USER_LINKED 仅投递给公共/OAuth 应用类型——私有应用订阅者不会收到。由于它没有 scope 要求,你会对每个与应用建立或重新建立关联的用户收到该事件,无论他们授予了哪些 scope。用它来开通或更新你本地的已连接用户记录、捕获授予的 scope 集合,并通过 externalReferenceId 映射你的用户标识符。
组件特有事件
适用于用户通过 Fluz 嵌入式流程进行交互的组件与 OAuth 集成。📘 命名说明:WIDGET_DEPOSIT_COMPLETE与WIDGET_WITHDRAW_COMPLETE描述的是顾客↔应用的“转账”;DEPOSIT/WITHDRAW的命名是历史遗留。将 “deposit” 理解为 “顾客 → 应用”,将 “withdraw” 理解为 “应用 → 顾客”。
设置 webhook
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。你的端点会立即开始接收事件。管理 webhook
- 多个端点 — 你可以为每个应用注册多个 webhook URL。
- 变更订阅事件 — 删除该 webhook 并用新的事件选择重新创建。
- 移除 webhook — 点击其旁边的 Remove。该 webhook 会立刻被归档并停止接收事件。
接收 webhook
请求格式
每个 webhook 都以 HTTPPOST 形式投递,并包含以下请求头:
请求体是一个 JSON 对象,每个负载都包含一个标识事件的
eventType 字段。
端点要求
- 仅限 HTTPS — 纯 HTTP 端点会在注册时被拒绝。
- 可公开访问,且能接受
POST请求。 - 在 30 秒内返回
2xx。 非2xx响应或超时会触发重试。 - 验证每次请求的 HMAC 签名。
验证签名
每次投递都包含一个X-HMAC-Signature 请求头——这是以你的应用API key对原始 JSON 请求体计算的 HMAC-SHA256 散列。务必在信任负载前先进行验证。
⚠️ 务必针对原始请求体验证。 以 Fluz 发送的精确字节计算 HMAC——不要对解析后的 JSON 再次序列化。重新字符串化可能改变键顺序或空白,从而导致有效签名验证失败。下方示例捕获原始请求体正是出于此原因。
Node.js(Express)
Python(Flask)
响应 webhook
你的端点必须:- 在 30 秒内返回
2xx状态。 - 快速返回——先确认,再异步处理事件。
- 能通过 HTTPS 访问。你的端点不得:
- 返回重定向(
3xx)。 - 对有效的 webhook 返回
4xx/5xx(这会触发重试)。
重试策略
当你的端点恢复后,新事件会自动恢复投递。要重新发送已耗尽重试次数的事件,请联系支持并提供相关的
X-Event-ID。
幂等性与顺序
Webhook 可能会被多次投递,且不保证投递顺序。- 使用
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。被拒交易携带DECLINED(或FAILED)的status。本页早期草稿展示过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。