Getting started
Idempotency
Retry safely — a network hiccup never creates a double charge.
The Idempotency-Key header is the only thing that deduplicates a create. It is optional — send none and every attempt is its own payment request, which is exactly what it means.
Three identifiers travel with a create. Only the first one changes what happens; the other two are labels we store, echo back, and let you filter on.
Idempotency-Key
A header, up to 255 bytes, and your protection against the network. The limit counts bytes rather than characters, so a key built out of non-ASCII text runs out sooner; a UUID is unaffected. Send the same key again and you get the original payment request back with status 200 instead of 201, and nothing is created the second time.
So 201 means created and 200 means you already had it. Nothing else returns an existing payment request.
Once a key is on a payment request, sending it with a different body is rejected 409 idempotency_conflict. A key only lands on a payment request that was actually created: if your first attempt was refused — a 422, say — nothing was stored and the key is free to use again. We compare a hash of the exact bytes you sent, not the parsed object, so reordering keys or changing whitespace counts as a different body. Keys are scoped to your account, stored permanently, and never expire — retrying an hour or a month later is equally safe.
POST /v1/refunds takes the same header, with one difference: a key already on one of your refunds replays that refund whatever the body says this time. There is no body comparison on refunds, so no 409 — the original refund comes back and nothing moves twice.
merchant_ref
Your own reference for the payment, max 64 characters, echoed in every response and filterable on the list endpoint. It does not deduplicate anything. Two creates carrying the same merchant_ref are two payment requests.
external_id
The seller's order number. Like merchant_ref, it is stored and filterable and nothing more — one order can legitimately be paid twice, and we do not decide otherwise on your behalf.
What to use
A value unique per payment request — your order number, or a UUID your code generates before the first attempt and reuses for every retry of it. Generating a fresh key on retry defeats the whole mechanism, and no other field will catch it for you.