API reference

Error handling

Every failure comes back in the same envelope: type: "error", data: [], and the reasons as an array of strings in message.error with the HTTP status repeated in message.code. One error branch handles the whole API.

Common failures

400validationA field failed validation — e.g. "The amount must be a string." when amount is sent as a number. The array may hold several messages, one per failing field. Fix the request; don’t retry it unchanged.
400invalid secret"Invalid secret ID" from the token endpoint — the secret_id is wrong or was regenerated. Re-copy both keys from the merchant panel.
403invalid token"Requested with invalid token!" — the Bearer access token is expired (they live 600 seconds) or wrong. Request a fresh access token and retry once; a second 403 means a credential problem, not expiry.
404wrong base URLThe route doesn’t exist — usually a mistyped base URL. It must end in /pay/api/v1; the response here may be the platform’s HTML 404 rather than the JSON envelope.
5xxserver errorTransient failure on the QRPay side. Retry with exponential backoff (e.g. 1s, 2s, 4s, then give up). Token requests are safe to repeat; for payment/create, keep your own order reference so a retry can’t double-charge.

Surfacing errors

  • Log the full message.error array (plus the endpoint and message.code) — it’s written for you, the developer.
  • Don’t show those strings to customers. "Invalid secret ID" means nothing to a buyer and leaks integration detail — show a generic “payment couldn’t be started, please try again” instead.
  • Branch on type (or the HTTP status) before reading data— on errors it’s an empty array, not an object.
Retry rules of thumb
  • 400 — never retry unchanged; fix the request.
  • 403 — refresh the token, retry once.
  • 5xx — retry with backoff, a few attempts at most.
Error 400 · validation
{
  "message": {
    "code": 400,
    "error": ["The amount must be a string."]
  },
  "data": [],
  "type": "error"
}
Error 400 · invalid secret
{
  "message": {
    "code": 400,
    "error": ["Invalid secret ID"]
  },
  "data": [],
  "type": "error"
}
Error 403 · invalid token
{
  "message": {
    "code": 403,
    "error": ["Requested with invalid token!"]
  },
  "data": [],
  "type": "error"
}