#Idempotency
Network calls fail. Idempotency lets you safely retry a request that creates something — a payment, a payment link — without accidentally creating it twice.
#How it works
Attach an Idempotency-Key header to a supported POST. If PlutoPay has already processed a request with that key for your account, it returns the original result instead of doing the work again — and echoes the key back on the response.
Supported on four endpoints:
| Endpoint | Retrying returns |
|---|---|
POST /v1/transactions (and its alias POST /v1/payment-intents) |
the original transaction |
POST /v1/terminal/create-payment |
the original transaction |
POST /v1/transactions/{id}/refunds |
the original refund |
POST /v1/payment-links |
the original link |
The echo is the proof. Only these endpoints return the Idempotency-Key header on the
response. If you send a key to any other endpoint it is ignored and not echoed — so a
response without the header means the request was not deduplicated, and a retry would do
the work again. Design retries around that.
curl https://plutopayus.com/api/v1/transactions \
-H "Authorization: Bearer sk_test_your_key_here" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order_1001" \
-d '{ "amount": 4750, "currency": "usd", "payment_method_type": "card" }'
- First call → creates the transaction, returns
201. - Repeat with the same key → returns the existing transaction with
200and a note:"Idempotent request - returning existing transaction." - The response echoes the header back:
Idempotency-Key: order_1001.
On POST /v1/transactions and /v1/terminal/create-payment, a legacy idempotency_key body field is still accepted for backward compatibility, but the header is preferred.
Not supported on capture, cancel, hosted checkout sessions or customers. A retried cancel or capture is safe by nature (the second call finds nothing to do); a retried checkout session creates a second session — keep your own record of the session id.
#Best practices
- Generate a unique key per logical operation — e.g. your internal order id, optionally suffixed (
order_1001:charge). Reusing a key for a different operation returns the first result, which is probably not what you want. - Keep keys stable across retries of the same operation, and different across distinct operations.
- Safe to retry with the same key:
429(rate limited) and5xx(server) responses. Do not blindly retry4xxvalidation errors — fix the request first.