Hướng dẫn

Webhook Là Gì? Cách Các App Thông Báo Cho Nhau

Webhook là một thông điệp tự động mà một dịch vụ gửi đến app của bạn ngay khi có sự việc xảy ra. Khi thanh toán của khách hàng thành công, Stripe gửi một webhook đến một địa chỉ trong app của bạn với nội dung “thanh toán thành công, đây là chi tiết”, và app của bạn phản ứng — đánh dấu đơn hàng đã thanh toán, gửi biên nhận, mở khóa tài khoản. Nói ngắn gọn: API là khi app của bạn hỏi một dịch vụ khác một câu hỏi; webhook là khi dịch vụ khác gọi đến app của bạn để báo cho nó điều gì đó.

Vì sao điều này quan trọng khi bạn xây dựng bằng AI

Ngay khi app của bạn nhận thanh toán, nhận biểu mẫu từ một công cụ khác, hoặc kết nối với các dịch vụ như GitHub, Shopify hay lịch, bạn sẽ gặp webhook. Đây thường là cách đúng để biết điều gì đó đã xảy ra — nhưng cũng là nơi các app xây bằng AI hay sai một cách tinh vi:

  • Endpoint chấp nhận mọi yêu cầu, nên bất kỳ ai cũng có thể giả một sự kiện “thanh toán thành công”.
  • App cấp quyền truy cập ngay trên trang chuyển hướng sau thanh toán thay vì dựa vào webhook, nên người đóng tab sớm sẽ không nhận được thứ họ đã trả tiền, còn người tìm được URL thành công thì nhận được miễn phí.
  • Cùng một sự kiện đến hai lần khiến khách hàng nhận hai đơn hàng hoặc hai email.

Hiểu cách webhook hoạt động giúp bạn yêu cầu các biện pháp bảo vệ ngay từ đầu.

Một ví dụ đời thường: tin nhắn báo giao hàng

Bạn có thể biết bưu kiện đã đến bằng hai cách. Bạn có thể cứ mười phút lại đi ra cửa trước để kiểm tra (đó là polling — app của bạn liên tục gọi một API để hỏi “có gì mới không?”). Hoặc người giao hàng có thể nhắn tin cho bạn khi đã giao xong (đó là webhook).

Tin nhắn rõ ràng là tốt hơn — miễn là bạn có thể tin nó. Nếu bất kỳ ai cũng có thể gửi cho bạn tin “đã giao hàng”, bạn sẽ muốn có cách nào đó để biết nó thực sự đến từ người giao hàng. Và nếu điện thoại bạn tắt khi tin nhắn đến, bạn sẽ muốn người giao hàng thử lại sau. Hai mối quan tâm này — xác minh và thử lại — chính là phần lớn lý do khiến webhook trở nên phức tạp.

Webhook hoạt động như thế nào, từng bước

  1. Bạn tạo một endpoint trong backend của app: một URL như https://yourapp.com/webhooks/stripe nhận các yêu cầu POST.
  2. Bạn đăng ký URL đó với nhà cung cấp và chọn những sự kiện bạn muốn (ví dụ “checkout hoàn tất” và “hủy đăng ký”).
  3. Nhà cung cấp cấp cho bạn một bí mật ký. Bạn lưu nó như một secret trên máy chủ — xem biến môi trường và secret.
  4. Một sự kiện xảy ra. Nhà cung cấp gửi một yêu cầu HTTP đến URL của bạn với nội dung JSON mô tả sự kiện, cùng một header chữ ký.
  5. App của bạn xác minh chữ ký, ghi lại ID sự kiện, nhanh chóng trả lời mã thành công (200), rồi mới thực hiện công việc.
  6. Nếu app của bạn không trả lời thành công, nhiều nhà cung cấp sẽ thử lại sau.

Chữ ký

Chữ ký chứng minh yêu cầu đến từ nhà cung cấp và không bị thay đổi. Ví dụ, Stripe tính một HMAC (một loại dấu vân tay có khóa) bằng SHA-256 trên nội dung yêu cầu và một dấu thời gian, dùng bí mật ký, và gửi nó trong header Stripe-Signature. App của bạn thực hiện đúng phép tính đó với bản sao bí mật của mình; nếu kết quả khớp, yêu cầu là chính hãng. Vì dấu thời gian cũng được ký, bạn có thể từ chối các yêu cầu cũ mà ai đó đã ghi lại và phát lại sau này — theo tài liệu của Stripe tính đến tháng 9/2026, thư viện của Stripe mặc định cho phép sai lệch năm phút.

