Errors
Learn about our error codes and how to resolve them.
When you make an API request, errors can occur due to authentication failures, invalid input, or processing issues. It's important to handle these errors properly by understanding their structure, status codes, and related messages. You can explore the details below.
Error Structure
If there’s an issue with your request, the API returns a 4XX or 5XX HTTP status code along with a structured error response. This response includes information about what went wrong.
{
"status": "failed",
"error": {
"type": "REQUEST_NOT_VALID",
"code": "10400",
"message": "Request is not valid",
"validation_errors": [
{
"field_name": "payment_method_id",
"message": "must not be null"
},
{
"field_name": "currency",
"message": "must not be null"
}
]
}
}
The general structure of the error contains:
| Parameter | Definition | Example |
|---|---|---|
status | Indicates the outcome of the request. | failed |
error.type | Describes the category of the error, such as validation, authentication, or processing issues. | REQUEST_NOT_VALID |
error.code | A unique identifier for the error. Useful for debugging and custom error handling. | 10400 |
error.message | A short message that explains the error. | Invalid card number |
error.validation_errors | A list of specific validation errors, usually provided when there are issues with the input data. | [{ "field_name": "card.encrypted_card_number", "message": "must not be null" }] |
General Error Codes
When a request fails, it returns an error code to help identify the issue and guide troubleshooting. Below is a list of common error codes, their meanings, and potential causes:
| Code | Error Type | Definition | Possible cause |
|---|---|---|---|
10400 | REQUEST_NOT_VALID | The request was rejected due to invalid parameters or missing data. | Malformed request, missing parameters, or invalid JSON payload. |
10401 | UNAUTHORIZATION | The request requires authentication or has invalid credentials. | Missing API key, expired token, or incorrect credentials. |
10403 | FORBIDDEN | The client does not have permission to access the resource. | Insufficient privileges or access restrictions. |
10404 | RESOURCE_NOT_FOUND | The requested resource could not be found on the server. | Nonexistent endpoint, incorrect URL, or deleted resource. |
10409 | RESOURCE_CONFLICT | A conflict occurred due to duplicate or conflicting data. | Attempt to create an existing resource or version conflict. |
10422 | UNPROCESSABLE | The request was well-formed but contained invalid data. | Failed validation due to incorrect or incomplete fields. |
10500 | INTERNAL_SERVER_ERROR | An unexpected server error occurred while processing the request. | System failure or unhandled exceptions. |
Collections or Inflow Payments Error Codes
Below is a list of error codes you may encounter when collecting payments. If you keep getting persistent errors, please contact our support team for assistance.
| Code | Error Type | Definition | Possible Cause |
|---|---|---|---|
10400 | REQUEST_NOT_VALID | The request was rejected due to invalid parameters or missing data. | The JSON body is malformed, or required parameters are missing. |
10401 | UNAUTHORIZED | The request requires authentication or has invalid credentials. | Missing API credentials, expired token, or incorrect credentials. |
10403 | FORBIDDEN | The client does not have permission to access the resource. | Insufficient privileges or access restrictions. |
10404 | RESOURCE_NOT_FOUND | The requested resource could not be found on the server. | Nonexistent endpoint, incorrect URL, or deleted resource. |
10405 | METHOD_NOT_ALLOWED | Method not allowed | You used GET instead of POST (or vice versa). |
10409 | RESOURCE_CONFLICT | A conflict occurred due to duplicate or conflicting data. | Attempt to create an existing resource or version conflict. |
10422 | UNPROCESSABLE | The request was well-formed but contained invalid data. | Failed validation due to incorrect or incomplete fields. |
10500 | INTERNAL_SERVER_ERROR | An unexpected server error occurred while processing the request. | System failure or unhandled exceptions. |
701500 | INVALID_PAGINATION_TYPE | Invalid pagination type | The pagination parameters (page, limit) are formatted incorrectly. |
1100409 | CHARGE_ALREADY_EXISTS | Charge with reference already exists | You are reusing a transaction reference that has already been used. |
1101422 | CUSTOMER_NOT_FOUND_FOR_CHARGE | The Customer was not found for the charge. | The customer_id provided does not exist. |
1102422 | PAYMENT_METHOD_NOT_FOUND_FOR_CHARGE | The Payment method was not found for the charge. | The payment_method_id is invalid or does not belong to this customer. |
1104400 | CARD_NOT_TOKENIZED | The card is not tokenized. | You sent raw card data to an endpoint expecting a token/nonce. |
1105500 | CHARGE_FAILED | Could not complete charge. | General processing failure from the upstream provider. |
1106400 | PAYMENT_METHOD_TYPE_MISSING | Missing payment method type | The request body is missing the type field (e.g., card, bank_transfer). |
1107500 | CHARGE_CREATION_FAILED | Unable to create a charge | System error during the initialization of the charge. Kindly retry. |
1108400 | CARD_RETOKENIZATION_REQUIRED | Please retokenize the card. | The encryption or token used is invalid or expired. |
1110404 | CHARGE_NOT_FOUND | Charge not found | The charge ID provided does not exist. |
| 1111400 | CHARGE_FINALIZED | The Charge already has a final status | You cannot update or retry a transaction that is already successful or failed. |
| 1112400 | CHARGE_UPDATE_NOT_ALLOWED | The charge cannot be updated | The current state of the charge does not allow modification. |
| 1113500 | CHARGE_UPDATE_FAILED | Unable to update charge | System error during the update process. |
| 1114400 | ACCOUNT_ID_NOT_FOUND | No accountId found | Internal configuration error regarding the merchant account. |
| 1118400 | INVALID_CARD_NUMBER | Invalid card number | The card number length is incorrect or failed the Luhn check. |
| 1119500 | FAILED_TO_INITIATE_CHARGE | Failed to initiate charge | The payment provider rejected the initialization request. |
| 1121400 | INVALID_AUTHORIZATION | Failed to validate pre-existing charge | The PIN or OTP provided is incorrect. |
| 1122400 | FAILED_TO_VALIDATE_EXISTING_CHARGE | Failed to validate pre-existing charge | An error occurred while checking the status of a previous transaction. |
| 1125400 | CURRENCY_NOT_SUPPORTED | Currency not supported for payment type | Example: Trying to use UGX with a payment method that only supports NGN. |
| 1126400 | MOBILE_MONEY_COUNTRY_CODE_NOT_SUPPORTED | Country code not supported for Mobile Money | The country code provided is not valid for mobile money. |
| 1127400 | MOBILE_MONEY_NETWORK_NOT_SUPPORTED | Network not supported for Mobile Money. | The network (e.g., MTN, Airtel) is not supported in the selected region. |
| 1128500 | PAYMENT_CARD_TOKENIZATION_FAILED | Payment card details tokenization failed | Encryption failed. Check your encryption keys and logic. |
| 1130400 | AMOUNT_BELOW_MINIMUM | Amount below the minimum for the payment type | The transaction amount is too small to be processed. |
| 1134422 | CARD_EXPIRED | The Card has expired | The expiry date on the card is due. |
| 1135422 | CARD_EXPIRY_YEAR_OUT_OF_RANGE | Card expiry year out of range | The card expiry year provided is invalid. |
| 1136422 | CARD_EXPIRY_MONTH_OUT_OF_RANGE | Card expiry month out of range | The card expiry month provided is not between 01 and 12. |
| 1137400 | CLIENT_ENCRYPTION_ERROR | Unable to decrypt encrypted fields | The encryption logic is incorrect, or the wrong encryption key was used. |
| 1138422 | UNPROCESSABLE_F4B_RESPONSE | Unprocessable F4B response | An error was received from the banking partner system. |
| 1139422 | UNPROCESSABLE_CC_RESPONSE | Unprocessable CC response | An error was received from the card network/scheme. |
| 1140400 | CHARGE_NOT_SUCCESSFUL | The charge is not successful. | The transaction was declined by the bank or failed fraud checks. |
| 1141400 | REDIRECT_URL_INVALID | Redirect URL is invalid. | The redirect URL format is incorrect. |
| 1142400 | USSD_BANK_CODE_INVALID | Invalid bank code | The USSD bank code provided is incorrect |
| 1150400 | INVALID_CHARGE | Please use the /virtual-accounts resource | You are attempting to create a bank transfer using the wrong endpoint. |
| 1100409 | ORDER_ALREADY_EXISTS | Order with reference already exists | Duplicate order reference. |
| 1101422 | CUSTOMER_NOT_FOUND_FOR_ORDER | Customer not found for the order | The customer_id attached to the order is invalid. |
| 1102422 | PAYMENT_METHOD_NOT_FOUND_FOR_ORDER | Payment method not found for order | The payment_method_id attached to the order is invalid. |
| 1110404 | ORDER_NOT_FOUND | Order not found | The Order ID provided does not exist. |
| 1111400 | ORDER_FINALIZED | Order already has final status | You cannot modify an order that is already completed. |
| 1112400 | ORDER_UPDATE_NOT_ALLOWED | Order update is not allowed | The order state does not allow updates. |
| 1143400 | CAPTURE_AMOUNT_INVALID | Capture amount is greater than the order amount | You cannot capture more funds than were authorized. |
| 1144400 | PAYMENT_METHOD_MISMATCH | The payment method does not match the order | The payment method in the charge request differs from the Order. |
| 1144400 | CUSTOMER_MISMATCH | Customer does not match the order customer | The customer in the charge request differs from the Order. |
| 1144400 | CURRENCY_MISMATCH | Currency does not match the order currency | The currency in the charge request differs from the Order. |
| 1145400 | CAPTURE_VOID_NOT_ALLOWED | The order cannot be captured or voided | The order is not in a state (e.g., authorized) that allows capture/void. |
| 1145400 | PAYMENT_METHOD_INVALID | The payment method is invalid | The payment method provided is not valid for this order type. |
| 1401404 | REFUND_NOT_FOUND | Refund not found | The Refund ID provided does not exist. |
| 1402400 | REFUND_AMOUNT_INVALID | The refund amount cannot be more than the charge amount | You are attempting to refund more than the original transaction value. |
| 1403400 | REFUND_CREATION_FAILED | Refunds can't be initiated for pending transactions | You must wait for the transaction to be successful before refunding. |
| 1404400 | REFUND_ALREADY_COMPLETED | Charge already refunded | The transaction has already been fully refunded. |
| 1500404 | SETTLEMENT_NOT_FOUND | Settlement not found | The Settlement ID provided does not exist. |
| 1600400 | WEBHOOK_URL_INVALID | Webhook endpoint URL is invalid | The URL provided is not a valid HTTP/HTTPS URL. |
| 1601404 | WEBHOOK_ENDPOINT_NOT_FOUND | Webhook endpoint not found | No webhook configuration exists for this account. |
| 1602422 | UNPROCESSABLE_SVIX_RESPONSE | Unprocessable Svix response | Error communicating with the webhook provider (Svix). |
| 1603500 | INTERNAL_SERVER_ERROR_SVIX | Internal server error Svix response | System failure with the webhook provider. |
| 1700404 | CHARGEBACK_NOT_FOUND | Chargeback not found | The Chargeback ID provided does not exist. |
| 1703400 | CHARGEBACK_DECLINE_INVALID | Declined chargebacks must have a comment and proof | You rejected a chargeback without providing evidence. |
| 1704400 | CHARGEBACK_PROOF_INVALID | Invalid proof data | The file uploaded is corrupted or in an unsupported format. |
| 1705500 | CHARGEBACK_PROOF_UPLOAD_FAILED | Error uploading proof data | System error during file upload. |
| 1706400 | CHARGEBACK_DUE_DATE_INVALID | The chargeback due date is invalid | The deadline for responding to this chargeback has passed. |
| 1707400 | CHARGEBACK_AMOUNT_INVALID | The chargeback amount is invalid | The amount specified does not match the dispute amount. |
| 1708400 | CHARGEBACK_HAS_EXISTING_CHARGE | The charge already has an existing chargeback | A dispute is already in progress for this transaction. |
| 1800404 | CHECKOUT_SESSION_NOT_FOUND | Checkout section not found | The session ID provided does not exist or has expired. |
| 1801409 | CHECKOUT_SESSION_ALREADY_EXISTS | Checkout session with reference already exists | Duplicate session reference. |
| 1900404 | VIRTUAL_ACCOUNT_NOT_FOUND | Virtual account not found | The Virtual Account reference provided does not exist. |
| 1900409 | VIRTUAL_ACCOUNT_REFERENCE_ALREADY_EXISTS | Virtual account with that reference already exists | You are reusing a reference for a new virtual account. |
| 1900500 | VIRTUAL_ACCOUNT_UPDATE_FAILED | Virtual account update failed | System error during account update. |
| 1900500 | FAILED_TO_CREATE_VIRTUAL_ACCOUNT | Failed to create a virtual account | System error during account creation. |
| 10503 | VIRTUAL_ACCOUNT_CREATE_TIMEOUT | Request timeout | The provider took too long to generate the account. Retry. |
| 19400 | VIRTUAL_ACCOUNT_IS_ALREADY_INACTIVE | The virtual account is already inactive | You are trying to deactivate an account that is already closed. |
Payout Error Codes
Transfers could fail for different reasons. Read all possible error codes for payouts in the table below:
| Code | Error Type | Definitions | Possible Cause |
|---|---|---|---|
0301 | TRANSFER_AMOUNT_EXCEEDS_LIMIT | The transfer amount exceeds the allowed limit. | The amount you are trying to transfer exceeds the maximum allowed limit for a single transfer. |
0302 | TRANSFER_AMOUNT_BELOW_LIMIT | The transfer amount is below the minimum amount required. | You are trying to transfer an amount that is below the minimum allowed amount. |
0303 | MONTHLY_TRANSFER_LIMIT_EXCEEDED | You have exceeded your monthly transfer limit. | You have reached the cumulative value of transfers allowed for your account in a single month. |
0304 | DAILY_TRANSFER_LIMIT_EXCEEDED | The daily transfer limit has been reached. | You have reached the cumulative value of transfers allowed on your account in a day. |
0305 | TRANSFER_LIMIT_NOT_SET_FOR_CURRENCY | The transfer limit has not been set for this currency. | There is no configured transfer limit for the specified currency. Kindly contact support. |
0306 | PAYOUT_CREATION_FAILED | An error occurred while creating the payout. | Temporary service timeout. Kindly retry again. |
0307 | INSUFFICIENT_BALANCE | You do not have sufficient funds. | Your wallet does not have sufficient funds to cover the transfer amount and the applicable fee. |
0308 | SERVICE_UNAVAILABLE | The service is temporarily unavailable. | Bank maintenance or network downtime |
0309 | TRANSFER_FAILED | We encountered an issue processing your transfer. | The destination account is closed or dormant, Network failure during processing. |
0310 | PRICING_NOT_SET | Pricing has not been set. | The transfer fee could not be determined. Kindly contact support. |
0311 | CURRENCY_CONVERSION_NOT_SET | Currency conversion has not been configured. | You are attempting a cross-currency transfer (e.g., USD Wallet to NGN Bank), but the exchange rate is not configured. Kindly contact support. |
0312 | REJECTED_RECIPIENT_MERCHANT | The recipient merchant is not eligible to receive transfers. | There are compliance or risk restrictions on the destination account. |
0313 | INVALID_BANK_CODE | The provided bank destination code is invalid. | You are passing an incorrect or outdated bank code. |
0314 | UNABLE_TO_DETERMINE_COUNTRY | The country for the provided bank code could not be determined. | The bank code format is incorrect. There is a mismatch between the bank code and the expected currency |
270400 | RECIPIENT_NOT_FOUND | The specified recipient could not be found. | The provided recipient_id does not exist. |
270409 | RECIPIENT_ALREADY_EXISTS | A recipient with the provided details already exists. | A recipient with the provided details has already been created. |
280409 | SENDER_ALREADY_EXISTS | A sender with the provided details already exists. | A sender with the provided details has already been created. |
280400 | SENDER_NOT_FOUND | The specified sender could not be found. | The provided sender_id does not exist. |
281400 | UNKNOWN_SENDER_TYPE | The provided sender type is invalid or unsupported. | The provided sender type value is not a supported value. |
262400 | ACCOUNT_DETAILS_CHANGED | The Account details specified have changed. Update the account details and try again. | The account details provided have been updated or migrated by the bank. |
260400 | BENEFICIARY_ACCOUNT_NOT_SUPPORTED | The beneficiary account is not supported. Check the account details and try again. | The receiving account type is not supported for transfers. |
252400 | UNKNOWN_BANK_CODE | The specified bank code is not recognized. Verify the bank code and try again. | The provided bank code is invalid or unsupported. |
251400 | INVALID_ACCOUNT | The specified account number is invalid. Check the account number and try again. | The provided account number is invalid or does not exist. |
250400 | ACCOUNT_VERIFICATION_FAILED | The specified account details cannot be verified. Check the details and try again. | The provided account details could not be verified with the bank. |
501422 | RATE_UNAVAILABLE_ERROR | The exchange rate is currently not available. | The exchange rate for the requested currency pair is unavailable. |
301404 | RATE_NOT_FOUND | The specified rate could not be found. | The provided rate id does not exist. |
404400 | REQUIRES_FAILED_STATUS | You can only retry a failed transfer | The transfer being retried does not have a failed status. |
201409 | REFERENCE_ALREADY_EXISTS | A transfer with the provided reference already exists. | A transfer has already been initiated with the provided reference. |
403400 | SCHEDULED_DEFERRED_NOT_ALLOWED | A scheduled or deferred transfer cannot be retried or duplicated. | The transfer being retried or duplicated is scheduled or deferred. |
401400 | REQUIRES_SUCCESSFUL_STATUS | You can only duplicate a successful transfer | The transfer being duplicated does not have a successful status. |
204400 | REQUIRES_DISBURSE_OPTION | Scheduled payouts require a`disburse_optionobject. | The `disburse_option parameter is missing from the request. |
205400 | REQUIRES_TIMEZONE | Thedisburse_option object requires a timezoneparameter. | The timezone parameter is missing from the.disburse_option. `object. |
206400 | REQUIRES_DATETIME | The disburse_option object requires adate_timeparameter | The date_time parameter is missing in the disburse_option object. |
231400 | INVALID_DISBURSE_DATETIME | The date_timevalue must use the YYYY-MM-DD HH:MM:SS 24-hour format. | The provided date_time value is not in the required format. |
207400 | DISBURSETIME_RESTRICTION | For scheduled payouts, the date_time value must be more than 30minutes in the future. | The provided date_time value is 30 minutes or less in the future. |
215400 | COMPLIANCE_APPROVAL_REQUIRED | Approval is required to use this feature | The merchant has not completed the required KYC verification. |
214400 | TRANSFER_SERVICE_UNAVAILABLE | The transfer service is temporarily unavailable. Retry again later or contact support. | The transfer service is temporarily unavailable or disabled. |
216400 | TRANSFER_SOURCE_REQUIRED | A transfer preference is required to make transfers. | No transfer preference has been selected. Settings > Business Preference > Security. |
217400 | TRANSFER_SOURCE_DISABLED | Transfers are not enabled. | The account is disabled from making transfers. Kindly re-enable. Settings > Business Preference > Security. |
218400 | API_TRANSFER_DISABLED | Transfers via the API are not enabled. | Transfers using the API are not currently enabled. Enable it on your dashboard. Settings > Business Preference > Security. |
219400 | NG_DOM_TRANSFER_UNAVAILABLE | This transfer option is temporarily unavailable. Try again later | The specific transfer option is temporarily unavailable. |
220400 | IP_WHITELISTING_REQUIRED | IP whitelisting is required to access the transfer service. | IPs have not been whitelisted. |
221400 | NON_WHITELISTED_IP | A transfer request was made from an unwhitelisted IP address. | The request originated from an IP address that is not whitelisted. |
222400 | BLACKLISTED_IP | A transfer request was made from a blacklisted IP address | The request originated from a blocked IP address. |
223400 | BLACKLISTED_ACCOUNT_NUMBER | Transfer was made to a blacklisted account number. | The destination account number is blocked. |
226400 | XAF_TRANSFER_ONLY | Only XAF-to-XAF transfers are supported for this account. | A cross-currency transfer involving XAF was attempted without the required approval. |
405400 | POSSIBLE_DUPLICATE_RETRIES | A retry already exists for this transfer and has not failed. | A previous retry attempt is still pending or was successful. |
227400 | TRANSFER_OPTION_UNAVAILABLE | This transfer option is temporarily unavailable. Try again later | The requested transfer type (mobile_money, bank e.t.c) is currently unavailable. |
228400 | TRANSFER_AMOUNT_LIMIT | The transfer amount passed is outside the allowed limit. | The transfer amount is either below the minimum or above the maximum allowed limit. |
229400 | ZAMBIA_TRANSFER_UNAVAILABLE | Payouts to Zambia are only available to merchants registered in Zambia. | The merchant is not registered in Zambia or has not been approved for Zambia payouts. |
230400 | UNSUPPORTED_MOBILE_MONEY_COUNTRY | The destination country is not supported for XOF mobile money transfers. | A XOF mobile money transfer was attempted to an unsupported country. |
230401 | INVALID_MOBILE_NUMBER | For XAF payouts to the Republic of the Congo MSISDN must start with `242 and contain at least 12 digits. | The provided mobile number does not meet the required format for the destination. |
301404 | TRANSFER_NOT_FOUND | The specified transfer could not be found. | The provided transfer ID does not exist. |
210400 | INVALID_CURSOR | The provided pagination cursor is invalid. | An invalid value was provided for the next parameter when listing transfers. |
212400 | MERCHANT_WALLET_NOT_FOUND | The wallet for the specified destination currency could not be found. | The requested destination currency does not have a corresponding wallet. |
213400 | UNSUPPORTED_CURRENCY_PAIRS | The specified currency pair is not supported for transfers. | The requested source and destination currencies cannot be used for the transfer. |
302400 | INVALID_TRANSFER_STATUS | The transfer cannot be updated because it is not in NEW status. | An attempt was made to update a transfer whose status is not NEW |
208400 | `INVALID_DISBURSE_ACTION | The specified disburse action is invalid. | An unsupported disburse action was provided. Supported actions are instant, deferred, scheduled, retry, and duplicate. |
304400 | TIME_LIMIT_EXCEEDED | The scheduled or deferred transfer could not be processed because its scheduled time has passed. | Processing began after the date_time specified in disburse_option. |
303400 | TRANSFER_NOT_DEFERRED_SCHEDULED. | The transfer cannot be updated because it is not deferred or scheduled. | An attempt was made to update a transfer with an action other than deferred or scheduled. |
211400 | INVALID_TRANSFER_TYPE | The specified transfer type is invalid. | The provided transfer type is not supported. |
261400 | UNABLE_TO_CONFIRM_BANK_NOT_COP_PARTICIPANT | The beneficiary bank could not be confirmed. | The beneficiary bank is not a participant in the Confirmation of Payee(COP) service. |
209400 | UNSUPPORTED_CASHPICKUP_INSTRUCTION | The cash pickup transfer request is invalid. Kindly check your payload and try again | The request payload contains a syntax error, such as a missing comma, quotation mark, or closing brace. |
232400 | UNSUPPORTED_CRYPTO_INSTRUCTION | The crypto transfer request is invalid. Kindly check your payload and try again. | The request payload contains a syntax error, such as a missing comma, quotation mark, or closing brace. |
209400 | UNSUPPORTED_MOMO_INSTRUCTION | The momo transfer request is invalid. Kindly check your payload and try again | The request payload contains a syntax error, such as a missing comma, quotation mark, or closing brace. |
203400 | UNSUPPORTED_BANK_INSTRUCTION | The bank transfer request is invalid. Kindly check your payload and try again | The request payload contains a syntax error, such as a missing comma, quotation mark, or closing brace. |
202400 | UNSUPPORTED_WALLET_INSTRUCTION | The wallet transfer request is invalid. Kindly check your payload and try again. | The request payload contains a syntax error, such as a missing comma, quotation mark, or closing brace. |
202500 | TRANSFER_HANDLER_NOT_SET | An internal error occurred while processing the transfer. Retry again later. | The transfer service is temporarily unavailable. |
10500 | INTERNAL_SERVER_ERROR | An internal error occurred while processing the request. Kindly contact support. | An unexpected error occurred while processing the request. |
253400 | MERCHANT_DOES_NOT_EXIST | The specified Merchant ID does not exist. Confirm and try again. | The provided merchant id does not exist. |
Handling Timeout Errors
In some cases, requests may timeout if there is no feedback from our servers within a period of time (usually between 25 and 28 seconds). This typically applies to charge and order requests. If you encounter a timeout with another service API, please contact our support team for assistance.
When this happens, we return a requires_requery with an HTTP 201 Created status. This indicates that the charge is being processed and should not be retried.
{
"status": "success",
"message": "Charge created",
"data": {
"id": "chg_ZWf4Kiifxx",
"amount": 250,
....
"next_action": {
"type": "requires_requery",
"requires_requery": {}
},
"payment_method_details": {
...
},
..
"status": "pending",
...
"created_datetime": "2026-05-14T13:33:15.625Z"
}
}
When you receive this response, wait 20 seconds before calling the retrieve charge/order endpoints to fetch the updated next_action object.
{
"status": "success",
"message": "Charge fetched",
"data": {
"id": "chg_tSn4fdwdwR",
"amount": 250,
...
"next_action": {
"type": "redirect_url",
"redirect_url": {
"url": "https://developersandbox.flutterwave.com/redirects?bank_account&token=eyJhbGciOiJIUzI1NiJ9.eyJjbGllbnRJZCI6IjQ0OTllNjBiLThkYzgtNDdlMy05ZDYyLWQwOTUyNjA1ZTYyOSIsImNoYXJnZUlkIjoiY2hnX3RTbjRmZHdkd1IiLCJzdWIiOiI0NDk5ZTYwYi04ZGM4LTQ3ZTMtOWQ2Mi1kMDk1MjYwNWU2MjkiLCJpYXQiOjE3NzkyMjY5MzAsImV4cCI6MTc3OTIyNzIzMH0.lnGvyF4_kWIPW_G0-qWWV1jwGeD0anmsqkXdKN58tSc"
}
},
"payment_method_details": {
"type": "bank_account",
"bank_account": {},
"id": "pmd_f5hpfzTraH",
"meta": {},
"created_datetime": "2026-05-19T21:41:57.493Z"
},
"redirect_url": "https://flutterwave.com/",
"reference": "TRN-vL11q2TcVqhc",
"status": "pending",
"processor_response": {
"type": "pending",
"code": "02"
},
"created_datetime": "2026-05-19T21:42:10.654Z"
}
}
If the retrieve request still returns a requires_requery response, retry the request in 40 seconds. Transactions that remain unresolved after a minute will transition to a failed status.
To safely retry a request, add the X-Idempotency-Key header to your request to prevent duplicate transactions.
curl --request POST \
--url 'https://developersandbox-api.flutterwave.com/charges' \
--header 'Authorization: Bearer {{ACCESS TOKEN}}' \
--header 'Content-Type: application/json' \
--header 'X-Idempotency-Key: {{X_IDEMPOTENCY_KEY}}' \
--data '{
"reference": "TRN-64OVUUz9Tul7",
"currency": "USD",
"customer_id": "cus_9zKqBW94OP",
"payment_method_id": "pmd_gZvoGry0vq",
"redirect_url":"https://flutterwave.com/",
"amount": 250,
"meta":{
"person_name": "Derek Jones",
"role": "Developer"
}
}'
Rate Limiting
We rate-limit every API endpoint to keep the platform stable and fast for everyone building on it. When these limits are exceeded, the API returns an HTTP 429 Too Many Requests response. In some cases, intermediary infrastructure such as CDNs, WAFs, or traffic protection services may return non-JSON responses (for example, HTML error pages such as Cloudflare 1015 responses) before requests reach the API origin.
Rate limits may be enforced using a combination of signals: API credentials, account identifiers, IP addresses, request volume, and concurrent request behaviour. Your integration should ensure that both request throughput and concurrent in-flight requests remain within supported limits.
The current limit is 500 API requests per minute.
Managing Rate Limits
Rate limiting should be considered as part of your service architecture and traffic management strategy. These practices reduce the likelihood of rate limiting in systems:
- Design workflows to minimise unnecessary API calls.
- Use caching and batching where appropriate to reduce the frequency of requests.
- Implement idempotency to prevent duplicates during retries.
- Always use webhooks and event-driven integrations instead of aggressive polling (this should only be considered as a last resort).
- Limit request concurrency and avoid unbounded parallel processing patterns.
- Ensure your application gracefully handles non-JSON error responses returned by intermediary systems.
Retry Strategy
If you receive an HTTP 429 Too Many Requests response or intermediary throttling responses such as Cloudflare 1015, implement a controlled retry strategy:
- Stop sending immediate follow-up requests after throttling occurs.
- Retry requests using exponential backoff with randomized jitter. For example, wait 1s, then 2s, then 4s, adding a small random offset each time so retries from multiple clients don't sync up.
- Increase the delay gradually with each attempt.
- Set retry limits to avoid infinite retry loops.
- Avoid high-frequency polling or uncontrolled concurrent retries that may continue triggering restrictions.
Retries may help recover from temporary traffic bursts. Repeated rate-limit responses usually indicate that request patterns, concurrency levels, or polling strategies should be redesigned.
Updated 3 days ago
