keepcalculator

06 Numbers and Powers

Idempotency Keys: How They Stop Duplicate Payments

Card No. 06·48847 · Updated · Standard formula, shown below

Idempotency keys are a simple but powerful tool that payment APIs use to make sure a payment is processed only once, even if a request is retried due to network issues or timeouts. When you send a payment request with a unique key, the server remembers that key and the response it gave, so if you send the same request again, it returns the saved response instead of charging the customer again. This guide explains how idempotency keys work, how to implement them correctly, and what to do when things go wrong.

What You’ll Need

  • A basic understanding of HTTP requests and responses.
  • Access to a payment API that supports idempotency keys (most major providers do).
  • A way to generate unique identifiers (e.g., UUIDs) in your application.
  • A strategy for storing idempotency keys and their responses (e.g., a database table or cache).

Step-by-Step

  1. Generate a unique idempotency key for each payment attempt. This key should be a random string, typically a UUID (version 4). Do not reuse a key for different payments. If you need to retry the same payment, use the same key; if it’s a new payment, generate a new key.
  2. Include the key in your payment request. Most APIs expect it in a header named Idempotency-Key or as a field in the request body. Check your provider’s documentation for the exact location. For example, Stripe uses the Idempotency-Key header, while PayPal uses a PayPal-Request-Id header.
  3. Send the request to the payment API. When the API receives a request with an idempotency key it hasn’t seen before, it processes the payment and stores the key along with the response (including the HTTP status code and body).
  4. Handle the response. If the request succeeds, store the response in your own records. If it fails (e.g., network timeout), you can safely retry the same request with the same idempotency key.
  5. On retry, send the same key. When you retry, the API checks if the key already exists. If it does, it returns the stored response from the first attempt, without processing the payment again. This is the core of idempotency.
  6. If the key is new, process normally. If the key doesn’t exist (e.g., the first request never reached the server), the API processes the payment as a new one.
  7. Store the key and response in your own system too. This helps you reconcile and debug. Keep the key with the payment record so you can trace retries.

Common Mistakes

  • Reusing the same key for different payment attempts. This can cause the second payment to be blocked or return the wrong response. Always generate a new key for a new logical operation.
  • Not including the key in retries. If you retry without the key, the API treats it as a new request and may charge the customer twice.
  • Using a predictable key (e.g., order ID). If an attacker can guess the key, they might be able to replay a request. Use a cryptographically random UUID.
  • Ignoring the API’s idempotency window. Some APIs only remember keys for a limited time (e.g., 24 hours). After that, a retry with the same key may be treated as new. Check your provider’s limits.
  • Not handling the case where the key exists but the response was a failure. Some APIs store error responses too. If the first attempt failed with a validation error, retrying with the same key will return the same error, not a new attempt. You may need to generate a new key if the error is fixable.

Tips

  • Generate keys on the client side (your server) before sending the request, so you have them available for retries.
  • Use a library that handles idempotency automatically if your payment SDK supports it. Many SDKs let you pass an idempotency key and automatically retry on network errors.
  • Log the idempotency key with every payment attempt. This makes debugging much easier when something goes wrong.
  • Consider using a dedicated column in your database for idempotency keys with a unique constraint, so your own system also prevents duplicate processing.
  • For high-throughput systems, use a fast key-value store (like Redis) to check keys quickly, but ensure it’s persistent enough for your needs.

Troubleshooting

Problem: The API returns an error saying the idempotency key was already used.

This means the key already exists in the API’s system. If you intended to retry, you should have received the original response. If you didn’t, check if the API stores error responses. If the original request failed with a client error (e.g., invalid card), you need to generate a new key after fixing the issue. If it was a server error, you can retry with the same key.

Problem: The customer was charged twice despite using idempotency keys.

This can happen if the idempotency key wasn’t sent on one of the requests, or if the key was different between retries. Check your logs to see if both requests had the same key. Also, ensure that your retry logic actually reuses the key – some developers mistakenly generate a new key on each attempt.

Problem: The idempotency key works for a while, then stops.

This is likely due to the API’s idempotency window expiring. If the key is older than the allowed time, the API may treat it as new. In that case, you need to accept that the payment might be processed again, and you should have a mechanism to detect and refund duplicates.

Problem: The API returns a 409 Conflict response.

This is a common HTTP status for idempotency conflicts. It means the key exists but with a different request payload. This happens when you reuse a key for a different request. Generate a new key for the new request, or ensure you send the exact same payload.

Frequently Asked Questions

What is an idempotency key exactly?

It’s a unique string that identifies a specific operation. When you send it with a request, the server can recognize if you’ve sent the same request before and return the same response instead of performing the action again.

How long do idempotency keys last?

It depends on the provider. Some keep them for 24 hours, others for a week. Check your payment API’s documentation for the exact duration. After that, the key is forgotten, and a retry might be treated as a new request.

Can I use the same idempotency key for multiple payments?

No. Each payment (or each logical operation) must have a unique key. Reusing a key for a different payment will either cause an error or return the original response, which is wrong.

What happens if I lose the idempotency key?

If you lose the key, you can’t safely retry the request, because you don’t know if the original went through. You’ll need to check your payment records to see if the charge occurred, and if not, you can create a new payment attempt with a new key.

Do idempotency keys prevent all duplicate payments?

They prevent duplicates caused by retries of the same request. They don’t prevent duplicates from user error (e.g., clicking ‘Pay’ twice) unless your application also uses the key to deduplicate at your end. You should still have a unique constraint on your side.

Is it safe to expose idempotency keys in logs?

Yes, they are not secret. They are just identifiers. However, be careful not to log full payment details like card numbers. Idempotency keys themselves are safe to log.

Related

Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.

More cards in this drawer

The whole Numbers and Powers drawer →