Để kiểm tra một webhook, bạn cần cung cấp cho nhà cung cấp một URL có thể truy cập, kích hoạt một sự kiện thực tế hoặc sự kiện kiểm thử, rồi xác nhận rằng trình xử lý của bạn nhận payload, xác minh chữ ký, trả về trạng thái đúng và thực hiện đúng tác dụng phụ. Điểm khác biệt so với API thông thường là ứng dụng của bạn đóng vai trò bên nhận, nên quy trình kiểm thử phải tập trung vào việc thu thập request đến, tái phát payload và tự động hóa xác nhận.
Tại sao webhook khó kiểm tra hơn API thông thường
Với API thông thường, bạn chủ động tạo request, gửi đi và đọc response. Với webhook, nhà cung cấp là bên gửi request đến hệ thống của bạn, theo thời điểm và payload do họ định nghĩa.
Điều này tạo ra một số vấn đề khi kiểm thử:
Bạn không luôn tự kích hoạt được sự kiện
Ví dụ, sự kiệnpayment_intent.succeededchỉ xuất hiện khi Stripe tạo ra trạng thái thành công. Vì vậy bạn cần công cụ CLI, dashboard hoặc tính năng test event từ nhà cung cấp.Webhook là bất đồng bộ
Bạn không chờ một return value trực tiếp. Thay vào đó, bạn phải bắt request đến và kiểm tra cách hệ thống xử lý nó.Payload do nhà cung cấp định nghĩa
Trình xử lý của bạn phải parse đúng payload mà GitHub, Stripe, Slack hoặc dịch vụ khác gửi.Nhiều webhook có chữ ký bảo mật
Endpoint của bạn nên xác minh header chữ ký trước khi tin tưởng payload. Nếu test bỏ qua bước này, bạn có thể bỏ sót lỗi bảo mật thực tế. Xem thêm hướng dẫn về xác minh chữ ký webhook.
Nếu bạn vẫn đang chọn mô hình tích hợp, hãy xem thêm webhooks so với polling và webhook so với WebSocket.
Bộ công cụ cần có để kiểm tra webhook
Một quy trình kiểm thử webhook thực tế thường cần bốn nhóm công cụ:
- Dịch vụ thu thập request để xem payload gốc
- Công cụ tunnel để public
localhost - Công cụ kích hoạt sự kiện từ nhà cung cấp
- Công cụ xác nhận response và tác dụng phụ
1. Thu thập payload thật trước khi viết handler
Trước khi triển khai logic xử lý, hãy gửi webhook của nhà cung cấp đến một URL tạm thời để quan sát request thực tế.
Các công cụ phổ biến:
webhook.site
webhook.site tạo một URL ngẫu nhiên và hiển thị mọi request gửi đến URL đó theo thời gian thực, bao gồm:
- Method
- Headers
- Body
- Query parameters
Bản miễn phí có URL hết hạn sau 7 ngày, giới hạn 100 request và request tối đa 10 MB. Gói trả phí hỗ trợ URL vĩnh viễn, request không giới hạn và lịch sử request dài hơn.
Beeceptor
Beeceptor cung cấp endpoint HTTPS miễn phí để nhận webhook và kiểm tra payload đến. Nó cũng hỗ trợ mock server, hữu ích khi bạn muốn vừa thu thập request vừa mô phỏng API.
Pipedream RequestBin
Pipedream RequestBin cũng là lựa chọn phổ biến để bắt request đến. Hãy kiểm tra tài liệu hiện tại của dịch vụ vì giới hạn miễn phí có thể thay đổi.
Mục tiêu của bước này là lấy được một payload thật để dùng lại trong các test có thể lặp lại.
Ví dụ payload Stripe đơn giản:
{
"id": "evt_test",
"type": "payment_intent.succeeded",
"data": {
"object": {
"id": "pi_123",
"status": "succeeded"
}
}
}
2. Kiểm tra webhook trên localhost bằng tunnel
Nhà cung cấp không thể truy cập localhost:3000 trên máy của bạn. Bạn cần một tunnel để tạo URL HTTPS công khai và chuyển tiếp request về server local.
Dùng ngrok
brew install ngrok
ngrok config add-authtoken $YOUR_TOKEN
ngrok http 3000
Sau khi chạy, ngrok sẽ in ra một URL HTTPS công khai. Dán URL đó vào cấu hình webhook của nhà cung cấp, ví dụ:
https://abc123.ngrok-free.app/webhooks
Các tài khoản ngrok miễn phí nhận domain phát triển được chọn tự động. Domain tùy chỉnh yêu cầu gói trả phí.
Dùng cloudflared
cloudflared tunnel --url http://localhost:3000
Tương tự, copy URL công khai mà cloudflared trả về và dùng làm endpoint webhook.
Xem thêm: cách kiểm tra API localhost với các dịch vụ webhook.
3. Kích hoạt sự kiện kiểm thử từ nhà cung cấp
Sau khi có endpoint công khai, bạn cần tạo sự kiện thật hoặc sự kiện test để nhà cung cấp gửi webhook.
Stripe CLI
Stripe CLI hỗ trợ chuyển tiếp event sandbox đến endpoint local.
stripe listen --forward-to localhost:3000/webhooks
Bạn cũng có thể chỉ lắng nghe một số event cụ thể:
stripe listen \
--events payment_intent.succeeded,checkout.session.completed \
--forward-to localhost:3000/webhooks
Lệnh stripe listen sẽ in ra webhook signing secret. Đặt secret này vào cấu hình ứng dụng để handler có thể xác minh chữ ký.
Kích hoạt event test:
stripe trigger payment_intent.succeeded
stripe trigger checkout.session.completed
stripe trigger --help
Lưu ý: một trigger có thể tạo thêm event liên quan. Ví dụ payment_intent.succeeded cũng có thể phát sinh payment_intent.created.
GitHub
GitHub cho phép phát lại delivery gần đây.
Các bước:
- Vào repository
- Mở Settings
- Chọn Webhooks trong phần Code and automation
- Chọn webhook URL
- Mở tab Recent deliveries
- Chọn một GUID delivery
- Nhấn Redeliver
Giới hạn cần nhớ:
- Chỉ phát lại được delivery trong 3 ngày gần nhất
- Cần quyền admin repository
- GitHub không tự động phát lại delivery thất bại
Slack incoming webhook
Slack incoming webhook dễ kiểm tra vì bạn chỉ cần POST JSON đến URL webhook.
curl -X POST https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX \
-H 'Content-type: application/json' \
-d '{"text":"Hello, world."}'
URL webhook của Slack là secret. Không đưa nó vào client-side code hoặc public repository. Slack có thể thu hồi URL bị lộ.
4. Xác nhận handler bằng request có thể lặp lại
Thu thập và kích hoạt webhook giúp bạn biết hệ thống có nhận được event hay không. Nhưng bạn vẫn cần kiểm tra handler xử lý đúng.
Kiểm tra nhanh bằng curl:
curl -X POST http://localhost:3000/webhooks \
-H 'Content-Type: application/json' \
-H 'Stripe-Signature: t=...,v1=...' \
-d '{"id":"evt_test","type":"payment_intent.succeeded","data":{"object":{"id":"pi_123","status":"succeeded"}}}'
Lệnh này phù hợp cho smoke test. Nhưng khi cần test lặp lại trong CI, bạn nên lưu request, payload, headers và assertion trong một công cụ kiểm thử API.
Kiểm tra webhook với Apidog
Apidog là nền tảng API để thiết kế, gỡ lỗi, kiểm thử, mock và tạo tài liệu API. Với webhook, Apidog hữu ích nhất ở các việc sau:
- Tạo và lưu payload mẫu
- Gửi lại request đến handler
- Thêm assertion cho response
- Mock nhà cung cấp khi cần
- Chạy test trong CI bằng CLI
Apidog không phải là “webhook inbox” chuyên dụng, nên bạn vẫn nên dùng công cụ như webhook.site để bắt request thật ban đầu.
Tạo request webhook có thể tái sử dụng trong Apidog
Quy trình:
- Thu thập payload thật từ webhook.site hoặc tài liệu nhà cung cấp
- Tạo request mới trong Apidog
- Chọn method
POST - Nhập URL handler, ví dụ:
http://localhost:3000/webhooks
- Thêm headers nhà cung cấp thường gửi:
Content-Type: application/json
Stripe-Signature: t=...,v1=...
- Dán payload JSON vào body
- Lưu request vào project
Từ đây, bạn có thể gửi lại cùng một payload nhiều lần mà không phải gõ lại curl.
Bạn cũng nên lưu nhiều biến thể payload:
- Payload hợp lệ
- Payload thiếu field bắt buộc
- Payload có event type không hỗ trợ
- Payload có chữ ký sai
- Payload trùng event ID để test idempotency
Thêm assertion để kiểm tra response
Gửi request chỉ là một nửa bài test. Bạn cần xác nhận handler trả về đúng kết quả.
Trong Apidog:
- Mở request hoặc scenario
- Vào Post Processors
- Nhấn + Add
- Chọn Assertion
- Cấu hình rule kiểm tra response
Ví dụ kiểm tra status trong JSON response:
JSON path: $.data.status
Condition: Equals
Expected: succeeded
Nếu response là:
{
"data": {
"status": "succeeded"
}
}
Assertion sẽ pass khi $.data.status bằng succeeded.
Bạn nên thêm các assertion như:
- HTTP status phải là
200hoặc204 - Response body có field mong muốn
- Event ID được ghi nhận
- Error message đúng khi payload không hợp lệ
- Chữ ký sai bị từ chối với
400hoặc401
Ví dụ với script kiểu Postman-compatible pm.test khi cần kiểm tra linh hoạt hơn:
pm.test("status is succeeded", function () {
const json = pm.response.json();
pm.expect(json.data.status).to.eql("succeeded");
});
Dùng Apidog Mock để mô phỏng nhà cung cấp
Đôi khi hệ thống của bạn không chỉ nhận webhook mà còn gọi ngược đến API của nhà cung cấp. Khi test local, bạn có thể không muốn gọi API thật vì có thể phát sinh side effect.
Apidog hỗ trợ mock server để thay thế nhà cung cấp trong môi trường test.
Các loại mock gồm:
- Local Mock: chạy cùng desktop client, chỉ hoạt động khi client mở
- Cloud Mock: chạy trên server Apidog, có thể hoạt động 24/7, mặc định tắt
- Runner Mock: chạy trên hạ tầng runner tự host và chia sẻ trong team
Cách dùng:
- Tạo endpoint API trong Apidog
- Cấu hình response mẫu
- Mở module Mock
- Copy mock URL
- Trỏ code test của bạn đến mock URL đó
Lưu ý: chỉ các path bắt đầu bằng / mới được định tuyến đến môi trường mock.
Chạy test webhook trong CI bằng Apidog CLI
Khi scenario đã chạy ổn ở local, bạn có thể đưa vào CI.
Cài Apidog CLI:
npm install -g apidog-cli
node -v
apidog -v
which node
which npm
which apidog
Apidog CLI yêu cầu Node.js v16 trở lên.
Chạy một scenario đã lưu:
apidog run \
--access-token $APIDOG_ACCESS_TOKEN \
-t 637132 \
-e 358171 \
-d 3497013 \
-r html,cli
Ý nghĩa tham số:
-
--access-token: access token của Apidog -
-t: test scenario -
-e: environment, bắt buộc -
-d: test data, có thể là CSV, JSON hoặc ID dataset đã lưu -
-r: reporter, hỗ trợcli,html,json,junit
Xem thêm: hướng dẫn Apidog CLI.
Bạn muốn xây dựng và xác nhận test webhook trực quan? Hãy dùng thử Apidog miễn phí, không yêu cầu thẻ tín dụng.
Quy trình kiểm tra webhook từng bước
Dưới đây là quy trình thực tế có thể áp dụng cho hầu hết webhook.
Bước 1: Thu thập payload thật
Trỏ webhook của nhà cung cấp đến webhook.site hoặc công cụ tương tự.
Ghi lại:
- Body
- Headers
- Signature header
- Event type
- Retry behavior nếu có
Bước 2: Chạy handler ở local
Ví dụ server chạy ở cổng 3000:
npm run dev
Endpoint:
http://localhost:3000/webhooks
Bước 3: Public localhost bằng tunnel
Dùng ngrok:
ngrok http 3000
Hoặc cloudflared:
cloudflared tunnel --url http://localhost:3000
Dán URL HTTPS public vào cấu hình webhook của nhà cung cấp.
Bước 4: Kích hoạt event thật hoặc event test
Ví dụ với Stripe:
stripe trigger payment_intent.succeeded
Ví dụ với Slack:
curl -X POST $SLACK_WEBHOOK_URL \
-H 'Content-type: application/json' \
-d '{"text":"Webhook test"}'
Bước 5: Kiểm tra xác minh chữ ký
Gửi cùng payload với chữ ký hợp lệ và chữ ký sai.
Kỳ vọng:
- Chữ ký hợp lệ: handler chấp nhận
- Chữ ký sai: handler từ chối
Ví dụ kết quả mong muốn:
Valid signature -> 200 OK
Invalid signature -> 400 Bad Request hoặc 401 Unauthorized
Bước 6: Xác nhận response và side effect
Không chỉ kiểm tra HTTP 200.
Hãy xác nhận thêm:
- Database có record mới
- Event ID đã được lưu để chống xử lý trùng
- Job hoặc message queue được tạo
- Trạng thái đơn hàng được cập nhật
- Không xử lý lại event trùng
Bước 7: Lưu thành test có thể chạy lại
Đưa payload vào Apidog, thêm assertion và lưu thành scenario.
Sau đó chạy trong CI bằng Apidog CLI để phát hiện regression khi handler thay đổi.
Checklist test webhook
Trước khi đưa webhook handler lên production, hãy kiểm tra tối thiểu:
- [ ] Endpoint có thể truy cập qua HTTPS
- [ ] Handler parse đúng payload thật
- [ ] Kiểm tra đúng event type
- [ ] Xác minh chữ ký webhook
- [ ] Từ chối payload có chữ ký sai
- [ ] Trả về status phù hợp
- [ ] Xử lý idempotency bằng event ID
- [ ] Không xử lý trùng event đã nhận
- [ ] Log đủ thông tin để debug
- [ ] Không log secret hoặc full signature
- [ ] Có test cho payload thiếu field
- [ ] Có test cho event không hỗ trợ
- [ ] Có test chạy trong CI
Nếu bạn đang thiết kế hệ thống webhook, xem thêm cách thiết kế webhooks đáng tin cậy và các thực hành tốt nhất cho webhook thanh toán. Để hiểu bối cảnh rộng hơn, tham khảo hướng dẫn API webhooks và webhooks trong kiến trúc hướng sự kiện.
Các câu hỏi thường gặp
Làm thế nào để kiểm tra một webhook?
Cung cấp cho nhà cung cấp một URL có thể truy cập, kích hoạt event thật hoặc event test, rồi xác nhận handler nhận payload, xác minh chữ ký, trả về status đúng và thực hiện đúng side effect. Nên bắt đầu bằng việc thu thập payload thật, sau đó lưu payload đó thành request có assertion để test lặp lại.
Làm thế nào để kiểm tra webhook cục bộ?
Chạy handler trên local, ví dụ localhost:3000, rồi public nó bằng tunnel:
ngrok http 3000
Hoặc:
cloudflared tunnel --url http://localhost:3000
Sau đó dán URL HTTPS public vào cấu hình webhook của nhà cung cấp và kích hoạt event.
Làm thế nào để kiểm tra webhook với Postman?
Postman có thể gửi payload mẫu đến endpoint và kiểm tra response, nhưng không tự nhận webhook đến như một webhook inbox. Apidog cũng tương tự: bạn tạo request với payload và headers của nhà cung cấp, thêm assertion, rồi lưu thành test có thể tái sử dụng. Để bắt webhook thật, hãy dùng thêm webhook.site, RequestBin hoặc tunnel.
Làm thế nào để kiểm tra webhook của Stripe?
Dùng Stripe CLI:
stripe listen --forward-to localhost:3000/webhooks
Sau đó trigger event:
stripe trigger payment_intent.succeeded
Bạn cũng có thể xem danh sách event hỗ trợ:
stripe trigger --help
Lưu ý rằng một trigger có thể phát sinh thêm event liên quan, ví dụ payment_intent.succeeded có thể đi kèm payment_intent.created.
Làm thế nào để kiểm tra webhook của Slack?
Gửi POST JSON đến incoming webhook URL:
curl -X POST $SLACK_WEBHOOK_URL \
-H 'Content-type: application/json' \
-d '{"text":"Hello, world."}'
Nếu thành công, tin nhắn sẽ xuất hiện trong kênh đã cấu hình. Luôn giữ URL webhook bí mật.
Làm thế nào để kiểm tra một URL webhook?
Gửi POST request mẫu đến URL và kiểm tra response. Với smoke test, bạn có thể dùng curl. Với test đáng tin cậy hơn, hãy dùng payload thật, kiểm tra cả chữ ký hợp lệ và không hợp lệ, rồi xác nhận response cùng các side effect thay vì chỉ kiểm tra mã 200.
Top comments (0)