Skip to content

Errors

Download .md

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.

{
"type": "https://api.paymee.online/errors/validation-error",
"title": "Validation Error",
"status": 422,
"detail": "One or more fields failed validation.",
"errors": [
{ "field": "email", "code": "required", "message": "This field is required." }
]
}
Field Meaning
type Stable URI identifying the error — branch on this.
title Short, human-readable summary.
status HTTP status code.
detail Explanation specific to this occurrence.
errors On validation-error only: one { field, code, message } per invalid field.
existing_session_id On conflict from session creation: the session that already uses this merchant_reference.

Key your handling on type (and errors[].code), never on title, detail or message, which may change.

Status Means
400 The request is malformed (e.g. the body isn’t valid JSON).
401 Missing, malformed, expired or revoked API key.
404 The object doesn’t exist on this account.
409 The request conflicts with an earlier one.
422 The request is well-formed but was refused: a field failed validation, or a business rule refused it.
429 Rate limit exceeded.
500 Unexpected server error. Nothing was changed.

All type URIs are under https://api.paymee.online/errors/.

type suffix HTTP Meaning Retry?
bad-request 400 Malformed request: the body isn’t valid JSON, or a header is invalid. No
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 Same merchant_reference as an existing session, with a different amount or currency. Includes existing_session_id. No
session-terminal 409 The session is already final (cancel). No
idempotency-key-reuse 409 The Idempotency-Key was already used for a different refund request. No
validation-error 422 One or more fields failed validation (see errors). No
invalid-state 422 Not allowed in the session’s current state (e.g. canceling a PROCESSING session, refunding one that didn’t succeed). No
no-payment 422 The session has no successful payment to refund. No
partial-requires-settled 422 Partial refund before the payment has settled. See Refunds. Later
over-refund 422 The refund exceeds the amount left to refund. No
insufficient-funds 422 The refund can’t be funded from your balance. Later
refund-failed 422 The refund could not be recorded. No
rate-limit-exceeded 429 Too many requests. Wait Retry-After seconds. Yes
error 405 / 415 Wrong HTTP method or content type. No
internal-error 500 Unexpected server error; nothing was changed. Yes, with backoff

New types may be added (see Versioning): give your code a default branch.

A validation-error lists each invalid field in errors. Nested fields are named with dots, e.g. items.1 or metadata.cart_id.

Any field

errors[].code Meaning
required The field is missing.
blank A required text field is empty.
null The field is null.
invalid The value is malformed (e.g. not an email address, wrong JSON type).
max_length The text is too long.
min_value / max_value The number is out of range (e.g. max_attempts outside 1–10).
invalid_choice Not one of the allowed values (e.g. refund_type).
not_a_list / not_a_dict items isn’t a list, or one of its entries isn’t an object.

amount and currency

errors[].code Meaning
invalid_format Thousands separators, leading zeros, or not a decimal number.
invalid_precision The decimals don’t match the currency: exactly 3 for TND, 2 for EUR. See Amounts & currency.
invalid_value Zero or negative, or a foreign amount that rounds to nothing in TND.
amount_too_large Over 999999.999 TND, before or after conversion.
currency_unsupported No exchange rate is configured for this currency. See Amounts & currency.

metadata

errors[].code Meaning
too_many_keys More than 50 keys.
key_too_long A key is longer than 40 characters.
invalid_key_chars A key contains [ or ].
invalid_value_type A value is an object, a list or null (text, numbers and booleans are accepted).
value_too_long A value is longer than 500 characters.

return_url, cancel_url, webhook_url

errors[].code Meaning
https_required The URL doesn’t use https://.
invalid_domain The host isn’t a domain name with at least one dot (e.g. localhost).
ip_not_allowed webhook_url uses an IP address instead of a domain name.
invalid_scheme javascript: URLs are refused.
url_too_long Over 2048 characters.

Limits apply per merchant account, separately for live (sk_live_) and test (sk_test_) keys: test traffic never uses your live budget, and every key of the same account shares that account’s budget.

Every request counts against the account-wide limit. Creating sessions 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 /gateway/sessions/ 10 requests/second 5 requests/second
Refund POST /gateway/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. Spread bulk work (backfills, reconciliation) over time rather than sending it in bursts.