Errors Error codes and how to handle them.
All errors follow a consistent envelope:
{
"error" : {
"code" : "invalid_amount" ,
"message" : "Amount must be a positive integer"
}
}
Status Meaning 400 Bad RequestInvalid or missing parameters 401 UnauthorizedMissing, invalid, or revoked API key 403 ForbiddenLive mode not activated, or unauthorized access 404 Not FoundResource not found or belongs to another merchant 409 ConflictIdempotency key in-flight (retry in a moment) 422 Unprocessable ContentBusiness rule violation (invalid state transition, over-refund, etc.) 429 Too Many RequestsRate limit exceeded — check Retry-After header 500 Internal Server ErrorUnexpected server error 503 Service UnavailableProvider is unreachable
Code Status Description unauthorized401 Missing or invalid Bearer token invalid_credentials401 Wrong email or password token_expired401 JWT has expired — log in again token_revoked401 JWT was invalidated by logout api_key_revoked401 API key has been revoked live_mode_disabled403 Live keys not activated in this instance
Code Status Description invalid_amount400 Amount is not a positive integer unsupported_currency400 Currency not in the supported list unsupported_payment_method400 Payment method not enabled for your account idempotency_key_required400 Idempotency-Key header is missingidempotency_conflict409 Same key used with different parameters invalid_state_transition422 Charge cannot move to the requested state provider_declined422 Card declined by the payment provider charge_not_found404 Charge ID doesn't exist or belongs to another merchant
Code Status Description refund_exceeds_charge422 Refund amount would exceed original charge charge_not_capturable422 Can only refund captured charges charge_not_voidable422 Can only void authorized charges
const response = await fetch ( "https://paygate-api.fly.dev/v1/charges" , {
method: "POST" ,
headers: {
"Authorization" : `Bearer ${ secretKey }` ,
"Idempotency-Key" : idempotencyKey,
"Content-Type" : "application/json" ,
},
body: JSON . stringify ({ charge: chargeData }),
});
if ( ! response.ok) {
const { error } = await response. json ();
console. error ( `[${ error . code }] ${ error . message }` );
// Handle specific codes
if (error.code === "provider_declined" ) {
// Ask user to try a different card
}
}
When the underlying payment provider declines a charge, Paygate surfaces it as provider_declined (422). The charge record is saved with status failed so you have an audit trail.