Skip to content

Paystack · Error reference

Paystack API Errors and Transaction Statuses Explained

Paystack reports problems with an HTTP status code and an error type, and reports what happened to a payment or transfer as a status word such as success, abandoned or reversed.

Have a response you don't understand? Paste it into the Payment Error Code Lookup and it finds every known code inside.

How Paystack reports errors

  • Rejected requests come back with an HTTP status (400, 401, 404, 5xx), "status": false, a message, and an error type and code such as validation_error and missing_params.
  • Charge and verify requests always return HTTP 200. Whether the customer paid is in data.status, not the HTTP status.
  • Transfer (payout) outcomes arrive in transfer webhooks and from the fetch and verify transfer endpoints as data.status: pending, otp and received are not final; the rest are.

How sure is this?

Each code below is labelled by how well it is documented. All 19 codes on this page come from Paystack'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.

pay_offline Waiting for the customer to approve

WaitingSeen in: Status / callbackRetry: No, fix the cause firstIn the provider's docs

Returned by a mobile money charge: the customer must approve the payment on their phone. They have 180 seconds.

What to do

  • Show data.display_text to the customer.
  • Wait for the charge.success webhook, and verify the reference after the 180 seconds. If it isn't success, data.message says why.

What to tell the customer

Check your phone and approve the payment to continue.

Sources: Paystack docs: payment channels (mobile money)

pending Still processing

WaitingSeen in: Status / callbackRetry: No, fix the cause firstIn the provider's docs

The charge or transfer is still being processed. Not final.

What to do

  • Wait for the webhook and check again later. Do not retry or mark it failed yet.

Sources: Paystack docs: how transfers work

otp Transfer needs OTP approval

WaitingSeen in: Status / callbackRetry: No, fix the cause firstIn the provider's docs

The transfer needs an extra approval step: a one-time code sent to your email or phone. Not final. If the code isn't used within 30 minutes the transfer becomes abandoned; a wrong code makes it failed.

What to do

  • Approve it with the OTP, or check which approval steps are turned on for transfers in your Paystack dashboard.
  • Paystack recommends turning on both email and phone channels so the code arrives.

Sources: Paystack docs: how transfers work

received Transfer waiting for your server's approval

WaitingSeen in: Status / callbackRetry: No, fix the cause firstIn the provider's docs

The transfer needs your server to approve it, and Paystack has sent the approval request. Not final.

What to do

  • Make sure your transfer approval URL answers quickly. No answer makes the transfer blocked; a decline makes it rejected.

Sources: Paystack docs: how transfers work

success Paid / transfer processed

PaidSeen in: Status / callbackRetry: not neededIn the provider's docs

For a charge, the customer paid. For a transfer, Paystack processed it, which does not always mean the money has reached the customer yet.

What to do

  • For a charge, check the amount and currency match your order before giving value.
  • For a transfer, keep listening: a later transfer.reversed event can still return the money to your balance.

Sources: Paystack docs: how transfers work · Paystack docs: payment channels (mobile money)

Failure reasons

Why a payment did not go through.

reversed Reversed, money returned

Not paidSeen in: Status / callbackRetry: Later, it is temporaryIn the provider's docs

For a transfer: it could not be completed and the amount went back to your Paystack balance, typically because the recipient's bank or wallet couldn't receive money then. It can follow an earlier success. For a charge: the payment was reversed.

How to fix it

  • Mark the payout as not paid and retry later. Reuse the same reference only for a transfer with no final status; a reversed one is final.

Sources: Paystack docs: how transfers work

failed Failed

Not paidSeen in: Status / callbackRetry: Yes, as a new requestIn the provider's docs

The charge or transfer could not be processed. Final.

How to fix it

  • For a charge, read data.message from verify for the reason and let the customer try again.
  • For a transfer, you can retry it.

What to tell the customer

Your payment didn't go through. Please try again.

Sources: Paystack docs: how transfers work · Paystack docs: payment channels (mobile money)

abandoned Abandoned

Not paidSeen in: Status / callbackRetry: Yes, as a new requestIn the provider's docs

For a charge, the customer didn't complete it. For a transfer, the OTP wasn't given in time, and it won't be processed.

How to fix it

  • Mark it not paid. Let the customer start again, or create a new transfer.

Sources: Paystack docs: how transfers work

blocked Transfer blocked (no approval answer)

Not paidSeen in: Status / callbackRetry: Yes, as a new requestIn the provider's docs

Your server didn't respond to Paystack's transfer approval request. Final.

How to fix it

  • Check your approval URL is reachable and answers fast, then send a new transfer.

Sources: Paystack docs: how transfers work

rejected Transfer rejected by your server

Not paidSeen in: Status / callbackRetry: No, fix the cause firstIn the provider's docs

Your server declined the transfer approval request. Final.

How to fix it

  • If you didn't mean to decline it, check the rules in your approval handler.

Sources: Paystack docs: how transfers work

Request errors

Returned straight away when the API rejects your request.

HTTP 200 Request worked (check data.status)

Not known yetSeen in: API responseRetry: Check the status before retryingIn the provider's docs

Paystack always returns 200 for charge and verify requests, whatever happened to the payment. A 200 alone does not mean the customer paid.

How to fix it

  • Read data.status. Treat the payment as paid only when verify returns success and the amount and currency match your order.

Sources: Paystack docs: errors

HTTP 400 Validation or client error

Request errorSeen in: API responseRetry: No, fix the cause firstIn the provider's docs

A validation or client side error: the request was not carried out. Usually a missing or badly formatted field.

How to fix it

  • Read message and, when present, meta.nextStep: Paystack puts the suggested fix there.
  • Check amounts are in subunits (pesewas, cents) as whole numbers.

