Skip to content

Idempotency and limits

Idempotency

The idempotency key is your merchant_payment_id, unique within the project. There is no Idempotency-Key header.

What you send Answer
A new merchant_payment_id 201 — a new payment
The same merchant_payment_id and the same fields 200 — the existing payment; requisites are not requested again
The same merchant_payment_id with other fields 409 payment_idempotency_conflict

"The same fields" are merchant_payment_id, the amount, currency, geo_code, payment_method, bank_code, is_intrabank and callback_url. Defaults are applied before the comparison: a request without currency and the same request with "currency": "RUB" are the same.

What you get. If the answer was lost — timeout, dropped connection, your server crashed — just repeat the request with the same id. No duplicate payment, no double charge.

A new payment attempt. If a payment closed (canceled, error) or got 422, a new attempt needs a new merchant_payment_id: repeating the old one returns the old result. Adding an attempt number works well: order-1001-2.

When the id is not taken. Rejections before the payment is accepted do not take the merchant_payment_id: 429, 503, 401 signature_invalid, 409 request_replayed, 413 request_too_large, 400 bad_request (unparsable body), 400 invalid_payment (a field failed validation). Fix the cause and send the request with the same id. If the corrected request gets 409 payment_idempotency_conflict, use a new id.

Nonces and retries

Payment idempotency and one-time signatures are different things.

  • X-Request-Nonce is single-use: resending the same signed request returns 409 request_replayed.
  • So re-sign on every retry: new nonce, new created/expires, the same merchant_payment_id and the same body.
  • Exception: 429 too_many_concurrent_requests does not burn the nonce, so the same signed request may be sent again before expires.

Rate limits

Limit Default When exceeded
Requests per source IP 600 per minute 429 rate_limited
Project requests 600 per minute, burst 60 429 rate_limited
Project payment creates 60 per minute, burst 6 429 rate_limited
Concurrent project requests 20 429 too_many_concurrent_requests
Request body size 64 KB 413 request_too_large
  • Project limits are visible in the cabinet; your manager can change them — ask them manager if you expect more payments.
  • A 429 carries Retry-After: how many seconds to wait.
  • Limits are per project: all your servers share one counter.
  • If rate or nonce accounting is temporarily unavailable, the API answers 503 with Retry-After: 1 — not a problem with your request, retry it.

Timeouts

Creating a payment picks requisites synchronously. Keep the HTTP client timeout at 15 seconds or more. If a timeout still happens, repeat the request with the same merchant_payment_id — see above.