Vấn đề: POST không idempotent — nếu client gửi tạo đơn/thanh toán rồi mạng timeout, nó không biết server đã nhận chưa. Retry khi chưa biết kết quả → tạo trùng (đơn hàng lặp, trừ tiền hai lần).
Idempotency key là một chuỗi duy nhất (thường UUID) client sinh cho mỗi thao tác và gửi kèm (vd header Idempotency-Key). Server:
1. Lần đầu thấy key → xử lý và lưu kết quả gắn với key.
2. Lần sau thấy cùng key → không làm lại, trả kết quả đã lưu.
Nhờ đó retry an toàn dù request thực chất là POST. Cần lưu key + kết quả trong một cửa sổ thời gian (TTL) và xử lý race (khóa/INSERT unique). Đây là cơ chế Stripe/PayPal dùng cho API thanh toán.