Unirail

Idempotency keys

Make every write safe to retry by deriving its key from your own record.

Networks fail after a request has been sent, and a retry that creates a second payment is the worst outcome a payments API can have. Send an Idempotency-Key header with every write, and a retry with the same key returns the result of the first request instead of doing the work again.

With the SDK, pass it in the call context:

await unirail.paymentIntents.create(
  { quote: quote.id, digest: quote.digest, returnUri },
  { context: { idempotencyKey: `payment:${payment.id}` } },
);

Choosing keys

Derive the key from the record on your side that the write belongs to, so every retry of the same intent produces the same key, wherever it runs:

WriteKey
Create a customercustomer:${user.id}
Start a link sessionlink:${linkAttempt.id}
Register a payeepayee:${contact.id}
Create a payment intentpayment:${payment.id}

Avoid random keys generated at call time: a crash between generating the key and storing it turns your retry into a new request.

Conflicts

Reusing a key for a different request fails with idempotency_conflict. That usually means two different records derived the same key, so make the key more specific rather than retrying.

On this page