Error Codes
All PayElect API errors follow a consistent JSON structure. The code field is a machine-readable string; message is human-readable and may change between releases — always branch on code, never on message.
{
"status": "error",
"code": "PAY_1002",
"message": "Requested with invalid token!",
"errors": {},
"data": []
}
Validation errors include a field-level breakdown in errors:
{
"status": "error",
"code": "PAY_4000",
"message": "Validation failed.",
"errors": {
"amount": ["The amount field is required."],
"currency": ["The selected currency is invalid."]
},
"data": []
}
PAY_1xxx — Authentication
| Code | HTTP | Message | Cause & Remedy |
|---|---|---|---|
PAY_1001 |
401 | Access denied! Token not found |
No Authorization header was sent.
Add the header: Authorization: Bearer <token> |
PAY_1002 |
403 | Requested with invalid token! |
The access token does not match any live payment session.
Request a new token via POST /authentication/token. Tokens expire after 10 minutes. |
PAY_1003 |
401 | Request token is expired |
The access token was issued more than 10 minutes ago.
Call POST /authentication/token again immediately before creating each payment. |
PAY_1004 |
401 | Requested credentials is invalid |
client_id not found, or client_secret hash does not match.
Verify credentials in the merchant portal. Do not expose client_secret in client-side code. |
PAY_1005 |
400 | Requested with invalid credentials |
Mode mismatch: sandbox credentials used against the production URL, or vice versa.
Use sandbox credentials with /sandbox/api/v1 and live credentials with /api/v1. |
PAY_2xxx — Payment Errors
| Code | HTTP | Message | Cause & Remedy |
|---|---|---|---|
PAY_2001 |
404 | Payment order not found. |
The trx_id does not exist or belongs to a different merchant.
Confirm the trx_id from the payment.created webhook or POST /payment/create response. |
PAY_2002 |
400 | Payment request is invalid! |
The payment session is in a status that prevents the requested action (e.g. already SUCCESS or REJECTED).
Check data.status via GET /payment/status before retrying. |
PAY_2003 |
400 | Mode mismatch |
The developer credential mode does not match the URL environment.
Match credentials to environment: sandbox keys with /sandbox/api/v1. |
PAY_2004 |
422 | Only completed payments can be refunded. |
Refund attempted on a PENDING or REJECTED payment.
Poll GET /payment/status and only request a refund when status is SUCCESS. |
PAY_2005 |
404 | Refund not found. |
The refund_uid does not exist or belongs to a different merchant.
Use the refundUid returned by POST /payment/{trx_id}/refund. |
PAY_2006 |
422 | Refund not supported for this provider. |
The payment was made via a provider that does not support API refunds (e.g. MTN MoMo in some markets).
Issue a manual refund via the merchant portal, or use payout to return funds. |
PAY_3xxx — Payout Errors
| Code | HTTP | Message | Cause & Remedy |
|---|---|---|---|
PAY_3001 |
422 | Payout request failed. |
Business logic error: insufficient wallet balance, missing destination fields, or recipient validation failure.
Check the message field for specifics. Ensure your merchant wallet has sufficient balance. |
PAY_3002 |
404 | Payout not found. |
The payout_uid does not exist or belongs to a different merchant.
Use the payoutUid from the POST /payout response. |
PAY_4xxx — Validation Errors
| Code | HTTP | Message | Cause & Remedy |
|---|---|---|---|
PAY_4000 |
400 | Validation failed. |
One or more required fields are missing, have the wrong type, or fail format checks.
Inspect the errors object for per-field messages. All amounts must be numeric strings; currencies must be valid ISO 4217 codes; country codes must be ISO 3166-1 alpha-2. |
PAY_5xxx — Provider / Server Errors
| Code | HTTP | Message | Cause & Remedy |
|---|---|---|---|
PAY_5001 |
500 | Failed to create access token. Please try again. |
Database or internal server error during token generation.
Retry with exponential backoff. If persistent, check https://status.payelecthq.com. |
PAY_5002 |
400 | Failed to create payment! Please try again. |
Unexpected error during payment session creation or update.
Retry using the same idempotency_key. The key ensures only one payment is created even if you retry. |
PAY_5003 |
500 | Provider error. |
The upstream payment provider returned an unexpected error or timed out.
PayElect automatically cascades to the next available provider. If all providers fail, this error is returned. Retry later or select a different payment method. |
PAY_6xxx — Merchant / Credential Errors
| Code | HTTP | Message | Cause & Remedy |
|---|---|---|---|
PAY_6001 |
400 | Merchant doesn't exist or credentials are invalid. |
The merchant account was deleted, suspended, or the credential no longer belongs to an active merchant.
Log in to the merchant portal and verify your account status and API key association. |
HTTP status code summary
| HTTP Status | Meaning in PayElect context |
|---|---|
| 200 | Request succeeded. Check data for the response payload. |
| 201 | Resource created (e.g. refund, payout). Check data. |
| 202 | Accepted but processing is async (e.g. payout pending approval, payment pending provider confirmation). |
| 400 | Bad request — missing required fields, mode mismatch, or invalid state transition. |
| 401 | Authentication required or token expired. |
| 403 | Authentication failed — invalid credentials or access denied. |
| 404 | Resource not found (payment, refund, or payout with that ID does not exist for your merchant). |
| 422 | Business logic rejection — payment not refundable, provider not supported, etc. |
| 429 | Rate limit exceeded. Retry after the number of seconds in the Retry-After response header. |
| 500 | Internal server error. These are rare. Check status.payelecthq.com for incidents. |
Rate limits
| Endpoint group | Limit |
|---|---|
| POST /authentication/token | 10 requests per minute per IP |
| POST /payment/create | 30 requests per minute per access token |
| GET /payment/status, GET /payments/gateways | 60 requests per minute per access token |
| Refunds, Payouts, Subaccounts | 30 requests per minute per client_id |