Một chi tiết thực tế: chữ ký được tính trên nội dung yêu cầu thô. Nếu framework của bạn phân tích và định dạng lại JSON trước khi bạn xác minh, phép kiểm tra sẽ thất bại. Đây là một lỗi rất phổ biến.

Thử lại, trùng lặp và thứ tự

Các nhà cung cấp khác nhau, nên hãy kiểm tra tài liệu của từng bên. Tính đến tháng 9/2026:

Hành viStripeGitHub
Tự động thử lạiCó, tối đa ba ngày với khoảng cách tăng dần ở chế độ liveKhông; bạn gửi lại các lần giao thất bại bằng tay hoặc bằng script
Thời gian phản hồiTrả lời mã 2xx nhanh chóng, trước mọi công việc chậmLần giao mất hơn 10 giây để trả lời được tính là thất bại

Tài liệu của Stripe cũng cho biết các sự kiện không được đảm bảo đến theo đúng thứ tự xảy ra, và cùng một sự kiện đôi khi có thể đến hơn một lần, nên khuyến nghị theo dõi ID sự kiện.

Bài học chung đúng với mọi nhà cung cấp: sự kiện có thể đến muộn, nhiều hơn một lần và sai thứ tự. Trình xử lý của bạn nên là idempotent — xử lý cùng một sự kiện hai lần cho kết quả giống như xử lý một lần.

Ví dụ minh họa: mở khóa một khóa học trả phí

Bạn bán một khóa học trực tuyến. Một học viên nhấn Mua, thanh toán trên trang checkout được Stripe lưu trữ, rồi được đưa trở lại website của bạn.

Cách mong manh: trang “cảm ơn” mở khóa khóa học. Nếu học viên đóng trình duyệt trong lúc chuyển hướng, họ đã trả tiền nhưng không có quyền truy cập. Nếu ai đó đoán được URL cảm ơn, họ sẽ có quyền truy cập mà không cần trả tiền.

Cách dùng webhook:

  1. Khi Stripe xác nhận thanh toán, nó gửi sự kiện checkout.session.completed đến /webhooks/stripe.
  2. Backend của bạn xác minh chữ ký bằng bí mật ký. Nếu thất bại, nó trả về 400 và không làm gì thêm.
  3. Nó kiểm tra xem ID sự kiện đó đã được xử lý chưa. Nếu rồi, nó trả về 200 và dừng lại.
  4. Nó lưu ID sự kiện, trả về 200, rồi cấp quyền truy cập cho học viên và gửi email chào mừng.
  5. Trang cảm ơn chỉ hiển thị “Đã nhận thanh toán — khóa học của bạn sẽ xuất hiện trong giây lát” và kiểm tra trạng thái quyền truy cập của học viên.

Về sau, nếu một gói đăng ký bị hủy hoặc thẻ bị từ chối, các sự kiện webhook khác sẽ báo cho app của bạn gỡ bỏ hoặc tạm dừng quyền truy cập. Đây là cách các sản phẩm đăng ký giữ đồng bộ với thanh toán — xem SaaS là gì và cách thêm thanh toán vào app.

Thuật ngữ quan trọng

  • Endpoint: URL trong app của bạn nhận webhook.
  • Event / payload (sự kiện / nội dung): điều đã xảy ra, và dữ liệu mô tả nó (thường là JSON).
  • Signing secret (bí mật ký): bí mật chia sẻ dùng để xác minh chữ ký.
  • Idempotent: an toàn khi chạy nhiều lần với cùng một kết quả.
  • Polling: liên tục hỏi một API xem có thay đổi gì thay vì chờ webhook.
  • Tunnel: công cụ cấp cho máy tính xách tay một URL công khai tạm thời để webhook có thể đến được trong lúc phát triển.

