Gửi lại webhook và xử lý lỗi
Video hướng dẫn
Xem transcript video (9 phần)
Tìm lỗi không đoán mò
Webhook lỗi đúng lúc khách chuyển tiền thì đơn có thể nằm chờ, nhưng đoán mò và bắt khách trả lại là cách xử lý nguy hiểm. Trong video này, mình sẽ đọc Lịch sử gửi, giải nghĩa từng nhóm lỗi, sửa timeout và gửi lại đúng giao dịch. Bạn cũng sẽ biết chỉ số nào cần theo dõi để phát hiện endpoint xuống sức trước giờ cao điểm.
Điều kiện thành công
Một lần gửi chỉ được tính thành công khi máy chủ trả HTTP hai trăm, hai trăm lẻ một hoặc hai trăm lẻ hai trong tối đa mười giây. Body phản hồi không bắt buộc và hệ thống không đọc nội dung. Mã hai trăm lẻ bốn không nằm trong danh sách. Redirect ba trăm lẻ một hoặc ba trăm lẻ hai cũng tính là thất bại vì MONA Pay không đi theo đường chuyển hướng.
Đọc từng dòng log
Vào Webhooks, mở tab Lịch sử gửi. Mỗi dòng có thời điểm, mã HTTP, duration_ms là số mili giây chờ phản hồi, error_label là nhãn kết quả, payload đã gửi và phần đầu body phản hồi. API tương ứng là GET /api/v1/webhook-logs. Hãy tìm theo thời điểm và transaction_code, rồi so payload ở đây với raw body đã lưu trên máy chủ của bạn.
Nhóm lỗi HTTP
Nhóm lỗi HTTP cho biết máy chủ đã trả lời. HTTP_3XX thường do URL thiếu HTTPS, thừa dấu gạch cuối hoặc chuyển hướng tên miền. HTTP_4XX có thể là sai Secret, tường lửa chặn, sai đường dẫn, route không nhận POST hoặc endpoint đòi trường không có. HTTP_5XX nghĩa là code, bộ nhớ hay kết nối cơ sở dữ liệu lỗi. Mở log ứng dụng đúng thời điểm ghi trong dòng gửi.
Lỗi kết nối và timeout
Nhóm lỗi kết nối cần kiểm tra hạ tầng. TIMEOUT là quá mười giây, thường vì endpoint xử lý đơn rồi mới phản hồi. SSL liên quan chứng chỉ hết hạn, tự ký, sai tên miền hoặc thiếu chuỗi trung gian. DNS là tên miền không phân giải được. CONNECTION thường do cổng bốn trăm bốn mươi ba bị chặn hoặc máy chủ tắt. Tường lửa cần cho phép IP 103.168.55.14.
Gửi lại đúng giao dịch
Sửa xong, tại dòng thất bại bấm Gửi lại. Hệ thống gửi nguyên payload đến nguyên URL ngay lập tức và tạo thêm một dòng log. transaction_code không thay đổi, vì vậy endpoint phải chống trùng bằng khóa UNIQUE. Bạn cũng có thể gọi endpoint retry với transaction_id, body có target_type là WEBHOOK; nếu cần chỉ một cấu hình thì truyền thêm target_id.
Endpoint chịu tải tốt
Để tránh timeout, trình tự phía server là kiểm chữ ký, trả hai trăm, rồi mới cập nhật đơn, gửi email hoặc gọi API khác bằng hàng đợi. Lưu raw body và header ít nhất ba mươi ngày để đối chiếu. Gửi lại tự động tối đa bảy lần đang được triển khai và chưa chạy trên production, nên hiện bạn vẫn gửi lại chủ động và chạy đối soát định kỳ để không sót tiền.
Theo dõi tỷ lệ và P95
Theo dõi thêm tab thống kê hoặc GET /api/v1/webhook-logs/stats. Tỷ lệ thành công dưới chín mươi chín phần trăm trong ngày là dấu hiệu cần xem phân bố lỗi. P chín mươi lăm trên ba nghìn mili giây cho thấy endpoint làm việc nặng trước phản hồi. Nếu HTTP_4XX tăng ngay sau khi triển khai code, kiểm tra Secret và đường dẫn. Log OK nhưng đơn không đổi thì lỗi nằm ở bước xử lý sau phản hồi.
Mở docs và kiểm log
Bảng chín nhãn lỗi, endpoint gửi lại và lệnh đọc thống kê nằm tại monapay.vn/docs/webhooks/gui-lai-va-xu-ly-loi. Bạn đăng ký tại my.monapay.vn, mở Lịch sử gửi và thử lại một giao dịch cũ sau khi đã sửa server. Nếu chưa xác định được nhãn lỗi, gọi tổng đài một chín không không, sáu ba sáu, sáu bốn tám để đội MONA hỗ trợ.
MONA Pay tính một lần gửi webhook là thành công khi máy chủ của bạn trả HTTP 200, 201 hoặc 202 trong vòng 10 giây. Mọi lần gửi đều ghi log với mã HTTP, thời gian phản hồi và một nhãn lỗi. Lần gửi thất bại được gửi lại thủ công từ dashboard; gửi lại tự động theo lịch (tối đa 7 lần) đang được triển khai.
Thế nào là thành công
| Điều kiện | Giá trị |
|---|---|
| Mã HTTP chấp nhận | 200, 201, 202 |
| Thời gian chờ tối đa | 10 giây tính từ lúc MONA Pay bắt đầu gửi |
| Body phản hồi | Không bắt buộc, MONA Pay không đọc nội dung |
| Redirect | Không đi theo. 301/302 tính là thất bại |
Điều này nghĩa là endpoint của bạn chỉ cần trả 200 OK với body rỗng. Đừng trả 204 (không nằm trong danh sách) và đừng để URL webhook có redirect.
Log từng lần gửi
Mỗi lần MONA Pay gửi, kể cả gửi thử và gửi lại, đều có một dòng trong dashboard mục Webhooks, tab Lịch sử gửi. Cùng dữ liệu có ở API GET /api/v1/webhook-logs.
| Trường log | Ý nghĩa |
|---|---|
| Thời điểm gửi | Lúc MONA Pay bắt đầu request |
| Mã HTTP | Mã máy chủ của bạn trả, trống nếu không kết nối được |
duration_ms |
Thời gian từ lúc gửi tới lúc nhận phản hồi, mili giây |
error_label |
Nhãn phân loại kết quả, xem bảng dưới |
| Payload | Gói đã gửi, để bạn đối chiếu |
| Phản hồi | Vài trăm ký tự đầu body máy chủ trả về, tiện tìm lỗi |
Các nhãn lỗi và cách sửa
error_label |
Nghĩa | Nguyên nhân hay gặp | Cách sửa |
|---|---|---|---|
OK |
Thành công | Máy chủ trả 200/201/202 trong 10 giây | Không cần làm gì |
HTTP_3XX |
Máy chủ trả redirect | URL thiếu https, thiếu hoặc thừa dấu / cuối, chuyển hướng www |
Khai URL đích cuối cùng, không qua redirect |
HTTP_4XX |
Máy chủ từ chối | 401/403 sai secret hoặc tường lửa ứng dụng chặn; 404 sai đường dẫn; 405 route không nhận POST; 422 endpoint đòi trường không có | Kiểm secret, đường dẫn, method. Với WAF (Cloudflare, ModSecurity) cho phép IP 103.168.55.14 |
HTTP_5XX |
Máy chủ lỗi | Code ném exception, hết bộ nhớ, database không kết nối được | Xem log máy chủ của bạn đúng thời điểm duration_ms |
TIMEOUT |
Quá 10 giây không phản hồi | Endpoint xử lý xong đơn mới trả lời, hoặc máy chủ quá tải | Trả 200 trước, xử lý sau |
SSL |
Bắt tay TLS thất bại | Chứng chỉ hết hạn, tự ký, sai tên miền, thiếu chuỗi trung gian | Kiểm bằng openssl s_client -connect ten-mien:443, cài lại chứng chỉ đầy đủ |
DNS |
Không phân giải được tên miền | Gõ sai tên miền, tên miền hết hạn, bản ghi DNS chưa lan | Kiểm dig ten-mien từ máy ngoài |
CONNECTION |
Không mở được kết nối | Tường lửa chặn cổng 443, máy chủ tắt, cổng sai | Mở cổng 443 cho IP 103.168.55.14, kiểm máy chủ đang chạy |
ERROR |
Lỗi khác | Trường hợp không xếp được vào các nhãn trên | Xem phản hồi trong log, gọi 1900 636 648 nếu không rõ |
Gửi lại thủ công
Trong Lịch sử gửi, mỗi dòng thất bại có nút Gửi lại. Bấm là MONA Pay gửi lại đúng payload đó tới đúng URL đó, ngay lập tức, và ghi thêm một dòng log mới. transaction_code không đổi nên endpoint của bạn phân biệt được đây là gói cũ. Bạn cũng gửi lại bằng API: POST /api/v1/acb/virtual-account/transactions/{transaction_id}/retry với body {"target_type": "WEBHOOK"} (hoặc "TELEGRAM", kèm target_id là id cấu hình muốn gửi lại), header Authorization: Bearer + X-Client-Secret như mọi lệnh ghi. Xem thêm Cấu hình webhook qua API.
Gửi lại có 2 tình huống dùng:
- Sửa xong lỗi ở máy chủ. Ví dụ endpoint bị 500 vì thiếu bảng, tạo bảng xong bấm gửi lại từng dòng thất bại.
- Kiểm tra sau khi đổi code. Gửi lại một giao dịch cũ để xem code mới xử lý đúng không, thay vì phải chuyển tiền thật.
Gửi lại tự động (đang triển khai)
Cấu hình webhook có trường max_retries mặc định 7, dành cho cơ chế gửi lại tự động theo lịch giãn dần khi máy chủ của bạn trả lỗi. Cơ chế này đang được triển khai và chưa chạy trên production; hiện tại mọi lần gửi lại đều do bạn bấm. Khi lên, đội MONA công bố lịch cụ thể tại trang này. Trong lúc chờ, bạn nên chạy đối soát định kỳ để không sót giao dịch nào lúc máy chủ gặp sự cố.
Thống kê tỷ lệ thành công và P95
Dashboard mục Webhooks có tab thống kê, dữ liệu lấy từ GET /api/v1/webhook-logs/stats: tổng số lần gửi, tỷ lệ thành công, thời gian phản hồi trung bình và P95 (95% lần gửi nhanh hơn mốc này), phân bố theo nhãn lỗi. Vài mốc tham khảo:
- Tỷ lệ thành công dưới 99% trong ngày: có gì đó không ổn ở máy chủ, xem phân bố nhãn lỗi.
- P95 trên 3.000 ms: endpoint đang làm việc nặng trước khi trả lời, sớm muộn sẽ dính
TIMEOUTkhi tải tăng. - Nhãn
HTTP_4XXtăng đột ngột sau khi deploy: thường là đổi secret hoặc đổi đường dẫn mà quên cập nhật cấu hình.
Xử lý phía máy chủ của bạn
Ba nguyên tắc để endpoint không bao giờ lỗi vì tải:
- Trả lời trước, làm việc sau. Kiểm chữ ký xong là trả 200 ngay. Việc cập nhật đơn, gửi email, gọi API bên thứ ba đẩy vào hàng đợi (Redis, database, cron). Mẫu PHP dùng
fastcgi_finish_request(), mẫu Node gọires.send()trước rồi xử lý tiếp, xem Tích hợp webhook. - Chống trùng bằng
transaction_code. Gửi lại tay, hai cấu hình cùng URL, hoặc gửi lại tự động sau này đều sinh gói trùng. UNIQUE trêntransaction_codelà đủ. - Ghi log ở phía bạn. Lưu raw body và header của mọi gói nhận được, ít nhất 30 ngày. Khi cần đối chiếu với log MONA Pay, hai bên cùng nhìn một
transaction_code.
Lỗi thường gặp
Log báo OK nhưng đơn không đổi trạng thái. Endpoint trả 200 rồi phần xử lý sau đó lỗi. Xem log ứng dụng của bạn, vì MONA Pay chỉ biết mã HTTP.
Bấm gửi lại vẫn ra cùng nhãn lỗi. Lỗi chưa được sửa ở máy chủ. Thử gói giả lập bằng cURL ở trang Bảo mật webhook từ máy khác để tái hiện.
TIMEOUT chỉ xảy ra vào giờ cao điểm. Máy chủ quá tải, xử lý đồng bộ. Chuyển sang trả 200 trước.
Tất cả webhook ra CONNECTION từ một thời điểm. Thường do đổi tường lửa hoặc đổi máy chủ. Mở lại cổng 443 cho IP 103.168.55.14.