Webhook và những điều cần biết
Tình huống
Chắc mọi người ai đã từng tích hợp các chức năng thanh toán vào hệ thống của mình thì đều đã biết đến WEBHOOK rồi nhỉ, giả sử:
Trong quy trình xử lý đơn hàng của một website thương mại điện tử, khi khách hàng đặt hàng, dữ liệu sẽ được gửi từ API Gateway đến Order Service. Sau đó chuyển tiếp đến Payment Service để thực hiện thanh toán. Đây là lúc Payment Service Provider (PSP) (ví dụ: Stripe, PayPal, Adyen, GMO) bắt đầu tham gia.
Vậy có những cách nào để Stripe, giao tiếp được với website của mình để xác nhận thanh toán, gửi thông báo trạng thái giao dịch ?
1. Short polling:
Hiểu đơn giản là Payment Service (hệ thống của mình) sẽ hỏi liên tục STRIPE là giao dịch này sao rồi, xong chưa e ey, giờ sao... Payment service sẽ kiểm tra liên tục cho đến khi nhận được kết quả xác nhận.
Tuy nhiên, mọi người có thể thấy rằng, short polling tiêu tốn tài nguyên vì phải gửi request liên tục.
2. Long polling
Long polling là phiên bản kiên nhẫn hơn của short polling. Thay vì hỏi liên tục, server giữ yêu cầu mở kết nối và chỉ phản hồi khi có thông tin mới.
Long polling giúp giảm số lần request liên tục như short polling, nhưng vẫn có nhược điểm là server phải giữ kết nối mở, dẫn đến tốn tài nguyên, đặc biệt khi có nhiều client kết nối cùng lúc.
3. Webhooks
Thay vì yêu cầu Stripe liên tục để hỏi kết quả như short polling hay long polling, thì chúng ta sẽ cung cấp cho Stripe 1 URL và nói nó " gửi kết quả qua cái URL này cho tôi khi có kết quả nhé !!!"
Khi thanh toán hoàn tất, Stripe sẽ tự động gửi dữ liệu về cái URL này cho hệ thống bên mình để xử lý kết quả thanh toán.
Yeah, giờ thì không còn lãng phí tài nguyên nữa rồi.
4. Webhooks kết hợp với polling (Failover):
Trong 1 hệ thống để đảm bảo an toàn, thì làm gì cũng cần và nên có cơ chế Failover (dự phòng). Trong trường hợp server webhook không phản hồi, sử dụng polling định kỳ để đảm bảo không bỏ lỡ các cập nhật quan trọng.
5. Một số kinh nghiệm khi sử dụng webhook:
Tính Idempotency:
Tự đặt câu hỏi: Khi webhook được gọi nhiều lần cho cùng 1 giao dịch thì có ảnh hưởng gì đến dữ liệu của hệ thống không ?
Đây được gọi là tính Idempotency, Webhook có thể được gửi nhiều lần do lỗi mạng, retry từ phía sender hoặc mất kết nối. Do đó, cần đảm bảo rằng:
- Chỉ xử lý một lần duy nhất hoặc dù được gọi nhiều lần thì kết quả vẫn không thay đổi.
- Sử dụng ID/token để phân biệt từng request.
Đây là kỹ thuật khá quan trọng, thông thường các Payment Gateway thường dùng để tránh việc Duplicate Payment
Mọi người có thể tham khảo bài viết này, mình thấy khá hay 💯
BÀI HỌC KINH NGHIỆM:
Mình cũng đã từng làm việc với GMO PAYMENT GATEWAY VÀ PAIDY, cũng sử dụng webhook nhận kết quả giao dịch để xử lý, đã gặp trường hợp webhook được gọi duplicate nhiều lần và bùm... Không may là bên mình đặt logic gửi mail cho người dùng ở trong webhook nên xảy ra hiện tưởng gửi mail duplicate nhiều lần (sad) và còn có một số issue khác về lưu lượng lớn nên các bạn chú ý xử lý logic cho hợp lý ở trong webhook này nhé.
Bảo mật
- Chỉ chấp nhận các request có token xác thực hoặc chữ ký bí mật (HMAC) để đảm bảo request đến từ nguồn hợp lệ.
- Sử dụng HTTPS để mã hóa dữ liệu truyền tải, tránh bị tấn công trung gian (MITM).
- Chỉ cho phép IP đến từ Payment Gateway access vào WEBHOOK URL
Xử lý lưu lượng lớn:
Nếu trang web của bạn có lượng truy cập cao, hãy chuẩn bị hạ tầng để đối phó với đợt tăng đột biến lưu lượng webhook bằng cách:
- Sử dụng Queue để tách biệt việc nhận và xử lý sự kiện
- Ghi lại tất cả request webhook để dễ dàng debug khi có lỗi xảy ra.
All rights reserved