想像一個情境:
你做了一個電商網站,使用者下單後會跳轉到第三方金流頁面付款。
問題來了:使用者付完錢之後,你的網站怎麼知道他付了?
你可能會想:「讓網站每隔幾秒去問金流公司:『這筆訂單付了沒?付了沒?付了沒?』」
這樣做當然可以,但很蠢——浪費資源又不即時。
更聰明的做法是:讓金流公司付款完成後,主動通知你的伺服器。
這個「主動通知」的機制,就叫做 Webhook。
學會 Webhook,你就能實現這些功能:
- 付款完成 → 自動更新訂單狀態、寄確認信
- 有人推程式碼到 GitHub → 自動部署網站
- LINE 收到訊息 → 你的機器人自動回覆
讓我們一步步來理解它!
Webhook 到底是什麼?
先拆解這個詞
Webhook = Web + Hook
- Web:透過網路
- Hook:鉤子、掛勾
那什麼是「掛」?
「掛」其實就是「登記」的意思。
就像去餐廳候位,你會在名單上登記你的電話號碼,有位子時店員會打給你。
Webhook 也一樣——你把網址登記到第三方服務上,有事情發生時它會通知你。
當你使用第三方服務(例如金流)時,它的後台通常會有一個欄位讓你填寫「Webhook URL」:
把你的網址填進去,就是「登記」(掛)的動作。
登記之後,當特定事件發生(例如付款完成),第三方服務就會把資料送到你登記的這個網址。
運作方式
sequenceDiagram
participant User as 使用者
participant Payment as 第三方金流
participant Server as 你的伺服器
User->>Payment: 付款完成
Payment->>Payment: 檢查有沒有登記 Webhook
Payment->>Server: HTTP POST 付款結果
Server->>Server: 處理付款結果
Server->>Server: 更新訂單狀態
Server-->>Payment: 回應 200 OK簡單來說:Webhook 就是讓 A 伺服器在某件事發生時,主動把消息送給 B 伺服器。
一句話定義
Webhook 就是:你先在第三方服務「登記」一個網址,當某個事件發生時,它就會主動用 HTTP POST 把資料送到這個網址。
為什麼需要 Webhook?
沒有 Webhook 的世界:一直問、一直問
想像你在等一個包裹,但物流公司不會通知你。你只能:
你:「包裹到了嗎?」
物流:「還沒。」
(5 分鐘後)
你:「包裹到了嗎?」
物流:「還沒。」
(5 分鐘後)
你:「包裹到了嗎?」
物流:「還沒。」
... 一直問到包裹到為止 😩這種方式在程式裡叫做 Polling(輪詢)——你的程式每隔一段時間就去問一次「好了沒?好了沒?」
Polling 的問題:
| 問題 | 說明 |
|---|---|
| 浪費資源 | 大部分的請求都是「還沒好」,做白工 |
| 有延遲 | 如果每 5 分鐘問一次,最慢要等 5 分鐘才知道結果 |
| 給對方壓力 | 一直發請求,對方伺服器也會累 |
有 Webhook 的世界:好了叫我
你:「這是我的電話號碼,包裹到了打給我。」
物流:「OK!」
(你去做其他事)
物流:「叮鈴鈴~包裹到了!」 📞
你:「太好了!我來處理。」這就是 Webhook 的運作方式——你給對方一個「通知網址」,事情完成時對方主動通知你。
Webhook 的好處:
| 好處 | 說明 |
|---|---|
| 即時 | 事件發生的當下就通知你,不用等 |
| 省資源 | 不用一直發請求去問 |
| 簡單 | 你只要開一個 API 等通知就好 |
Webhook 的運作流程
讓我們用「第三方金流」的實際案例來說明。
場景:使用者在你的網站上買東西
參與者:
- 使用者(顧客)
- 你的伺服器(Server 2)
- 第三方金流(Server 1,例如綠界、藍新)完整流程圖
sequenceDiagram
participant User as 使用者
participant Server as 你的伺服器
participant Payment as 第三方金流
User->>Server: ① 點擊結帳
Server->>Payment: ② 建立訂單
Payment-->>User: ③ 跳轉到付款頁面
User->>Payment: ④ 輸入卡號、完成付款
Payment->>Server: ⑤ Webhook!POST 付款結果
Server->>Server: ⑥ 更新訂單狀態
Server-->>User: ⑦ 顯示「付款成功」關鍵步驟解析
步驟 ⑤ 就是 Webhook 發生的地方!
當使用者在第三方金流那邊付款完成後:
- 第三方金流的系統觸發了「付款完成」事件
- 系統檢查:「這筆訂單有設定 Webhook 網址嗎?」
- 有!網址是
https://你的網站.com/api/payment-callback - 用 HTTP POST 把付款結果送到這個網址
Webhook 傳送的資料長什麼樣?
當 Webhook 觸發時,第三方服務會送一包資料給你。通常包含:
常見的資料結構
POST /api/payment-callback HTTP/1.1
Host: 你的網站.com
Content-Type: application/json
X-Webhook-Signature: sha256=a1b2c3d4e5f6...
{
"event": "payment.completed",
"type": "payment",
"payload": {
"order_id": "ORD-20241230-001",
"amount": 1500,
"currency": "TWD",
"status": "success",
"paid_at": "2024-12-30T14:30:00Z",
"payment_method": "credit_card"
}
}| 部分 | 說明 |
|---|---|
| POST /api/payment-callback | 送到你登記的 Webhook 網址 |
| Content-Type | 資料格式,通常是 JSON |
| X-Webhook-Signature | 簽章,用來驗證請求是否來自真正的第三方服務 |
| Body(event, type, payload) | 實際的事件資料 |
不同服務,格式不同
每個第三方服務給你的資料格式都不一樣,這是由他們決定的,不是你。
所以串接前一定要看他們的文件!
如何接收 Webhook?
你需要在自己的伺服器上開一個 API 端點 來接收 Webhook。
以 Node.js + Express 為例
const express = require('express');
const app = express();
// 解析 JSON 格式的請求
app.use(express.json());
// 開一個 API 來接收 Webhook
app.post('/api/payment-callback', (req, res) => {
// 收到的資料在 req.body 裡面
const { event, payload } = req.body;
console.log('收到 Webhook!');
console.log('事件類型:', event);
console.log('訂單編號:', payload.order_id);
console.log('付款狀態:', payload.status);
// 根據狀態更新你的訂單
if (payload.status === 'success') {
// 更新資料庫:訂單已付款
updateOrderStatus(payload.order_id, '已付款');
// 可能還要做其他事:發確認信、準備出貨等
sendConfirmationEmail(payload.order_id);
}
// 回應 200 告訴對方「我收到了」
res.status(200).send('OK');
});
app.listen(3000, () => {
console.log('伺服器啟動,等待 Webhook...');
});重要!一定要回應 200
當你收到 Webhook 後,一定要回傳 HTTP 200 狀態碼,告訴對方「我收到了」。
如果你沒回應或回傳錯誤,對方可能會:
- 以為你沒收到,重複發送
- 多次失敗後,停止發送給你
設定 Webhook 網址
在使用第三方服務時,你需要告訴他們「要把 Webhook 打到哪裡」。
在哪裡設定?
通常在第三方服務的後台,會有一個欄位讓你填寫 Webhook URL:
Webhook URL: https://你的網站.com/api/payment-callback網址的要求
| 要求 | 說明 |
|---|---|
| 必須是公開網址 | 對方要能從網路上連到你 |
| 建議用 HTTPS | 比較安全,有些服務強制要求 |
| 必須能回應 POST | Webhook 通常用 POST 方法 |
本地開發怎麼辦?
在開發階段,你的電腦通常沒有公開網址。可以用這些工具:
- ngrok:把你的 localhost 暴露到網路上
- localtunnel:類似 ngrok 的免費工具
# 使用 ngrok 範例
ngrok http 3000
# 會給你一個臨時網址,例如:
# https://abc123.ngrok.ioWebhook 的實際應用場景
金流串接
這是最常見的 Webhook 應用場景。
問題:使用者在第三方金流頁面付款,你的網站怎麼知道他付了?
解法:金流公司付款完成後,發 Webhook 通知你。
sequenceDiagram
participant User as 使用者
participant Payment as 金流公司
participant Server as 你的伺服器
User->>Payment: 付款完成
Payment->>Server: Webhook:付款成功
Server->>Server: 更新訂單狀態
Server->>User: 寄送確認信常見的台灣金流服務:
| 服務 | Webhook 事件 |
|---|---|
| 綠界 ECPay | 付款完成、退款、定期扣款 |
| 藍新 NewebPay | 付款完成、付款失敗、退款 |
| LINE Pay | 付款完成、退款 |
CI/CD 自動部署
這是工程師最愛的 Webhook 應用!
問題:每次改完程式碼,都要手動登入伺服器部署,很麻煩。
解法:程式碼推上 GitHub 後,GitHub 發 Webhook 通知伺服器自動部署。
sequenceDiagram
participant Dev as 工程師
participant GitHub as GitHub
participant Server as 部署伺服器
Dev->>GitHub: git push 推程式碼
GitHub->>Server: Webhook:有新程式碼
Server->>Server: 自動拉取程式碼
Server->>Server: 自動重啟服務
Server-->>Dev: 部署完成通知這就是為什麼你 git push 之後,網站會自動更新!
常見的 CI/CD 工具:GitHub Actions、GitLab CI、Jenkins 都支援 Webhook 觸發。
聊天機器人
所有聊天機器人都是靠 Webhook 運作的!
問題:使用者在 LINE 發訊息給你的機器人,你的程式怎麼收到訊息?
解法:LINE 收到訊息後,發 Webhook 到你的伺服器。
sequenceDiagram
participant User as 使用者
participant LINE as LINE 平台
participant Bot as 你的機器人伺服器
User->>LINE: 傳送訊息「你好」
LINE->>Bot: Webhook:收到訊息
Bot->>Bot: 處理訊息、產生回覆
Bot->>LINE: 回覆「你好!有什麼可以幫你的?」
LINE->>User: 顯示回覆常見的聊天平台:
| 平台 | Webhook 事件 |
|---|---|
| LINE Bot | 收到訊息、使用者加入好友、使用者封鎖 |
| Telegram Bot | 收到訊息、收到圖片、群組事件 |
| Discord Bot | 收到訊息、使用者加入伺服器、反應表情 |
| Slack Bot | 收到訊息、頻道事件、使用者互動 |
第三方服務整合
把不同的服務串連起來,實現自動化工作流程。
範例一:電商自動化
sequenceDiagram
participant Stripe as Stripe 金流
participant Server as 你的伺服器
participant Warehouse as 倉儲系統
participant Email as 郵件服務
Stripe->>Server: Webhook:收到付款
Server->>Warehouse: 建立出貨單
Server->>Email: 寄送訂單確認信範例二:內容同步
sequenceDiagram
participant Notion as Notion
participant Server as 你的伺服器
participant Blog as 部落格網站
Notion->>Server: Webhook:頁面更新
Server->>Server: 轉換格式
Server->>Blog: 發布新文章常見整合場景:
| 觸發來源 | Webhook 事件 | 可以做什麼 |
|---|---|---|
| Notion | 頁面更新 | 同步到部落格、更新文件 |
| Stripe | 付款成功 | 開通會員、發貨、寄信 |
| Shopify | 新訂單 | 同步到 ERP、通知倉庫 |
| Google Forms | 新回覆 | 寄通知、存到資料庫 |
Webhook vs Polling 比較
| 比較項目 | Webhook | Polling |
|---|---|---|
| 運作方式 | 對方主動通知你 | 你主動去問對方 |
| 即時性 | 即時 | 有延遲(看你多久問一次) |
| 資源消耗 | 低 | 高(一直發請求) |
| 實作複雜度 | 需要開 API 接收 | 簡單,但要處理重複邏輯 |
| 可靠性 | 依賴對方的實作 | 你可以控制 |
什麼時候用 Webhook?
- ✅ 第三方服務支援 Webhook
- ✅ 需要即時反應
- ✅ 事件發生頻率不固定
什麼時候用 Polling?
- ✅ 第三方不支援 Webhook
- ✅ 你需要完全掌控請求時機
- ✅ 資料更新頻率很固定
Webhook 的限制與注意事項
限制一:取決於第三方
Webhook 好不好用,完全取決於第三方服務:
| 問題 | 說明 |
|---|---|
| 事件種類有限 | 他只給你「付款成功」,不給「付款失敗」,你就不知道失敗了 |
| 資料不完整 | 他只給你訂單編號,不給金額,你就要自己去查 |
| 格式他決定 | 欄位名稱、資料結構都是他定的 |
限制二:網路問題
第三方發 Webhook → ❌ 你的伺服器剛好掛了 → 資料遺失?好的第三方服務會有重試機制,但不是每家都有。
限制三:安全性
任何人都可以假裝是第三方,發假的 Webhook 給你!
解決方案:驗證簽章(Signature)
// 很多服務會在 Header 加上簽章
const signature = req.headers['x-webhook-signature'];
// 你要驗證這個簽章是否正確
const isValid = verifySignature(req.body, signature, SECRET_KEY);
if (!isValid) {
return res.status(401).send('Invalid signature');
}Webhook 開發檢查清單
開發 Webhook 接收端時,確認以下事項:
- [ ] API 端點使用 POST 方法
- [ ] 能正確解析 JSON 資料
- [ ] 收到後回傳 HTTP 200
- [ ] 有驗證簽章(如果第三方有提供)
- [ ] 有記錄 log 方便除錯
- [ ] 處理重複請求(冪等性)
- [ ] 有錯誤處理機制
補充:Webhook 和傳統 Hook 是不同的東西!
看到「Webhook」這個名字,你可能會想:「這是 Hook(掛勾/勾點編程)的一種嗎?」
答案是:不太一樣!
名稱的由來
Webhook 這個詞是由程式開發者 Jeff Lindsay 在 2007 年創造的。他從程式設計術語「Hook」借用了這個詞,但兩者的本質其實不同:
| 傳統 Hook(勾點編程) | Webhook | |
|---|---|---|
| 本質 | 攔截機制 | 通知機制 |
| 能力 | 可攔截、修改、阻止流程 | 只能被動接收通知 |
| 運作位置 | 同一個系統內部 | 跨網路、跨伺服器 |
| 你能做什麼 | 深度介入、改變原本的行為 | 收到通知後做自己的事 |
用比喻來說明
傳統 Hook(勾點編程):
像是在河裡放魚鉤 🪝
魚游過來時,你可以:
- 看一眼就放走
- 幫牠做記號再放走
- 不讓牠繼續往下游(攔截)Webhook:
像是在河邊裝感應器 📡
魚游過去時,感應器發出「叮!」通知你
但魚已經游走了,你只是被通知,無法攔截那為什麼叫 Webhook?
因為 Jeff Lindsay 強調的是「把 URL 掛上去」這個動作:
✅ 你把一個網址「掛」到第三方服務上,等他通知你
❌ 不是你去「攔截」第三方的程式流程
如果當初叫 WebCallback 或 WebNotify 可能更精確,但 Webhook 這個名字已經流行了 😂
結論:Webhook 本質上是「跨伺服器的事件通知機制」,和傳統的 Hook(攔截機制)是不同的概念,只是借用了名字。
總結
核心觀念
| 概念 | 說明 |
|---|---|
| Webhook | 第三方服務發生事件時,主動通知你的機制 |
| Webhook URL | 你提供的「通知網址」,讓對方知道要打給誰 |
| Payload | 通知時附帶的資料(事件內容) |
| HTTP POST | 傳送通知的方式 |
三個重點
- Webhook 是被動接收:你開一個 API 等著,對方主動打給你
- 比 Polling 更即時:不用一直問,事件發生就通知
- 取決於第三方:對方給什麼事件、什麼資料,你就只能收什麼
常見使用場景
金流通知 → 付款完成、退款、扣款失敗
CI/CD → 程式碼推送、合併請求
聊天機器人 → 收到訊息、使用者加入
第三方整合 → 資料同步、狀態更新💡 小提醒:每個第三方服務的 Webhook 實作細節都不同,串接前一定要詳讀他們的文件!