Errors
The public API answers with ordinary HTTP codes. Here is what each one means in practice and when the request is worth repeating.
Successful responses
| Code | When |
|---|---|
201 | This request created the payment. |
200 |
A payment with that external_order_id already existed in the project, so we
returned it. Not an error: retrying is safe by construction.
|
Errors
| Code | Cause | What to do |
|---|---|---|
401 |
No Authorization header, not in Bearer … form, or the key is
unknown, revoked, or belongs to an archived project.
| Do not retry. All of these answer identically — the response never reveals whether such a key exists. Check the key in the dashboard. |
404 | Payment not found — either it does not exist or it belongs to another project. | Do not retry. Make sure you are asking with a key from the project that created the payment. |
409 |
A race: two concurrent first-time creates with the same external_order_id.
Rare.
| Retry once — the winning request created the payment, and the retry returns it with 200. |
422 |
Field validation failed: a required field is missing, amount is not greater
than zero or has more than two decimal places, a string exceeds its limit, or
return_url/fail_url are not URLs.
| Do not retry unchanged — the response body names the offending fields. |
422amount_above_maximum |
The amount is over the payment cap and crypto —
which the cap does not cover — is unavailable, so there would be nothing to pay with. The
body carries max_rub.
| Do not retry with the same amount: split the payment or lower it. |
5xx | A failure on our side. |
Retry with backoff. Create is idempotent on external_order_id, so a retry
will not produce a second payment.
|
Declines on the checkout page
These are what the customer sees; your server learns about them as a status change in the webhook, not as a failed request.
- Acquirer decline — the payment moves to
declined. Banks do not disclose the reason and the customer sees a generic message. Retrying means a new payment. - Processor unavailable — payment does not start and stays
pendinguntil it expires. The customer can try again or pick another method. - Expired — the payment moves to
expiredand can no longer be paid. Create a new one.
Retry rule
Only 5xx and 409 are worth retrying. 401,
404 and 422 will return exactly the same thing — they need fixing, not
retrying.
Because create is idempotent, the safest move after a network timeout is to repeat the same
request with the same external_order_id. Minting a fresh order ID for the retry is
both unnecessary and harmful: it turns one payment into two.