Skip to main content

Error Codes Reference

Complete reference of all HTTP status codes and error responses.

Complete reference of all error codes returned by Paysera Checkout APIs.

HTTP Status Codes​

CodeNameRetryDescription
200OK-Request successful
201Created-Resource created successfully
400Bad RequestNoMalformed request syntax
401UnauthorizedMaybe*Authentication failed
403ForbiddenNoInsufficient permissions
404Not FoundNoResource does not exist
409ConflictNoResource conflict (e.g., duplicate)
422Unprocessable EntityNoValidation error
429Too Many RequestsYesRate limit exceeded
500Internal Server ErrorYesServer-side error
502Bad GatewayYesUpstream service error
503Service UnavailableYesService temporarily unavailable

*Retry after refreshing access token

Error Response Format​

{
"error": "error_code",
"message": "Human-readable description",
"details": [
{
"field": "field_name",
"message": "Field-specific error"
}
]
}

Authentication Errors​

Error CodeHTTP StatusMessageSolution
invalid_client401Invalid client credentialsVerify client_id and client_secret
invalid_token401Token is expiredRequest new access token
invalid_token401Token validation failedCheck token format and environment
invalid_grant401Invalid grant typeUse client_credentials grant
unauthorized401Authorization requiredInclude Authorization header

Validation Errors​

Error CodeHTTP StatusCommon FieldsDescription
validation_error422VariousOne or more fields failed validation

Common Field Errors​

FieldError MessageSolution
project_idProject is requiredInclude project_id in request or ensure your JWT token contains a project
project_idProject not foundVerify project ID exists and you have access
purchase.amountAmount must be greater than 0Use positive amount in minor units
purchase.amountInvalid amount formatUse whole number string (e.g., "1000" for €10.00)
purchase.amount.currencyCurrency is requiredInclude currency code
purchase.amount.currencyInvalid currencyUse valid ISO 4217 code
purchase.referenceReference is requiredInclude unique reference
redirect_urls.success_urlInvalid URL formatUse valid HTTPS URL
redirect_urls.callback_urlInvalid URL formatUse valid HTTPS URL
lifetimeLifetime must be positiveUse positive integer
experience.languageInvalid language codeUse supported language

Resource Errors​

Error CodeHTTP StatusMessageDescription
not_found404Order not foundOrder ID does not exist
not_found404Payment link not foundLink ID does not exist
not_found404Project not foundProject ID does not exist

Business Logic Errors​

Error CodeHTTP StatusMessageSolution
conflict409Order with reference existsUse unique reference
conflict409Order already completedOrder cannot be modified
invalid_state409Cannot refund pending orderWait for completion
invalid_state409Order is cancelledCannot process payment
amount_exceeded422Refund exceeds availableReduce refund amount
currency_mismatch422Currency must matchUse original currency
method_unavailable422Payment method unavailableChoose different method
limit_exceeded422Amount exceeds method limitReduce amount or change method

Rate Limiting Errors​

Error CodeHTTP StatusHeadersSolution
rate_limited429Retry-After, X-RateLimit-*Wait and retry

Rate Limit Headers​

HeaderDescription
Retry-AfterSeconds to wait before retry
X-RateLimit-LimitRequest limit per window
X-RateLimit-RemainingRemaining requests
X-RateLimit-ResetUnix timestamp of reset

Rate Limit Handling Examples​

Implement exponential backoff when encountering rate limits:

<?php

class RateLimitHandler
{
private int $maxRetries = 3;
private int $baseDelay = 1000; // milliseconds

public function executeWithRetry(callable $request): mixed
{
$attempt = 0;

while ($attempt < $this->maxRetries) {
try {
return $request();
} catch (RateLimitException $e) {
$attempt++;

if ($attempt >= $this->maxRetries) {
throw $e;
}

$delay = $this->calculateDelay($attempt, $e->getRetryAfter());
usleep($delay * 1000);
}
}
}

private function calculateDelay(int $attempt, ?int $retryAfter): int
{
if ($retryAfter !== null) {
return $retryAfter * 1000; // Convert seconds to milliseconds
}

// Exponential backoff: 1s, 2s, 4s...
return $this->baseDelay * pow(2, $attempt - 1);
}
}

// Usage
$handler = new RateLimitHandler();
$result = $handler->executeWithRetry(function() use ($client, $payload) {
return $client->createOrder($payload);
});

Server Errors​

Error CodeHTTP StatusMessageSolution
internal_error500Internal server errorRetry with backoff
gateway_error502Bad gatewayRetry with backoff
service_unavailable503Service unavailableRetry with backoff

Error Handling by Type​

PHP Example​

<?php

function handleError(int $httpCode, array $body): never
{
$error = $body['error'] ?? 'unknown_error';
$message = $body['message'] ?? 'Unknown error';

match ($httpCode) {
401 => throw new AuthenticationException($message),
403 => throw new AuthorizationException($message),
404 => throw new NotFoundException($message),
409 => throw new ConflictException($message),
422 => throw new ValidationException($message, $body['details'] ?? []),
429 => throw new RateLimitException($message),
default => throw new ApiException($message, $httpCode),
};
}

JavaScript Example​

function handleError(response, body) {
const { error, message, details } = body;

switch (response.status) {
case 401:
throw new AuthenticationError(message);
case 403:
throw new AuthorizationError(message);
case 404:
throw new NotFoundError(message);
case 409:
throw new ConflictError(message);
case 422:
throw new ValidationError(message, details);
case 429:
throw new RateLimitError(message, response.headers.get('Retry-After'));
default:
throw new ApiError(message, response.status);
}
}

User-Friendly Messages​

Error CodeUser Message
invalid_clientUnable to authenticate. Please contact support.
invalid_tokenSession expired. Please try again.
validation_errorPlease check your input and try again.
not_foundThe requested item was not found.
conflictThis action cannot be completed. The item may already exist.
rate_limitedToo many requests. Please wait a moment.
internal_errorService temporarily unavailable. Please try again.

Troubleshooting Guide​

SymptomCheckSolution
401 on all requestsCredentialsVerify client_id/secret
401 after workingTokenRefresh access token
422 with amountFormatUse minor units as string (e.g., "1000" for €10.00)
422 with URLProtocolUse HTTPS URLs
404 on orderIDVerify order UUID
409 on createReferenceUse unique reference
429 frequentlyRequest rateImplement rate limiting