
Webhook là cách một phần mềm tự báo cho phần mềm khác ngay khi có chuyện xảy ra: có đơn hàng mới, khách vừa chuyển khoản, có người điền form trên website. Thay vì cứ vài phút lại hỏi "có gì mới không?", bạn đưa cho hệ thống nguồn một địa chỉ URL, và hệ thống nguồn gửi dữ liệu tới địa chỉ đó đúng lúc sự kiện xảy ra. Bài này giải thích webhook bằng ngôn ngữ đời thường, cách nhận và gửi webhook an toàn, kèm ví dụ thật từ website opcaios.org, nơi webhook của SePay và webhook gửi đi cho n8n đang chạy. Đầu tiên là khái niệm, tiếp theo là hai ví dụ, cuối cùng là chữ ký và các lỗi hay gặp.

Một lần gửi webhook: có sự kiện → gửi dữ liệu kèm chữ ký → bên nhận kiểm tra rồi trả 200. Sơ đồ: OPCAIOS.
Webhook là gì?
Webhook là một yêu cầu HTTP POST mà hệ thống nguồn gửi tới địa chỉ URL bạn đã đăng ký, mỗi khi một sự kiện xảy ra. Hãy so sánh hai cách chờ hàng giao tới:
- Gọi điện hỏi mỗi 10 phút "hàng tới chưa?": tốn công, và hàng tới giữa hai lần gọi thì bạn vẫn biết chậm.
- Để lại số điện thoại, shipper tới nơi thì gọi bạn: không tốn công chờ, biết ngay lập tức.
Cách thứ nhất là gọi API theo kiểu hỏi liên tục (polling). Cách thứ hai là webhook. Ví dụ, theo SePay (2026), webhook báo giao dịch tới website ngay khi khách chuyển khoản, thay vì website phải hỏi SePay mỗi 5 phút (một chu kỳ minh hoạ).
| Gọi API hỏi liên tục | Webhook | |
|---|---|---|
| Ai chủ động | Bạn hỏi | Hệ thống kia báo |
| Tốc độ biết tin | Chậm tới một chu kỳ hỏi | Gần như ngay lập tức |
| Tốn tài nguyên | Nhiều lần hỏi không có gì mới | Chỉ gửi khi có sự kiện |
| Bạn cần có | Khoá API | Một địa chỉ URL nhận được yêu cầu từ Internet |
Webhook được dùng ở đâu?
Webhook được dùng ở mọi nơi cần biết một sự kiện ngay lập tức, và có năm nhóm phổ biến. Đầu tiên là thanh toán: SePay, dịch vụ theo dõi chuyển khoản, hoặc cổng thanh toán báo "đơn ABC đã trả tiền". Tiếp theo là bán hàng: sàn thương mại điện tử và phần mềm bán hàng báo có đơn mới hay đơn huỷ. Thứ ba là form và khách hàng: website báo có người để lại thông tin, CRM báo có khách mới.
- Lập trình: GitHub báo có mã mới được đẩy lên để chạy kiểm thử và triển khai.
- Nhắn tin: Zalo OA, Messenger và Telegram gửi tin nhắn khách hàng tới hệ thống trả lời tự động.
Ví dụ, một cửa hàng nhỏ nhận 30 đơn mỗi ngày có thể nối webhook đơn hàng với Google Sheets qua n8n, để mỗi đơn mới tự thêm một dòng vào bảng tính mà không ai phải nhập tay. Ví dụ này là minh hoạ của OPCAIOS, không phải số liệu thật.
Một webhook trông như thế nào?
Một webhook là một yêu cầu HTTP POST bình thường, có thân là JSON, và nên chứa ba phần: mã sự kiện, loại sự kiện và dữ liệu. Ví dụ webhook opcaios.org gửi đi năm 2026 khi có người điền form trên website, theo định dạng mà n8n, Make và Zapier đều đọc được:
{
"id": "evt_3f9a1c2b7d8e4f60",
"event": "submission.created",
"createdAt": "2026-10-22T08:15:00.000Z",
"data": {
"form": "lien-he",
"fields": { "name": "Nguyễn Văn A", "phone": "09…", "message": "Tôi cần tư vấn" }
}
}
(Dữ liệu minh hoạ.)
Ba phần cần có trong mọi webhook: mã sự kiện (id) để chống xử lý trùng, loại sự kiện (event) để biết cần làm gì, và dữ liệu (data) chứa nội dung cụ thể. Bên nhận trong n8n, Make hay Zapier đọc 3 phần này rồi chuyển từng trường sang bước kế tiếp, thường trong vài giây.
Ví dụ thật 1: website nhận webhook thanh toán từ SePay ra sao?
Nhận webhook thanh toán là quy trình website tự mở khoá học khi SePay báo có tiền. Theo SePay (2026), dịch vụ này theo dõi giao dịch ngân hàng, và khi khách chuyển khoản mua khoá học trên opcaios.org, SePay gửi webhook tới website. Website làm bốn việc theo thứ tự:
- Kiểm tra khoá: yêu cầu phải mang đúng khoá bí mật đã cài trong SePay. Sai khoá thì từ chối, nếu không ai cũng có thể giả một yêu cầu "đã thanh toán".
- Ghi lại mã giao dịch trước khi xử lý: nếu cùng một giao dịch được gửi lại do mạng chập chờn, lần sau sẽ bị bỏ qua, không mở khoá học hai lần.
- Khớp nội dung chuyển khoản với mã đơn, mở khoá học cho khách và báo tin cho chủ site.
- Trả lời
200để SePay biết đã nhận, không gửi lại nữa.
Theo mã nguồn webhook của opcaios.org (kiểm tra ngày 22/10/2026), đây là khuôn mẫu cho mọi webhook nhận vào: xác thực, chống trùng, xử lý, trả lời nhanh.
Ví dụ thật 2: opcaios.org gửi webhook đi
Website cũng gửi webhook ra ngoài để nối với n8n, Make, Zapier hoặc hệ thống riêng. Chủ site vào trang quản trị, dán địa chỉ nhận và chọn các sự kiện muốn nghe:
| Sự kiện | Khi nào gửi |
|---|---|
submission.created |
Có bài gửi mới từ form (liên hệ, khoá học, bản tin, bình luận) |
order.created / order.paid |
Có đơn hàng shop mới / đơn đã thanh toán |
contact.created |
Khách mới vào CRM |
deal.won |
Cơ hội bán hàng chốt thành công |
payment.paid |
Link thanh toán hoặc đợt thu dự án đã trả tiền |
ticket.created |
Có yêu cầu hỗ trợ dự án mới |
Mỗi webhook có một khoá ký riêng (dạng whsec_…, chỉ hiện một lần khi tạo). Mỗi lần gửi, website kèm hai header:
X-OPCAIOS-Timestamp: 1792656900
X-OPCAIOS-Signature: sha256=<HMAC-SHA256(khoá, "timestamp.body")>
Có nút gửi thử (sự kiện ping) để kiểm tra địa chỉ nhận trước khi dùng thật, và trang quản trị ghi lại kết quả lần gửi gần nhất (mã phản hồi, lỗi nếu có). Bên nhận phải trả lời trong 10 giây.
Kiểm tra chữ ký webhook như thế nào?
Chữ ký webhook là mã giúp bên nhận chắc chắn yêu cầu đến từ đúng nơi và không bị sửa giữa đường. Cách làm chung gọi là HMAC: bên gửi và bên nhận cùng giữ một khoá bí mật, bên gửi dùng khoá đó "băm" nội dung thành chữ ký, bên nhận băm lại nội dung nhận được bằng cùng khoá rồi so sánh.
Theo mã nguồn của opcaios.org (2026), ví dụ kiểm tra chữ ký webhook bằng Node.js dưới đây từ chối mọi yêu cầu cũ hơn 5 phút:
import crypto from "node:crypto";
function verify(rawBody, timestamp, signatureHeader, secret) {
// Từ chối yêu cầu cũ hơn 5 phút, chống gửi lại yêu cầu bị đánh cắp
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
const expected = "sha256=" + crypto
.createHmac("sha256", secret)
.update(`${timestamp}.${rawBody}`)
.digest("hex");
const a = Buffer.from(expected);
const b = Buffer.from(signatureHeader || "");
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
Hai chi tiết hay bị bỏ sót:
- Dùng thân yêu cầu gốc (chuỗi nhận được), không phải JSON đã được đọc rồi chuyển lại thành chuỗi: chỉ lệch 1 dấu cách là chữ ký sai.
- So sánh bằng hàm an toàn (
timingSafeEqual), không dùng===, để kẻ tấn công không dò được chữ ký qua thời gian phản hồi.
Trong n8n, bạn làm việc này bằng node Crypto (HMAC) rồi node IF so sánh với header; hoặc dùng tuỳ chọn xác thực có sẵn của node Webhook nếu bên gửi dùng khoá tĩnh.
Nhận webhook không cần lập trình
- Trong n8n, Make hoặc Zapier, tạo quy trình bắt đầu bằng bước Webhook — công cụ sẽ cho bạn một địa chỉ URL.
- Dán địa chỉ đó vào phần cài đặt webhook của hệ thống gửi (SePay, website, CRM…), chọn sự kiện.
- Bấm gửi thử để công cụ nhận một mẫu dữ liệu, rồi ghép các trường vào bước tiếp theo: thêm dòng Google Sheets, gửi tin Telegram, tạo khách trong CRM.
- Bật quy trình. Từ giờ mỗi sự kiện sẽ tự chạy.
Những lỗi thường gặp khi dùng webhook là gì?
Lỗi thường gặp khi dùng webhook gồm năm loại, và lỗi nào cũng làm mất hoặc nhân đôi sự kiện. Ví dụ, một thanh toán bị xử lý hai lần là hậu quả của lỗi đầu tiên dưới đây, và theo OPCAIOS (2026) năm loại này đáng kiểm tra trước:
- Xử lý trùng: bên gửi có thể gửi lại cùng một sự kiện. Luôn lưu mã sự kiện đã xử lý và bỏ qua lần lặp, nhất là với thanh toán.
- Trả lời chậm: nhiều bên gửi chỉ chờ vài giây. Nhận xong thì trả
200ngay, việc nặng như gửi email hay gọi AI để chạy sau. - Không xác thực: địa chỉ webhook là công khai trên Internet. Không kiểm tra khoá hoặc chữ ký thì ai cũng gửi được dữ liệu giả.
- Địa chỉ không truy cập được: máy tính cá nhân hay mạng nội bộ không nhận được webhook từ Internet. Cần một máy chủ có địa chỉ công khai, hoặc dịch vụ trực tuyến như Make, Zapier, n8n cloud.
- Không có ai theo dõi: webhook lỗi thường âm thầm. Ghi log mỗi lần nhận, và đặt cảnh báo khi lâu không thấy sự kiện hoặc lỗi liên tiếp.
Đọc thêm: Thu tiền sản phẩm số bằng QR chuyển khoản (SePay) cho người làm một mình; Tự động hóa phễu hút khách hàng tiềm năng.
Câu hỏi thường gặp
Webhook có phải là API không?
Webhook là một dạng dùng API theo chiều ngược lại: thay vì bạn gọi tới hệ thống kia, hệ thống kia gọi tới bạn. Phần lớn quy trình tự động hoá dùng cả hai. Webhook giúp biết ngay khi có sự kiện, còn API giúp lấy thêm dữ liệu hoặc thực hiện hành động. Ví dụ, SePay gửi webhook báo có tiền, rồi website gọi API nội bộ để mở khoá học và gửi email xác nhận cho khách. Xem thêm bài API là gì nếu bạn chưa quen khái niệm này.
Webhook có mất phí không?
Bản thân webhook là một yêu cầu HTTP bình thường nên không mất phí. Chi phí, nếu có, đến từ dịch vụ nhận như gói của Make, Zapier hay máy chủ chạy n8n, hoặc từ dịch vụ gửi. Vì vậy, trước khi dùng, hãy xem bảng giá hiện hành của từng dịch vụ trên trang chính thức, vì mức giá và giới hạn số lần chạy mỗi tháng thay đổi theo thời gian. Bài này không nêu mức giá cụ thể vì OPCAIOS chưa kiểm chứng bảng giá mới nhất của các dịch vụ đó.
Nếu máy chủ của tôi tắt lúc webhook gửi tới thì sao?
Kết quả tuỳ bên gửi: có nơi gửi lại vài lần trong khoảng thời gian nhất định, có nơi chỉ gửi một lần. Đầu tiên, đọc tài liệu của bên gửi để biết chính sách gửi lại. Tiếp theo, với dữ liệu quan trọng như thanh toán, hãy thêm bước đối soát định kỳ bằng API để bắt các sự kiện bị lỡ. Cuối cùng, ghi log mỗi lần nhận để biết khoảng thời gian máy chủ tắt đã bỏ lỡ những gì.
Webhook có an toàn không?
Webhook an toàn khi bạn dùng HTTPS, kiểm tra khoá hoặc chữ ký ở mọi yêu cầu, từ chối yêu cầu quá cũ và chống xử lý trùng. Theo mã nguồn webhook của opcaios.org (kiểm tra ngày 22/10/2026), website kiểm tra khoá và chống xử lý trùng cho webhook SePay nhận vào, đồng thời ký HMAC-SHA256 kèm mốc thời gian cho webhook gửi đi.
Webhook là mảnh ghép thứ ba sau API và MCP: API để chủ động hỏi và ra lệnh, webhook để được báo ngay, MCP để trợ lý AI dùng cả hai bằng lời nói.
Nguồn: mã nguồn webhook của opcaios.org (gửi đi có ký HMAC, nhận từ SePay), kiểm tra ngày 22/10/2026.
Để lại bình luận
Email của bạn sẽ không hiển thị công khai. Bình luận sẽ hiển thị sau khi được duyệt.


