Skip to main content
ShadhinPay Docs

Idempotency

Use idempotency keys to safely retry mutating requests without creating duplicate payments or refunds.

Network calls fail in ambiguous ways — a request times out, but did the server process it? Idempotency keys let you retry safely: a repeated request with the same key returns the original result instead of creating a duplicate.

How it works

Send a unique X-Idempotency-Key header on mutating requests:

X-Idempotency-Key: order-7831-attempt-1

ShadhinPay remembers the key and the request for 24 hours:

  • Same key, same body → you get the original response back, verbatim. The response carries Idempotent-Replay: true so you can tell it was a replay. No new payment is created.
  • Same key, different body409 Conflict with errorType: IDEMPOTENCY_CONFLICT. The key is already bound to a different request.
  • New key → processed normally.

After 24 hours a key is forgotten and may be reused.

Where it applies

Idempotency keys are honoured on the mutating, money-moving endpoints:

  • POST /payments
  • POST /payments/{paymentId}/refunds

Use a fresh key per logical operation

Generate one key per intent — e.g. per checkout attempt or per order. Reuse the same key when retrying that operation, but use a new key for a genuinely new operation. A UUID per attempt is a good default.

How matching works

ShadhinPay compares requests by hashing a canonical form of the body (keys sorted, whitespace normalised). This means a re-serialised but semantically identical body still matches — but any real change to the payload (a different amount, a different order ID) counts as a different request and triggers the conflict response.

A safe retry pattern

key = uuid()                       # once, per checkout attempt
loop:
  response = POST /payments  with X-Idempotency-Key: key
  if response is a network error or 5xx:
      wait (with backoff) and retry with the SAME key
  else:
      break    # 2xx or a definitive 4xx — stop retrying

Because the key is stable across retries, you'll never double-charge a customer even if the first attempt actually succeeded but you never saw the response.

Next steps

On this page