Reseller API v1

Payouts API

Send money from your wallet to any Nigerian bank account, instantly, from your own server - with its own key, an IP allow-list, limits and safe retries.

Every code block, endpoint and section has a Copy button.

Before you start

Pay out from your PowerWave wallet to any Nigerian bank account, instantly, from your own server. Payouts are not part of the normal API key: you need payout access and a separate payout key (pw_payout_…).

  1. Be a reseller at Tier 3 (an approved reseller business).
  2. Get payout access: contact support (ticket or chat) and explain how you will use payouts. Our team approves each reseller.
  3. Create your payout key in your dashboard (Reseller → Payout API). You must list the IP addresses of your server: the key works only from those IPs. It is shown once.

Every call below uses Authorization: Bearer pw_payout_… (the examples read it from the PW_PAYOUT_KEY environment variable).

Limits & fee

  • Limits: each reseller has a maximum per payout and per day (defaults ₦500,000.00 and ₦2,000,000.00; minimum ₦100.00). A payout over a limit is refused immediately (per_request_limit_exceeded / daily_limit_exceeded) - nothing is sent or charged. Only PowerWave can raise your limits.
  • Fee: ₦100.00 per payout, charged on top of the amount from your wallet. A failed payout is refunded in full, fee included.
  • Speed: a payout is debited and sent in the same request. There is no review queue.

Endpoints

GET/v1/payouts/banks

List banks

Our cached bank list (refreshed daily). Use bank_code in the calls below. No live lookup per request.

curl "https://api.powerwave.ng/v1/payouts/banks" \
  -H "Authorization: Bearer $PW_PAYOUT_KEY"
Response data
{
    "banks": [
        {
            "bank_code": "BANK-CODE-FROM-LIST",
            "name": "Example Bank",
            "nip_code": "000014",
            "sort_code": "044"
        }
    ],
    "count": 575
}
POST/v1/payouts/validate

Validate a bank account

Look up the account holder's name at the bank. Always check the name before paying. (Live check, 20 per minute.)

ParameterDescription
bank_coderequired
from GET /payouts/banks
account_numberrequired
10-digit account number
curl -X POST "https://api.powerwave.ng/v1/payouts/validate" \
  -H "Authorization: Bearer $PW_PAYOUT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"bank_code":"BANK-CODE-FROM-LIST","account_number":"0123456789"}'
Response data
{
    "bank_code": "BANK-CODE-FROM-LIST",
    "bank_name": "Example Bank",
    "account_number": "0123456789",
    "account_name": "ADAEZE OKAFOR"
}
POST/v1/payouts

Send a payout

Send money from your wallet to a bank account, instantly. Debits the amount plus the payout fee and sends in the same request.

ParameterDescription
referencerequired
your unique ID for this payout (6-64 characters: letters, numbers, . - _)
bank_coderequired
from GET /payouts/banks
account_numberrequired
10-digit account number
amountrequired
naira, e.g. "25000" (at most 2 decimals)
account_nameoptional
the name you checked with /payouts/validate, kept on the record
curl -X POST "https://api.powerwave.ng/v1/payouts" \
  -H "Authorization: Bearer $PW_PAYOUT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"reference":"PAYOUT-7781","bank_code":"BANK-CODE-FROM-LIST","account_number":"0123456789","amount":"25000","account_name":"ADAEZE OKAFOR"}'
Response data
{
    "reference": "PAYOUT-7781",
    "status": "successful",
    "amount": "25000.00",
    "fee": "100.00",
    "total": "25100.00",
    "currency": "NGN",
    "bank_code": "BANK-CODE-FROM-LIST",
    "bank_name": "Example Bank",
    "account_number": "0123456789",
    "account_name": "ADAEZE OKAFOR",
    "transaction_ref": "PW8K2J4L9QXA",
    "failure_reason": null,
    "created_at": "2026-10-28T15:04:11+01:00",
    "completed_at": "2026-10-28T15:04:13+01:00"
}
  • status is successful, failed (not sent, wallet refunded in full) or processing (the bank has not confirmed yet - never send it again; wait for the webhook or poll the status).
  • The same reference with the same details returns the original payout (Idempotent-Replay: true); different details = 409 idempotency_conflict.
GET/v1/payouts/{reference}

Get a payout

The current state of one of your payouts, by YOUR reference.

curl "https://api.powerwave.ng/v1/payouts/{reference}" \
  -H "Authorization: Bearer $PW_PAYOUT_KEY"
Response data
{
    "reference": "PAYOUT-7781",
    "status": "successful",
    "amount": "25000.00",
    "fee": "100.00",
    "total": "25100.00",
    "currency": "NGN",
    "bank_code": "BANK-CODE-FROM-LIST",
    "bank_name": "Example Bank",
    "account_number": "0123456789",
    "account_name": "ADAEZE OKAFOR",
    "transaction_ref": "PW8K2J4L9QXA",
    "failure_reason": null,
    "created_at": "2026-10-28T15:04:11+01:00",
    "completed_at": "2026-10-28T15:04:13+01:00"
}

Statuses & safe retries

statusMeaningWhat to do
successfulSent.Done.
failedNot sent. Your wallet was refunded in full (amount and fee).Fix the cause (failure_reason) and send a new payout with a new reference.
processingThe bank has not confirmed yet (this can happen when the network is slow).Do not send it again and do not assume it failed. Wait for the webhook or poll GET /payouts/{reference}; it settles on its own.
  • Re-sending the same reference with the same details never pays twice: you get the original payout back (Idempotent-Replay: true). The same reference with different details is 409 idempotency_conflict. If your request times out, retry with the same reference.
  • Always call POST /payouts/validate first and compare the account name before you pay.

Payout errors

HTTPerror.codeMeaning
401unauthorizedMissing, malformed, wrong or revoked payout key.
403ip_not_allowed / ip_allowlist_requiredThe key was used from an IP that is not on its allow-list, or it has no allowed IP at all.
403payout_not_allowedPayout access is not approved for your account, your tier is too low, or the account is restricted.
409idempotency_conflictThat reference was used with different details.
422insufficient_fundsWallet balance is below the amount plus the fee.
422invalid_bank / ambiguous_bank_code / invalid_accountUnknown bank code, a code shared by several banks (use the bank_code from the list), or an account that could not be verified.
422amount_too_low / per_request_limit_exceeded / daily_limit_exceeded / validation_errorThe amount is outside your limits, or a field is missing or invalid.
429rate_limitedToo many requests; see Retry-After.
503service_unavailablePayouts are paused or the provider is unavailable. Nothing was charged.

Payout webhooks

When the result is final we send payout.successful or payout.failed to the webhook URL of your oldest approved business that has one. Payload and signature checking: Webhooks.

Questions? Contact us.