Summary
Double-click submit, retry, or duplicate events must not double-charge or duplicate records. Disable button during flight; dedupe by idempotency key server-side. UI debounce ≠ server idempotency — both needed. Especially payment, delete, toggle subscription.
Code example
async function handleSubmit(e) {
e.preventDefault();
if (submitting) return;
setSubmitting(true);
try {
await api.createOrder(formData);
} finally {
setSubmitting(false);
}
}
Key points
- Double-click submit, retry, or duplicate events must not double-charge or duplicate records.
- Disable button during flight; dedupe by idempotency key server-side.
- UI debounce ≠ server idempotency — both needed.
- Especially payment, delete, toggle subscription.