Skip to content

Errors

There are two different kinds of “error” to handle: the API call itself failing, and a transaction completing with a non-success status. They look nothing alike, and only the first one is a bug in your integration.

Failed requests return a JSON body with this shape:

{
"timestamp": "2026-09-01T10:32:14.000+00:00",
"message": "Currency code should be provided",
"description": null,
"status": "400"
}
FieldTypeDescription
timestampstringWhen the error occurred
messagestringWhat went wrong. This is the field to log and show your team
descriptionstringExtra detail. Usually null; carries the per-field list for validation failures
statusstringThe HTTP status code, as a string
StatusWhat it meansExample messageWhat to do
400The request was rejected — bad field, failed validation, or a payload that decrypted into something that isn’t valid JSONPayload was decrypted but did not produced a valid json representation; Currency code should be provided; Invalid Ecocash phone number suppliedFix the request. These are integration bugs, not transient failures — don’t retry unchanged
401Authentication failedInvalid username or passwordCheck the credentials you’re using
403Your integration key was rejected, or no payment method is availableIntegration key for the application is not valid (Not active or disabled); No payment method that supports {currency} is available at the momentConfirm the key is for the right environment and still active — see API keys
404The record you asked for doesn’t existLookup misses, e.g. an unknown referenceNumberCheck the reference number you’re sending
406The operation isn’t allowed in the transaction’s current state—Re-check the transaction’s status before retrying the operation
500Something failed server-side, including decryption failures and downstream service errorsFailed to decrypt your dataIf it mentions decryption, check your encryption key and IV rule. Otherwise retry once, and contact support with the referenceNumber if it persists

Field validation failures come back as 400, and multiple problems are joined into a single message separated by ; — so parse the whole string rather than assuming one error per response. Real examples:

Invalid Visa Card Number length, its either 13, 16, 19 numbers.;
Invalid Credit card expiry date provided

Each payment method validates its own fields. See the failure-modes table on the relevant payment method page for what each one rejects.

A request can succeed at the API level — HTTP 200, valid encrypted response — while the payment itself fails. A declined card and an EcoCash timeout are both HTTP 200. Read transactionStatus in the decrypted response, not the HTTP status:

  • SUCCESS is the only status that means you were paid.
  • DECLINED, INSUFFICIENT_FUNDS, AUTHORIZATION_FAILED, TIME_OUT, and CANCELLED are normal, expected outcomes your UI should handle gracefully.
  • Non-terminal statuses (PENDING, PROCESSING, PARTIALLY_PAID) mean the payment is still in flight — keep checking.

See Transaction statuses for the full list with numeric codes.

transactionStatusDescription on a failed transaction often carries text straight from the payment provider (EcoCash, the card issuer, and so on). It’s useful to log and sometimes useful to show the customer, but it isn’t a stable value to branch on.