Skip to content

Error catalogue

Every error response from the gateway uses the PaymentGatewayError envelope with a stable four-digit error_code. This page is the full catalogue. Branch on error_code, never on message.

The leading digit groups the cause:

Issues with credentials. Never auto-retry — these need human intervention or a fresh credential.

CodeSymbolCauseFix
1001INVALID_APP_KEYThe merchant_secret or session_token is unknown, expired, or revoked.Mint a fresh session for session_token. Rotate the key for merchant_secret.
1002APP_KEY_MISSINGNo Authorization header was sent.Add the Authorization: Bearer … header.
1003APP_NOT_ALLOWEDThe key is valid but the caller isn’t on the allow-list (IP CIDR mismatch).Add the source IP to the merchant key’s allow-list, or call from an allowed network.
1004APP_SUSPENDEDThe merchant account is suspended.Contact your Pdirect rep. Do not retry.
1005APP_EXPIREDThe credential’s hard expiry passed.Rotate the key.

Bad request shape or content. Fix on your side and don’t retry the same payload.

CodeSymbolCauseFix
1101INVALID_AMOUNTamount is <= 0, malformed, or doesn’t match session binding.Validate before sending. If session binding mismatch, mint a new session.
1102INVALID_CURRENCYcurrency not in [usd, cdf, xof] or doesn’t match session binding.Use lowercase ISO 4217. Mint a new session if the session binding is the issue.
1103INVALID_PAYMENT_METHODpayment_method not in the supported set.Check against Payment methods.
1104INVALID_PHONE_NUMBERphone_number doesn’t match ^\+?\d{1,15}$.Format as E.164 (+CCNNNNN…).
1105INVALID_EMAILEmail regex failure.Validate client-side.
1106INVALID_CARD_NUMBERCard fails Luhn check or length is out of [13, 19].Validate client-side.
1107INVALID_CARD_EXPIRYExpiry date format is wrong or in the past.Use MM/YY or MM/YYYY per the field; validate.
1108INVALID_CARD_CVVCVV not 3 or 4 digits.Validate client-side.
1109MISSING_REQUIRED_FIELDA required field for the chosen payment_method is missing.See Payment methods for the conditional table.
1110INVALID_FIELD_FORMATGeneric Pydantic validation failure. The details array has field-level breakdown.Read details, fix the field.

The request was well-formed but the business state forbids it.

CodeSymbolCauseFix
1201INSUFFICIENT_FUNDSCustomer can’t pay the requested amount.Surface to customer. Don’t auto-retry.
1202TRANSACTION_LIMIT_EXCEEDEDPer-customer or per-merchant transaction cap hit.Surface to customer; contact your rep if the limit is wrong.
1203DUPLICATE_TRANSACTIONSame payment already processed (idempotency reuse with no replay match).Use the original transaction_id.
1204TRANSACTION_NOT_FOUNDThe transaction_id or payment_id doesn’t exist or isn’t visible to this caller.Check the ID, check session ownership.
1205PAYMENT_METHOD_NOT_SUPPORTEDThe chosen method isn’t enabled for this merchant or country.Use a supported method or have your rep enable it.
1206CURRENCY_NOT_SUPPORTEDThe currency isn’t enabled for this method.Switch method or currency.
1207BENEFICIARY_LIMIT_EXCEEDEDMore than 100 beneficiaries on /payments/send.Split into multiple calls.

Rate limiting, blocked IPs, signature failures.

CodeSymbolCauseFix
1301RATE_LIMIT_EXCEEDEDPer-bucket limit exceeded.Honour Retry-After. See Rate limits.
1302SUSPICIOUS_ACTIVITYRisk engine flagged the request.Surface a generic error to the customer; investigate.
1303IP_BLOCKEDSource IP on a deny-list.Use a different network or appeal to ops.
1304INVALID_SIGNATUREMastercard 3DS callback signature mismatch (or webhook signature when that ships).Misconfigured MASTERCARD_WEBHOOK_SECRET on the gateway side; not normally your problem.
1305REQUEST_TOO_LARGERequest body over the 1MB limit.Reduce payload size.

Gateway-side or infrastructure problems. Often retryable: true.

CodeSymbolCauseFix
1401INTERNAL_SERVER_ERRORUnhandled gateway exception.Quote the request_id to support. Retry with Idempotency-Key if retryable: true.
1402SERVICE_UNAVAILABLEA downstream is offline; gateway can’t process.Retry with backoff.
1403DATABASE_ERRORPersistence-layer failure.Quote the request_id. Retry with backoff.
1404EXTERNAL_SERVICE_ERRORA processor (Mastercard, Onafriq, etc.) is misbehaving.Retry with backoff.
1405CONFIGURATION_ERRORMerchant configuration is incomplete (e.g. notify_url allow-list empty when the SDK sent a notify_url).Fix configuration in the dashboard; do not auto-retry.

The processor said no.

CodeSymbolCauseFix
1501PAYMENT_PROCESSOR_ERRORGeneric processor-side failure.Read failure_reason if present; surface or retry per retryable.
1502PAYMENT_DECLINEDIssuer or processor declined the transaction.Don’t auto-retry from the same source. Surface to the customer.
1503PAYMENT_TIMEOUTProcessor didn’t respond in time.Retry with Idempotency-Key to avoid double-charging.
1504PAYMENT_CANCELLEDCustomer or system cancelled mid-flight.Don’t retry; treat as a fresh start.
1505WEBHOOK_DELIVERY_FAILEDOutbound webhook to your notify_url failed all retries.Check your endpoint health. The transaction is still in its real state — query /payments/status/{id}.

Both SDKs collapse the four-digit codes into a nine-state PdirectPayApiResponseCode enum (LOK000–LOK009) for UI display. See the mapping in Flutter error handling or Angular error handling.

When you need the exact gateway code, drop down to the underlying HTTP client (PdirectHttpClient / PdirectHttpClientService) and read the response body’s error_code field.