Errors
Errors come back with a non-2xx HTTP status and a JSON body:
{ "error_code": "invalid_argument", "error_message": "the transaction amount is insufficient as it wont cater for cost: (4.62)", "status_code": 400}Always read error_message — it carries the specific reason, including the
provider’s own explanation when a provider refused the payment.
Validation errors
Section titled “Validation errors”When a request is malformed, invalid_arguments lists every problem at once,
so you can fix them together rather than one round trip at a time:
{ "error_code": "invalid_argument", "error_message": "transaction_channel is required", "status_code": 400, "invalid_arguments": [ { "field": "transaction_channel", "value": "", "tag": "required", "param": "", "message": "transaction_channel is required" } ]}field is the JSON path of the offending field, for example customer.first_name
or payment_config.account_number.
Provider refusals
Section titled “Provider refusals”When a provider rejects a payment, its reason is passed through in
error_message:
{ "error_code": "invalid_argument", "error_message": "missing country in recipient", "status_code": 400}These are usually a missing or mismatched field — compare your request against
required_fields[provider] from discovery.
Common cases
Section titled “Common cases”| Status | error_message |
What to do |
|---|---|---|
400 |
transaction_channel is required (and other fields) |
Fix every entry in invalid_arguments |
400 |
provider "…" is not a known provider code |
Copy the code from available_providers |
400 |
redirect_url is required for a card payment |
Send payment_config.redirect_url on card payments |
400 |
missing country in recipient |
Send customer.country |
400 |
full KYC information is required for the transaction |
Complete the beneficiary’s KYC |
400 |
the transaction amount is insufficient … |
Raise the amount to cover the cost |
401 |
— | Check your API key |
404 |
beneficiary not found | The customer_uuid is not on your account |
Handling tips
Section titled “Handling tips”- A
4xxis a permanent rejection of that request. Fix the input before retrying. - A
401means your API key is missing or wrong. - A timeout or
5xxmay still have started the payment. Before retrying, look it up withPOST /api/global/transaction-statusso the payer is never charged twice. - A
200whose body sayssuccess: falseis not an error when it carries amerchant_reference— the payment started and the result will arrive on your callback.