Sources: Paystack docs: errors

HTTP 401 Not authorized

Request errorSeen in: API responseRetry: No, fix the cause firstIn the provider's docs

The request was not authorized: the secret key is missing or invalid.

How to fix it

  • Send Authorization: Bearer <secret-key>, with your secret key (sk_test_ or sk_live_), never the public key.
  • Use the key from the same mode (test or live) as the data you are working with.

Sources: Paystack docs: errors

HTTP 404 Resource not found

Request errorSeen in: API responseRetry: No, fix the cause firstIn the provider's docs

The thing you asked for does not exist, for example a reference Paystack has never seen.

How to fix it

  • Check the reference or ID, and that it belongs to the same mode (test or live) as your key.
  • If you are verifying a charge you started an hour or more ago and it is still not found, nothing was charged.

Sources: Paystack docs: errors

HTTP 500 Error on Paystack's side (5xx)

Not known yetSeen in: API responseRetry: Check the status before retryingIn the provider's docs

Any 5xx status: the request could not be completed because of an error on Paystack's end. For a charge or a transfer you can't tell whether it went through.

How to fix it

  • Verify the charge, or fetch the transfer by its reference, before trying again.
  • If you retry a transfer, reuse the same reference so it can never be sent twice.
  • Paystack asks you to report 5xx errors to them.

Sources: Paystack docs: errors · Paystack docs: how transfers work

api_error Error type: Paystack API

Request errorSeen in: API responseRetry: Check the status before retryingIn the provider's docs

The error happened on the Paystack API itself, not because of your data.

How to fix it

  • Check the charge or transfer status before retrying, then retry with backoff.
  • If it keeps happening, report it to Paystack with the full response.

Sources: Paystack docs: errors

validation_error Error type: invalid data

Request errorSeen in: API responseRetry: No, fix the cause firstIn the provider's docs

The error is caused by invalid data in your request.

How to fix it

  • Read code, message and meta.nextStep in the response, fix the field, then send again.

Sources: Paystack docs: errors

processor_error Error type: payment processor

Request errorSeen in: API responseRetry: Check the status before retryingIn the provider's docs

The error comes from the payment processor or gateway behind Paystack (for mobile money, the network operator).

How to fix it

  • Verify the charge before deciding: do not let the customer pay twice.
  • Log the full response; the message usually says what the processor returned.

Sources: Paystack docs: errors

missing_params Required field missing

Request errorSeen in: API responseRetry: No, fix the cause firstIn the provider's docs

A required parameter is missing. Paystack's example is "Email Address is required", with the next step "Provide all required params".

How to fix it

  • Add the field named in message. Charges need email and amount; mobile money charges also need mobile_money.phone and mobile_money.provider.

Sources: Paystack docs: errors · Paystack docs: payment channels (mobile money)

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 Paystack outcome code.
// Unknown codes fall back to "check_status": never fulfil or fail an order on a code you don't recognise.
const ACTIONS = {
  "PAY_OFFLINE": "wait", // Waiting for the customer to approve
  "PENDING": "wait", // Still processing
  "OTP": "wait", // Transfer needs OTP approval
  "RECEIVED": "wait", // Transfer waiting for your server's approval
  "SUCCESS": "fulfil", // Paid / transfer processed
  "REVERSED": "mark_failed", // Reversed, money returned
  "FAILED": "mark_failed", // Failed
  "ABANDONED": "mark_failed", // Abandoned
  "BLOCKED": "mark_failed", // Transfer blocked (no approval answer)
  "REJECTED": "mark_failed", // Transfer rejected by your server
};

export function paystackNextStep(code) {
  const key = String(code ?? "").trim().toUpperCase().replace(/[\s-]+/g, "_");
  return ACTIONS[key] ?? "check_status";
}

// Example:
// switch (paystackNextStep(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 Paystack status abandoned mean?

abandoned (Abandoned): For a charge, the customer didn't complete it. For a transfer, the OTP wasn't given in time, and it won't be processed. Mark it not paid. Let the customer start again, or create a new transfer.

What does Paystack status reversed mean?

reversed (Reversed, money returned): For a transfer: it could not be completed and the amount went back to your Paystack balance, typically because the recipient's bank or wallet couldn't receive money then. It can follow an earlier success. For a charge: the payment was reversed. Mark the payout as not paid and retry later. Reuse the same reference only for a transfer with no final status; a reversed one is final.

What does Paystack status pay_offline mean?

pay_offline (Waiting for the customer to approve): Returned by a mobile money charge: the customer must approve the payment on their phone. They have 180 seconds. Show data.display_text to the customer.

What does Paystack status otp mean?

otp (Transfer needs OTP approval): The transfer needs an extra approval step: a one-time code sent to your email or phone. Not final. If the code isn't used within 30 minutes the transfer becomes abandoned; a wrong code makes it failed. Approve it with the OTP, or check which approval steps are turned on for transfers in your Paystack dashboard.

What does Paystack error HTTP 401 mean?

HTTP 401 (Not authorized): The request was not authorized: the secret key is missing or invalid. Send Authorization: Bearer <secret-key>, with your secret key (sk_test_ or sk_live_), never the public key.

Integration guides

Full Paystack integrations that handle these codes: Paystack Webhook Checker, Paystack mobile money in Node.js, Laravel, Django, Paystack payouts in Node.js.

Checked November 2026. Error codes change. If you see one that's missing or wrong, please let me know.

Need this built for you?

I integrate MTN MoMo, M-Pesa and Airtel Money into Laravel / PHP, Python / Django, Node.js / Next.js apps: payments, callbacks, payouts and go-live, with tests.