Skip to main content
Webhook 可讓你的應用程式在 Fluz 平台上發生事件時,即時接收通知。你無需輪詢變更,只要註冊一個 HTTPS 端點,Fluz 就會在事件發生的當下將資料推送給你——例如虛擬卡交易、被拒交易、完成的存款、使用者透過 OAuth 連結其帳戶,等等。
本頁涵蓋所有 webhook 事件,跨越多個平台領域(交易活動、存款、Widget 流程,以及 OAuth 帳戶連結),而非隸屬單一功能。
Webhook 適用於 Fluz 平台上的所有應用程式類型:在你自己帳戶上運行的私人應用、透過 API 代表其他使用者行動的公開 OAuth 應用,以及內嵌的 widget 應用。

運作方式

  1. 在 Developer Portal 中為你的應用程式註冊一個 webhook URL。
  2. 選擇要監聽的事件類型(或訂閱全部事件)。
  3. 當符合的事件發生時,Fluz 會以 HTTP POST 將已簽名的 JSON 載荷傳送至你的 URL。
  4. 你的伺服器驗證簽章、以 2xx 確認接收,並處理該事件。
若你的端點無法連線或回傳錯誤,Fluz 會採用指數退避最多重試 5 次,之後才放棄該次投遞。

依應用程式類型的 Webhook 行為

事件如何路由至你的應用,取決於你的應用程式模型。

私人應用 — 你的自有帳戶

Webhook 針對發生在「你的自有帳戶」上的活動觸發。任何你所擁有帳戶上的交易、拒絕、或存款,都會觸發註冊於你應用上的 webhook。 常見使用情境: 當虛擬卡交易被授權或入帳時的通知;即時拒絕警示;監控存款與消費帳戶的餘額變化。

公開應用(OAuth)— 代表使用者行動

Webhook 會針對「已授權你的應用」之帳戶的活動觸發。當使用者透過 OAuth 授予你的應用存取權時,他們的事件就會路由至你註冊的 webhook——前提是該使用者的 OAuth 授權包含必要的 scopes。無論使用者透過你的直接 API 串接或內嵌 widget 互動都適用;關鍵是使用者與你的應用之間存在 OAuth 關係。 常見使用情境: 知道使用者已連結(或重新連結)其帳戶至你的應用;監控已連結帳戶的虛擬卡消費;即時拒絕通知;追蹤存款完成;接收 KYC 狀態更新。

Widget 應用

Widget 應用是特殊的公開應用。事件路由機制相同(基於 OAuth 關係),此外還支援 widget 特有事件,例如轉帳完成與禮品卡購買。

事件類型

Fluz 僅在你的應用——以及對於公開/OAuth 應用來說,個別使用者的 OAuth 授權——擁有所需 scopes 時才會投遞事件。無需任何 scope 的事件(例如 OAUTH_USER_LINKED)會投遞給任何已訂閱的公開/OAuth 應用。

交易事件

涵蓋完整交易生命週期。適用於「所有應用類型」。

存款事件

OAuth 事件

適用於「公開/OAuth 與 widget 應用」。 OAUTH_USER_LINKED 僅投遞至公開/OAuth 類型應用——私人應用的訂閱者不會接收。由於它沒有 scope 要求,你會對每一位連結或重新連結至你應用的使用者收到該事件,無論他們授與哪些 scopes。使用此事件以建立或更新你本地的已連結使用者記錄、擷取授與的 scope 集合,並透過 externalReferenceId 對應你自己的使用者識別碼。

Widget 特有事件

適用於使用者透過 Fluz 內嵌流程互動的 widget 與 OAuth 整合。
📘 命名說明: WIDGET_DEPOSIT_COMPLETEWIDGET_WITHDRAW_COMPLETE 描述的是客戶↔應用之間的「轉帳」;DEPOSIT/WITHDRAW 的用詞為歷史沿用。請將「deposit」視為「客戶 → 應用」,「withdraw」視為「應用 → 客戶」。

設定 webhook

1. 開啟 Developer Portal

前往 Developer Portal 並選擇你的應用程式。

2. 開啟 Webhooks 區段

  • OAuth 應用: OAuth 分頁 → Webhook URLs
  • Widget 應用: 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 皆以 HTTP POST 傳送,並包含以下標頭: 本文為 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 標頭進行「去重」。在正式環境中以 Redis 或資料庫持久化已處理的 ID,並略過已處理的事件。
  • 「依資料排序而非抵達順序。」若順序有關,請依據載荷時間戳(createdAtupdatedAttransactionDateTime)與事件 ID 排序。

