Payouts

Create and monitor asynchronous business payouts.

Base URL: /v1/payouts
Auth: Authorization: Bearer <secret_key>

Use payouts for controlled single or bulk disbursements that need reservation, item-level execution, reconciliation, and webhook reporting.

Recommended flow

  1. Perform name enquiry for every beneficiary.
  2. Generate a stable idempotency key for the payout request.
  3. Create the payout and store the batch and item references.
  4. Treat reserved funds as unavailable while items are pending or processing.
  5. Process item webhooks and reconcile any in-flight item before retrying.
  6. Use the final batch status to close the payout run.

Payout creation reserves the amount and calculated fee; it does not mean every item has completed.

  • create requests reserve funds immediately
  • execution happens after creation
  • fetch/list endpoints return the current payout state

Name enquiry

POST /v1/payouts/name-enquiry

Body:

{
  "bank_code": "090286",
  "account_number": "0110000000"
}

Response:

{
  "data": {
    "bank_code": "090286",
    "account_number": "0110000000",
    "account_name": "Jane Doe",
    "session_id": "session_001",
    "status": "verified"
  }
}

Create single payout

POST /v1/payouts

Note:

  • source_account_number must be a business-owned source account from bank_accounts
  • payouts do not debit from fiat_account_reserveds
  • payout eligibility is checked against the business wallets balance

Body:

{
  "reference": "payout_001",
  "source_account_number": "0111632855",
  "narration": "Vendor payout",
  "idempotency_key": "payout-001",
  "amount": 5000,
  "beneficiary": {
    "bank_code": "090286",
    "account_number": "0110000000"
  }
}

Response:

{
  "data": {
    "id": "pout_1234567890",
    "reference": "payout_001",
    "status": "pending",
    "type": "single",
    "currency": "NGN",
    "source_account_number": "0111632855",
    "total_amount": 5000,
    "total_fee": 35,
    "reserved_amount": 5035,
    "item_count": 1,
    "success_count": 0,
    "failed_count": 0,
    "items": [
      {
        "reference": "payout_001_item_123456",
        "status": "pending",
        "amount": 5000,
        "fee": 35,
        "beneficiary": {
          "bank_code": "090286",
          "account_number": "0110000000",
          "account_name": "Jane Doe"
        },
        "session_id": null,
        "last_error": null
      }
    ]
  }
}

List / fetch single payouts

GET /v1/payouts

Query:

  • id
  • uid
  • reference
  • status
  • source_account_number
  • date_from
  • date_to
  • page
  • limit

If id, uid, or reference is supplied, the endpoint returns one payout with items.

Create bulk payout

POST /v1/payouts/bulk

Note:

  • source_account_number must be a business-owned source account from bank_accounts
  • payout eligibility is checked against the business wallets balance

Body:

{
  "reference": "bulk_payout_001",
  "source_account_number": "0111632855",
  "narration": "Weekly settlements",
  "idempotency_key": "bulk-payout-001",
  "items": [
    {
      "reference": "item_001",
      "bank_code": "090286",
      "account_number": "0110000000",
      "amount": 5000
    },
    {
      "reference": "item_002",
      "bank_code": "100004",
      "account_number": "8093930950",
      "amount": 7000
    }
  ]
}

Response:

{
  "data": {
    "id": "pout_1234567890",
    "reference": "bulk_payout_001",
    "status": "pending",
    "type": "bulk",
    "currency": "NGN",
    "source_account_number": "0111632855",
    "total_amount": 12000,
    "total_fee": 80,
    "reserved_amount": 12080,
    "item_count": 2,
    "success_count": 0,
    "failed_count": 0
  }
}

List / fetch bulk payouts

GET /v1/payouts/bulk

Query:

  • id
  • uid
  • reference
  • status
  • source_account_number
  • date_from
  • date_to
  • page
  • limit

If id, uid, or reference is supplied, the endpoint returns one payout with items.

Reconcile payout

GET /v1/payouts/reconcile

Query:

  • type optional: single or bulk
  • one of:
    • id
    • uid
    • reference
    • item_reference
  • refresh
    • 1 to trigger provider status refresh for matching in-flight items

Response:

  • summary
  • payout summary and item-level execution details

Status semantics

Batch status:

  • pending
  • processing
  • successful
  • partially_successful
  • failed
  • cancelled

Item status:

  • pending
  • processing
  • successful
  • failed

Reserve rule:

  • funds are reserved logically at create time as total_amount + total_fee
  • reserve checks use the business wallets.balance
  • items move to processing after provider submit
  • reconciliation finalizes successful or failed
  • successful finalization debits wallets.balance by amount + fee
  • each finalized item releases its own reserved slice from reserved_amount