Tiếng Việt
Tiếng Việt
Appearance
Tiếng Việt
Tiếng Việt
Appearance
Webhooks thông báo cho ứng dụng của bạn theo thời gian thực khi có sự kiện xảy ra với chứng chỉ của bạn — khi một chứng chỉ được cấp, gửi đi, thu hồi hoặc được xem. Thay vì phải liên tục truy vấn API, bạn đăng ký một điểm cuối HTTPS và badges.ninja sẽ gửi tới đó một POST đã ký cho mỗi sự kiện mà bạn đăng ký.
Tất cả các điểm cuối quản lý đều yêu cầu xác thực qua header X-Api-Key. Xem Xác thực. Việc tạo hoặc xóa điểm cuối yêu cầu khóa có phạm vi write; việc liệt kê yêu cầu phạm vi read. Xem Khóa API.
POST /webhooks| Tham số | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
url | string | Có | Điểm cuối HTTPS của bạn. Phải bắt đầu bằng https://. |
events | string[] | Không | Các loại sự kiện muốn đăng ký. Bỏ trống hoặc truyền ["*"] để nhận tất cả các sự kiện. |
curl -X POST https://api.badges.ninja/webhooks \
-H "X-Api-Key: bws_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/hooks/badges",
"events": ["credential.issued", "credential.delivered"]
}'201 Created. Khóa bí mật để ký chỉ được trả về một lần — hãy lưu ngay bây giờ; bạn không thể lấy lại nó nữa.
{
"id": "e4b19ff5-063d-4799-bd75-d03641be624f",
"url": "https://example.com/hooks/badges",
"events": ["credential.issued", "credential.delivered"],
"secret": "2be6d335682c1658242fde3a523fd8a2493bab8c"
}GET /webhooksTrả về các điểm cuối bạn đã đăng ký. Khóa bí mật để ký không bao giờ được bao gồm.
{
"webhooks": [
{
"id": "e4b19ff5-063d-4799-bd75-d03641be624f",
"url": "https://example.com/hooks/badges",
"events": ["credential.issued", "credential.delivered"],
"active": true,
"failureCount": 0,
"createdAt": 1787685415083,
"lastStatus": 200,
"lastDeliveryAt": 1787685480777
}
]
}DELETE /webhooks/{id}curl -X DELETE https://api.badges.ninja/webhooks/e4b19ff5-063d-4799-bd75-d03641be624f \
-H "X-Api-Key: bws_your_api_key_here"Việc gửi tới điểm cuối sẽ dừng lại ngay lập tức.
| Sự kiện | Kích hoạt khi… |
|---|---|
credential.issued | Một chứng chỉ được cấp cho người nhận. |
credential.delivered | Email thông báo của một chứng chỉ được gửi tới người nhận (đơn lẻ hoặc hàng loạt). |
credential.revoked | Một chứng chỉ bị thu hồi. |
credential.viewed | Trang chứng chỉ công khai của người nhận được xem lần đầu tiên. |
Mỗi lần gửi là một POST với phần thân JSON có dạng sau:
{
"id": "b1c2d3e4-...",
"type": "credential.issued",
"createdAt": 1787685415083,
"data": { }
}| Trường | Mô tả |
|---|---|
id | Id gửi đi duy nhất (dùng để loại bỏ trùng lặp). |
type | Loại sự kiện. |
createdAt | Dấu thời gian sự kiện (mili-giây epoch). |
data | Payload riêng theo từng sự kiện (xem bên dưới). |
data theo loại sự kiện credential.issued
{
"awardId": "https://api.badges.ninja/certify-badge/award/<guid>",
"badgeId": "https://api.badges.ninja/certify-badge/badge/<guid>",
"badgeName": "Advanced Certification",
"recipient": { "email": "jane@example.com", "name": "Jane Doe" },
"issuedOn": "2026-08-25",
"expires": null
}credential.delivered
{
"awardId": "https://api.badges.ninja/certify-badge/award/<guid>",
"recipient": { "email": "jane@example.com", "name": "Jane Doe" },
"badgeName": "Advanced Certification"
}credential.revoked
{ "awardId": "https://api.badges.ninja/certify-badge/award/<guid>", "reason": "Issued in error" }credential.viewed
{
"awardId": "https://api.badges.ninja/certify-badge/award/<guid>",
"recipient": { "email": "jane@example.com", "name": "Jane Doe" }
}Mỗi lần gửi mang theo các header sau:
| Header | Mô tả |
|---|---|
X-Bws-Event | Loại sự kiện (giống với type trong phần thân). |
X-Bws-Delivery | Id lần gửi (giống với id trong phần thân). |
X-Bws-Signature | sha256= theo sau là HMAC-SHA256 của phần thân yêu cầu thô, được ký bằng khóa bí mật của điểm cuối. |
User-Agent | badges.ninja-webhooks/1 |
Luôn xác minh chữ ký trước khi tin tưởng một lần gửi. Tính HMAC-SHA256 của phần thân yêu cầu thô bằng khóa bí mật ký của điểm cuối, rồi so sánh nó (theo thời gian hằng số) với header X-Bws-Signature.
import crypto from "node:crypto";
function verify(rawBody, signatureHeader, secret) {
const expected = "sha256=" +
crypto.createHmac("sha256", secret).update(rawBody, "utf8").digest("hex");
const a = Buffer.from(signatureHeader);
const b = Buffer.from(expected);
return a.length === b.length && crypto.timingSafeEqual(a, b);
}Hãy dùng đúng các byte bạn nhận được — việc phân tích và tuần tự hóa lại JSON trước sẽ làm thay đổi các byte và phá vỡ chữ ký.
2xx.failureCount; sau 20 lần thất bại liên tiếp, một điểm cuối sẽ bị tự động vô hiệu hóa (active: false) và ngừng nhận các lần gửi cho đến khi bạn khắc phục và đăng ký một điểm cuối mới.X-Bws-Delivery (hoặc id trong phần thân) để làm cho trình xử lý của bạn có tính bất biến (idempotent).Bạn cũng có thể quản lý các điểm cuối mà không cần API — mở Webhooks trong thanh bên của bảng điều khiển để thêm, liệt kê và xóa điểm cuối cũng như chọn sự kiện nào mà mỗi điểm cuối sẽ nhận.