何時使用 Webhook
沒有 Webhook 時,串接程式必須反覆向 API 查詢資料是否有變動。使用 Webhook 後,事件一發生 OB 就會主動呼叫您的伺服器,您的系統不需要輪詢,也不會消耗 API 的請求額度。
Webhook 屬於 API 客製化功能,因此必須先啟用該功能。每個商家可設定一個 Webhook 端點,您的開發人員需要準備一台具備公開 HTTPS 網址的伺服器來接收請求。
設定 Webhook
- 前往後台 → 客製化功能 → API → Webhook 通知。
- 在 Webhook 網址輸入您伺服器的網址。網址必須以
https://開頭,且能從公開網際網路連線;系統不會跟隨重新導向。 - 保持開啓。
- 在 Webhook 事件下開啟需要的事件。新建立的端點預設全部開啟。
- 點選儲存。
- 在網址下方,點選簽章密鑰下的複製,並將密鑰交給開發人員。密鑰在點選眼睛圖示前會以遮罩呈現,之後隨時都能再次查看或複製,即使尚未儲存網址也可以。
之後若要暫停傳送,請關閉開啓並儲存,網址與事件設定都會保留。
每次變更網址時,OB 會對該網址傳送一次測試請求,並在欄位下方顯示結果:回應為 2xx 時以綠色顯示回應代碼,否則顯示包含代碼或連線錯誤的警告。測試請求是 data 為空的 ping 事件;會以您的簽章密鑰簽章;若從未顯示過密鑰且尚未儲存網址,則不簽章。出現警告不會阻止您儲存。您的伺服器應忽略 ping 類型。
可接收的事件
| 事件 | 傳送時機 | 資料 |
|---|---|---|
reservation.created | 預約已確認。尚待付款的預約會在確認後才傳送。 | 預約 |
reservation.cancelled | 預約被顧客或員工取消,包含整個時段被取消的情況。 | 預約 |
reservation.attendance | 預約的出席狀態變更,例如報到。 | 預約 |
calendar.created | 課表新增時段。 | 行事曆時段 |
calendar.updated | 員工編輯時段,例如時間、教室或人數。 | 行事曆時段 |
calendar.cancelled | 時段被取消。 | 行事曆時段 |
user.created | 顧客註冊,或由員工新增顧客。 | 使用者 |
user.updated | 員工編輯使用者,或顧客編輯自己的個人資料。 | 使用者 |
user-pass.created | 顧客持有新的課卡。於付款確認後傳送,因此銀行轉帳會在員工確認後才通知。 | 已購課卡 |
user-pass.updated | 員工編輯顧客持有的課卡,例如到期日或堂數。預約扣除課卡時不會傳送。 | 已購課卡 |
payment.created | 建立付款紀錄,包含仍待確認的銀行轉帳。 | 付款及其項目與總額 |
payment.updated | 員工編輯付款,或付款已確認。 | 付款及其項目與總額 |
class.created、class.updated、class.deleted | 員工建立、編輯或刪除課程。 | 課程 |
pass.created、pass.updated、pass.deleted | 員工建立、編輯或刪除課卡。 | 課卡 |
資料與 API 回傳的物件完全相同,例如與 GET /v1/reservations/{id} 或 GET /v1/payments/{id} 的回應一致,因此同一套程式即可同時處理兩者。
每次請求的內容
每個事件都是一次 POST 請求,內容為 JSON:
{
"id": "2b4f1c0e-8a7d-4c1e-9f3a-6d5e4c3b2a10",
"type": "reservation.created",
"createdAt": "2026-11-10T09:30:00Z",
"data": { ... }
}id——此次傳送的唯一識別碼,可用來略過已處理過的事件。type——事件名稱。createdAt——事件發生時間(UTC)。data——事件所屬的資料。
請求包含三個標頭:X-OmceanBooking-Event(事件名稱)、X-OmceanBooking-Delivery(與 id 相同),以及 X-OmceanBooking-Signature。
各物件的完整欄位請參閱 API 文件。
驗證簽章
任何知道您網址的人都能對它送出請求,因此在信任請求之前務必先驗證簽章。X-OmceanBooking-Signature 標頭的格式為 t=1794300000,v1=5f2b…,其中 t 為時間戳記,v1 為簽章。
- 將時間戳記、一個句點,以及收到的原始請求內容串接:
t + "." + body。 - 使用簽章密鑰對該字串計算 HMAC-SHA256。
- 將結果與
v1比對,若不相同請拒絕該請求。 - 若時間戳記已超過數分鐘,請拒絕該請求。
請使用原始請求內容,而不是將解析後的 JSON 重新編碼,否則簽章不會相符。程式範例請參閱 API 文件。
回應、重試與重複事件
請在 10 秒內回應任一 2xx 狀態以確認收到,耗時的處理請在回應後進行。
若您的伺服器回應其他狀態、逾時或無法連線,OB 會在 1 分鐘後重試,接著是 5 分鐘、15 分鐘。三次重試後仍失敗,該次傳送會標記為失敗,不再重送。
- 可能收到重複事件。重試可能在您的伺服器已處理後才送達。請記錄
id,並略過已處理過的事件。 - 不保證順序。重試的事件可能比較新的事件晚到。若順序重要,請使用
createdAt,或向 API 查詢目前的資料。 - 事件發生時即傳送。事件不會批次傳送。
更換簽章密鑰
若密鑰可能外洩,請前往後台 → 客製化功能 → API → Webhook 通知,點選簽章密鑰下的重新產生並確認,新密鑰會立即顯示。若只是忘記密鑰則不需更換,點選眼睛圖示即可再次查看。
舊密鑰會立即失效,之後送出的請求都以新密鑰簽章,在您的伺服器更新之前都會驗證失敗。請與開發人員安排好更換時間。
疑難排解
- 儲存時網址被拒絕。網址必須以
https://開頭、主機名稱必須能解析,且不可指向內部網路。 - 沒有收到任何事件。請確認已啟用 API 客製化功能、開啓為開啟狀態,且預期的事件已開啟。
- 查看已傳送的事件。後台 → 客製化功能 → API → 使用量 → Webhook 通知會列出每個事件的狀態、您的伺服器回傳的回應代碼、嘗試次數、最後一次嘗試花費的時間,以及錯誤訊息。
- 購買課卡後沒有收到
user-pass.created。以銀行轉帳付款的課卡,要等員工確認付款後才會通知;payment.created則會立即傳送。 - 簽章不相符。請使用原始請求內容,並確認伺服器在重新產生後已改用最新的密鑰。
- 測試 Token。測試 Token 所使用的 API 沙盒環境不會傳送 Webhook。