辨識應用與使用者

  • 使用者: userId 是 Fluz 使用者 ID。對於 OAuth/widget 事件,externalReferenceId 會對應到你在 OAuth 流程中的「自家使用者識別碼」。
  • 應用: 交易載荷包含 connectedAppIdconnectedAppName。若你將多個應用路由至同一端點,請根據 connectedAppId 分支處理。對於 OAUTH_USER_LINKED,應用會以 appId 識別。

載荷參考

每個載荷都包含 eventType。欄位可用性會依事件而異;為維持前向相容性,處理器應忽略未識別的欄位。
📘 關於 status 值的說明。 對於建立/更新的交易,status 欄位可能為 PENDINGSETTLED、或 FAILED。遭拒的交易其 statusDECLINED(或 FAILED)。本頁早期草稿曾顯示 COMPLETED 為一種狀態——實際上不會發出該值;請以 SETTLED 判定交易已最終完成。

交易建立(TRANSACTION_CREATE

在任何新交易時觸發——虛擬卡消費、存款、轉帳,等等。

交易更新(TRANSACTION_UPDATE

當交易的狀態或詳細資訊變更時觸發——例如,待授權交易入帳。
出現的欄位與 TRANSACTION_CREATE 一致,並新增 updatedAt(ISO 8601)表示變更發生時間。userIdconnectedAppIdconnectedAppName 會與 TRANSACTION_CREATE 相同方式帶出,因此你可以在整個生命週期中一致地識別使用者與應用。status 轉為 SETTLED 表示先前的待處理交易已完成入帳。

交易遭拒(TRANSACTION_DECLINE

當交易遭到拒絕時觸發。包含你可據以採取動作的結構化拒絕原因。
視交易而定,可能出現其他選用欄位(例如 merchantIdmerchantCitymerchantStatemerchantCountrycardDisplayNamevirtualCardProgramchannelbankAccountNicknamebankAccountLastFour)。對未使用者可忽略。

存款完成(DEPOSIT_COMPLETE

當從資金來源到消費帳戶的存款完成時觸發。

OAuth 使用者已連結(OAUTH_USER_LINKED

當使用者完成將其帳戶透過 OAuth 連結至你的應用時觸發——包含初次連結與後續更新(例如使用者以不同的 scope 集合重新授權)。僅適用於公開/OAuth 與 widget 應用。接收此事件不需任何 scope。
由於 OAUTH_USER_LINKED 在重新連結/更新時也會觸發,請將其視為 upsert:首次接收時建立已連結使用者,後續接收時更新儲存的 scope 集合。

啟動 KYC(WIDGET_KYC_INITIATION

當使用者開始身分驗證時觸發。僅適用於公開/widget 應用。

轉帳完成 — 客戶至應用(WIDGET_DEPOSIT_COMPLETE

當使用者將資金轉入你的應用時觸發。

轉帳完成 — 應用至客戶(WIDGET_WITHDRAW_COMPLETE

當你的應用將資金轉給使用者時觸發。

禮品卡購買(WIDGET_PURCHASE_GIFT_CARD

當透過 widget 完成禮品卡購買時觸發。
常見的 widget 載荷欄位: userId(Fluz 使用者 ID)、accountId(Fluz 帳戶 ID)、externalReferenceId(你在 OAuth 流程中的使用者識別碼),以及在適用時的 amount

最佳實務

  • 快回應、後處理。 立即回傳 200 並以非同步處理事件,以避免逾時與不必要重試。
  • 驗證每個請求。 使用你的 API key 針對原始本文驗證 X-HMAC-Signature 後再處理。
  • 以事件 ID 去重。 追蹤 X-Event-ID 以處理重試/重複投遞。
  • 將類列舉欄位視為開放字串。 新的 transactionTypechanneldeclineCategory 值可能逐步出現;只對你關心的值進行分支,並容忍未知值。
  • OAUTH_USER_LINKED 採用 upsert。 每位使用者可能多次觸發;每次都更新儲存的 scope 集合,而非假設僅首次觸發。
  • 接受未知欄位。 載荷可能隨時間新增欄位;請忽略未識別的欄位,而非因此失敗。
  • 監控你的端點。 對連續的非 2xx 回應發送警示——在 5 次嘗試失敗後,該事件的投遞會被放棄。

疑難排解

需要協助?

  • 技術問題: 檢查你的端點日誌,並連絡支援時附上 X-Event-ID
  • scope 相關問題: 請參見 應用程式 Scopes拒絕代碼