← All notes

Idempotency in payment APIs

Published2 min readpaymentsapisreliability

A client sends a payment request and the connection drops before the response arrives. It cannot know whether the charge happened. If it retries, a naive API charges twice. Idempotency keys exist to make that retry safe.

The idea

The client generates a unique key per intended payment and sends it with the request. The server stores the key with the result of the first attempt. A second request with the same key returns the stored result instead of doing the work again.

What makes it hard

  • Scope. A key belongs to one merchant and one operation. Keys from different merchants must never collide.
  • Concurrency. Two requests with the same key can arrive at once. The first to claim the key wins, and the second waits or gets a conflict. A unique constraint is more reliable than a check followed by an insert.
  • Same key, different body. Reject it. Reusing a key for a different amount is a bug on the client, and silently accepting it hides the bug.
  • Expiry. Keys cannot live forever. Pick a window longer than any sensible retry and document it.

What to return on a replay

The same status code and body as the first response, plus a header that says it was a replay. A client should not be able to tell a replay from the original except by that header.

Ayomide Ilesanmi, Lagoscommit feec46d · built 2026-11-13 07:18 UTC