This task is one section of Eight software practices that keep business apps reliable, with 7 related tasks on one page.
1. Choose a stable key
Give each payment attempt a key that stays the same when you retry. A new random key on every click is a second charge waiting to happen.
2. Store the result
When the provider answers, save the key with the provider’s payment id and the status. A later retry should find that row first.
3. Retry on purpose
Simulate a lost response and send the same key again. The provider or your own check should return the original payment, not create another.
4. Treat a changed amount as new
If the amount or the customer changes, use a new key. Reusing the key for a different charge hides the difference.
5. Frequently asked questions
Is a unique order number enough?
Only if the same order cannot be charged twice on purpose, such as a deposit and a balance. Use a key per charge.
What if the provider has no idempotency key?
Store your own key and refuse to send a second create when the first result is unknown until you look it up.
Should the user click Pay again?
Let them retry the same attempt. Do not start a new charge while the first is unknown.
6. Related articles and next steps
Treat the checks below as the acceptance test for the change. Names of libraries can vary; the behavior to prove does not.