Các lỗi thường gặp và những hiểu lầm

  • Không xác minh chữ ký. URL endpoint không phải là bí mật. Việc xác minh mới làm cho yêu cầu đáng tin.
  • Làm việc chậm trước khi trả lời. Gửi email hoặc tạo PDF trước khi phản hồi có thể gây hết thời gian chờ, dẫn đến thử lại, rồi gây ra trùng lặp.
  • Giả định đúng một lần, đúng thứ tự. Hãy ghi lại ID sự kiện và đừng dựa vào thứ tự đến.
  • Dùng URL xem trước. Webhook cần một địa chỉ công khai ổn định. Bản xem trước riêng tư và localhost không thể truy cập từ internet; hãy dùng URL đã xuất bản của bạn (hoặc một tunnel khi đang kiểm thử).
  • Trộn lẫn khóa test và khóa live. Các nhà cung cấp thường cấp bí mật ký khác nhau cho chế độ test và live. Hãy lưu cả hai và dùng đúng cái.
  • Tin tuyệt đối vào nội dung cho các quyết định quan trọng. Với các hành động có rủi ro cao, nên lấy trạng thái mới nhất từ API của nhà cung cấp sau khi nhận sự kiện.

Nên nhờ AI builder của bạn làm gì

Thêm một endpoint POST /webhooks/stripe trên máy chủ. Xác minh chữ ký Stripe bằng nội dung yêu cầu thô và bí mật STRIPE_WEBHOOK_SECRET. Từ chối chữ ký không hợp lệ với mã 400. Lưu ID từng sự kiện và bỏ qua các sự kiện đã xử lý. Trả lời 200 nhanh chóng, sau đó xử lý checkout.session.completed bằng cách đánh dấu đơn hàng đã thanh toán và gửi biên nhận. Ghi log loại sự kiện. Đừng cấp quyền truy cập từ trang thành công của checkout.

Sau đó kiểm tra: gửi một sự kiện test từ bảng điều khiển của nhà cung cấp, gửi lại chính sự kiện đó, và gửi một yêu cầu với chữ ký sai. Chỉ lần đầu tiên mới được thay đổi dữ liệu.

Webhook trên Mythex

Mythex không chạy một dịch vụ webhook riêng; bạn nhờ agent thêm một endpoint webhook vào backend của chính app, rồi trỏ nhà cung cấp đến URL đã xuất bản của bạn, vì webhook cần một địa chỉ công khai. Bí mật ký được đưa vào secret của dự án, và nếu bạn đổi nó trên app đang hoạt động, bạn phải xuất bản lại. Công thức trong tài liệu về xử lý webhook có một prompt mẫu, và mẫu cửa hàng là điểm khởi đầu tốt cho các app nhận thanh toán.

Câu hỏi thường gặp

Webhook là gì, nói đơn giản?

Webhook là một thông điệp tự động mà một dịch vụ gửi đến một địa chỉ web trong app của bạn khi có sự kiện xảy ra, chẳng hạn một khoản thanh toán thành công hoặc một biểu mẫu được gửi đi. Thay vì app của bạn liên tục hỏi xem có thay đổi gì không, dịch vụ kia sẽ tự báo cho nó.

Sự khác nhau giữa webhook và API là gì?

Với một lệnh gọi API, app của bạn hỏi dịch vụ khác về một thứ gì đó và nhận câu trả lời. Với webhook, dịch vụ khác gọi đến app của bạn khi một sự kiện xảy ra. Nhiều tích hợp dùng cả hai: webhook để biết về sự kiện, lệnh gọi API để lấy chi tiết hoặc thực hiện hành động.

Webhook có an toàn không?

Có thể an toàn, nếu bạn xác minh chúng. Các nhà cung cấp được thiết kế tốt ký từng webhook bằng một bí mật chỉ chia sẻ với bạn, và app của bạn nên từ chối mọi yêu cầu có chữ ký không khớp. Nếu không có bước kiểm tra này, bất kỳ ai tìm được URL đều có thể gửi sự kiện giả.

Điều gì xảy ra nếu app của tôi ngừng hoạt động khi webhook được gửi?

Tùy vào nhà cung cấp. Ví dụ, Stripe thử gửi lại các lần giao thất bại trong tối đa ba ngày ở chế độ live, trong khi GitHub không tự động thử lại và yêu cầu bạn gửi lại. Hãy kiểm tra tài liệu của từng nhà cung cấp, và thiết kế trình xử lý của bạn để đối phó với sự kiện đến muộn hoặc bị lặp lại.

Mythex · Pricing · Xây dựng mọi thứ với AI · Mẫu website và ứng dụng · So sánh Mythex · Thuật ngữ xây dựng ứng dụng bằng AI · Công cụ miễn phí để xây dựng ứng dụng bằng AI · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو 简体中文 繁體中文(香港) 繁體中文(台灣)