Flutterwave (v3) · Error reference
Flutterwave API Errors and Statuses Explained (v3)
Flutterwave's v3 API marks every error body with "status": "error" and a message, and reports what happened to a charge or transfer in data.status.
Have a response you don't understand? Paste it into the Payment Error Code Lookup and it finds every known code inside.
How Flutterwave reports errors
- Rejected requests come back with an HTTP status (400, 401, 500, 503) and a body with "status": "error" and a message. Some also carry a code, such as app_error.
- Charge outcomes come from GET /v3/transactions/:id/verify. Only "successful" means paid.
- Transfer outcomes come from the transfer.completed webhook (sent for both success and failure) and GET /v3/transfers/:id: NEW, PENDING, SUCCESSFUL or FAILED, with the reason in complete_message.
How sure is this?
Each code below is labelled by how well it is documented. All 11 codes on this page come from Flutterwave's own documentation, linked under each one. Log the full response anyway: messages change.
Payment outcomes
The status values that tell you whether the customer paid.
WaitingSeen in: Status / callbackRetry: No, fix the cause firstIn the provider's docs
The create transfer response (HTTP 200). Flutterwave queued the transfer, usually with status NEW. Nothing has been paid yet.
What to do
- Save data.id: you need it to look the transfer up. Wait for the transfer.completed webhook.
Sources: Flutterwave v3 docs: transfers
NEW Transfer created
WaitingSeen in: Status / callbackRetry: No, fix the cause firstIn the provider's docs
The first status of a transfer. complete_message is empty. Not final.
What to do
- Wait for the transfer.completed webhook or check GET /v3/transfers/:id later.
Sources: Flutterwave v3 docs: transfers
pending Still processing
WaitingSeen in: Status / callbackRetry: No, fix the cause firstIn the provider's docs
A transfer shows PENDING with "Transaction is currently being processed". Not final.
What to do
- Wait for the webhook. Don't create a new transfer for the same payout.
Sources: Flutterwave v3 docs: transfers
successful Paid / transfer successful
PaidSeen in: Status / callbackRetry: not neededIn the provider's docs
Charges show "successful" from verify; transfers show SUCCESSFUL with "Transaction was successful.". The only status that means the money moved.
What to do
- For a charge, check the amount, currency and tx_ref match your order before giving value.
Sources: Flutterwave v3 docs: transaction verification · Flutterwave v3 docs: transfers
Failure reasons
Why a payment did not go through.
Not paidSeen in: Status / callbackRetry: Yes, as a new requestIn the provider's docs
The charge or transfer failed. For a transfer, complete_message gives the reason, for example "Account resolve failed."
How to fix it
- Mark it not paid. Fix the cause in complete_message (often a wrong account or number) before creating a new transfer.
What to tell the customer
Your payment didn't go through. Please try again.
Sources: Flutterwave v3 docs: transfers
Request errors
Returned straight away when the API rejects your request.
HTTP 400 Validation error
Request errorSeen in: API responseRetry: No, fix the cause firstIn the provider's docs
The request failed validation. The message names the problem, for example "Cardno is required".
How to fix it
- Fix the field named in message and send again.
Sources: Flutterwave docs: errors
HTTP 401 Authorization required
Request errorSeen in: API responseRetry: No, fix the cause firstIn the provider's docs
The message is "Authorization required": the secret key is missing or wrong.
How to fix it
- Send Authorization: Bearer <secret-key> with your secret key, from the same mode (test or live) you are working in.
Sources: Flutterwave docs: errors
Not known yetSeen in: API responseRetry: Check the status before retryingIn the provider's docs
An error on Flutterwave's side. For a charge or transfer you can't tell whether it went through.
How to fix it
- Query the transaction or transfer before retrying.
- If the body has an error_id, include it when you contact support.
Sources: Flutterwave docs: errors · Flutterwave v3 docs: handling error timeouts
HTTP 503 Timeout (may still be processing)
Not known yetSeen in: API responseRetry: Check the status before retryingIn the provider's docs
Flutterwave timed out after about 28 seconds. The charge or transfer may still be processing.
How to fix it
- Query the status before retrying: GET /v3/transactions/:id/verify for a charge, GET /v3/transfers/:id for a transfer.
- Retry only if nothing is found.
Sources: Flutterwave v3 docs: handling error timeouts
Not known yetSeen in: API responseRetry: Check the status before retryingIn the provider's docs
Comes with HTTP 500 and the message "Application error. Please contact support", plus an error_id.
How to fix it
- Check the charge or transfer status before retrying.
- Contact Flutterwave support with the error_id.
Sources: Flutterwave docs: errors
Not paidSeen in: API responseRetry: Yes, as a new requestIn the provider's docs
Returned by verify with "status": "error" and data: null. Flutterwave has no transaction with that ID.
How to fix it
- Check you are sending the transaction ID (data.id), not your tx_ref.
- After a timeout, not found means it was not created, so you can retry.
Sources: Flutterwave v3 docs: transaction verification · Flutterwave v3 docs: handling error timeouts
Handle every code in your code
Map each outcome code to one of four actions. Unknown codes fall back to "check the status", so a new or misspelled code never fulfils or cancels an order by accident.
// What to do with each Flutterwave (v3) outcome code.
// Unknown codes fall back to "check_status": never fulfil or fail an order on a code you don't recognise.
const ACTIONS = {
"NEW": "wait", // Transfer created
"PENDING": "wait", // Still processing
"SUCCESSFUL": "fulfil", // Paid / transfer successful
"FAILED": "mark_failed", // Failed
};
export function flutterwaveNextStep(code) {
const key = String(code ?? "").trim().toUpperCase().replace(/[\s-]+/g, "_");
return ACTIONS[key] ?? "check_status";
}
// Example:
// switch (flutterwaveNextStep(verified.data.status)) {
// case "fulfil": // verify amount, then mark the order paid (idempotently)
// case "mark_failed": // mark unpaid, show a retry button
// case "wait": // do nothing yet; a callback or your poller will follow
// case "check_status": // ask the status endpoint before deciding
// }
Frequently asked questions
What does Flutterwave error HTTP 503 mean?
HTTP 503 (Timeout (may still be processing)): Flutterwave timed out after about 28 seconds. The charge or transfer may still be processing. Query the status before retrying: GET /v3/transactions/:id/verify for a charge, GET /v3/transfers/:id for a transfer.
What does Flutterwave error app_error mean?
app_error (Application error): Comes with HTTP 500 and the message "Application error. Please contact support", plus an error_id. Check the charge or transfer status before retrying.
What does Flutterwave error No transaction was found for this id mean?
No transaction was found for this id (Transaction not found): Returned by verify with "status": "error" and data: null. Flutterwave has no transaction with that ID. Check you are sending the transaction ID (data.id), not your tx_ref.
What does Flutterwave status NEW mean?
NEW (Transfer created): The first status of a transfer. complete_message is empty. Not final. Wait for the transfer.completed webhook or check GET /v3/transfers/:id later.
What does Flutterwave status failed mean?
failed (Failed): The charge or transfer failed. For a transfer, complete_message gives the reason, for example "Account resolve failed." Mark it not paid. Fix the cause in complete_message (often a wrong account or number) before creating a new transfer.
Integration guides
Full Flutterwave integrations that handle these codes: Flutterwave Webhook Checker, Flutterwave mobile money in Node.js, Laravel, Django, Flutterwave payouts in Node.js.
Checked November 2026. Error codes change. If you see one that's missing or wrong, please let me know.