Errors
The gateway returns errors as RFC 9457
problem documents with the application/problem+json content type. The type
field is a stable URI you can branch on programmatically.
{ "type": "https://api.paymee.online/errors/validation-error", "title": "Validation Error", "status": 422, "detail": "One or more fields failed validation.", "errors": [ { "field": "amount", "code": "invalid", "message": "Amount is required." } ]}| Field | Meaning |
|---|---|
type |
Stable URI identifying the error category — branch on this. |
title |
Short, human-readable summary. |
status |
HTTP status code. |
detail |
Explanation specific to this occurrence. |
errors |
Present on validation failures: a per-field array of { field, code, message }. |
Always key your handling on type (and the HTTP status), never on the
human-readable detail string, which may change.
Error type catalog
Section titled “Error type catalog”All type URIs are under https://api.paymee.online/errors/.
type suffix |
HTTP | Meaning | Retry? |
|---|---|---|---|
unauthorized |
401 | Missing, malformed, expired, or revoked API key. | No |
forbidden |
403 | Authenticated, but not allowed. | No |
not-found |
404 | The session does not exist for this account. | No |
conflict |
409 | Conflicts with the resource’s current state. May include existing_session_id. |
No |
session-terminal |
409 | The session is already in a terminal state. | No |
validation-error |
422 | One or more fields failed validation (see errors). |
No |
checkout-limit-exceeded |
422 | Too many active checkouts on the session. | No |
invalid-state |
422 | Operation not allowed in the session’s current state (e.g. refunding a non-succeeded session). | No |
no-payment |
422 | No successful payment found to act on. | No |
refund-failed |
422 | The refund could not be completed. | No |
no-terminal-configured |
422 | The merchant account has no acquirer terminal configured. | No (merchant config) |
terminal-inactive |
422 | The account’s acquirer terminal is inactive. | No (merchant config) |
terminal-rejected |
422 | The acquirer rejected the terminal credentials. | No (merchant config) |
rate-limit-exceeded |
429 | Too many requests. Back off and retry. | Yes |
processor-unavailable |
502 | The acquirer is unreachable or timed out. | Yes |
internal-error |
500 | Unexpected server error. | Yes (with backoff) |
Validation error codes
Section titled “Validation error codes”A validation-error carries a per-field errors array. The code values you
should branch on:
errors[].code |
Field | Meaning |
|---|---|---|
required / invalid |
any | The field is missing or malformed. |
invalid_type |
amount |
amount was sent as a number, not a string. |
invalid_format |
amount |
Thousands separators, leading zeros, or not a decimal. |
invalid_precision |
amount |
Decimal places don’t match the currency (3 for TND, 2 for EUR). |
invalid_value |
amount |
Zero or negative, or a foreign amount that rounds to nothing in TND. |
amount_too_large |
amount |
Over 999999.999 TND, before or after conversion. |
currency_unsupported |
currency |
No exchange rate is configured for this currency. Configure one in Settings → Currencies, or request in TND. See Amounts & currency. |
Rate limits
Section titled “Rate limits”Limits apply per merchant account, separately for live (sk_live_) and test
(sk_test_) keys: sandbox traffic never uses your live budget, and every key on the
same account shares that account’s budget.
Every request counts against the account-wide limit. Creating sessions and checkouts, and refunds, also count against their own, lower limit.
| Budget | Endpoints | Live | Test |
|---|---|---|---|
| Account-wide | All gateway endpoints | 25 requests/second | 10 requests/second |
| Create | POST /sessions/, POST /sessions/{id}/checkout/ |
10 requests/second | 5 requests/second |
| Refund | POST /sessions/{id}/refund/ |
5 requests/second | 2 requests/second |
Over a limit, the API answers 429 Too Many Requests with a Retry-After
header giving the number of seconds to wait. Wait at least that long before retrying.
When you retry a session creation, reuse the same merchant_reference so a request
that did go through is not repeated (see Idempotency). Spread
bulk work (backfills, reconciliation) over time rather than sending it in bursts.

