Wallets

Multi-currency balances + ledger history. Each merchant has one wallet per (currency, env) combo.

The wallet object

{
  "object": "wallet",
  "id": "ckxxxxxxxxxxxxxxxxxx",
  "currency": "NGN",
  "env": "live",
  "available_balance_minor": "1234567890",
  "pending_out_minor": "0",
  "is_active": true,
  "is_frozen": false,
  "is_demo": false,
  "created_at": "2026-01-15T10:00:00Z",
  "updated_at": "2026-05-05T12:34:56Z",
  "virtual_accounts": [
    {
      "provider": "monnify",
      "account_number": "8001234567",
      "bank_name": "Moniepoint Microfinance Bank",
      "bank_code": "50515",
      "account_name": "TECHNEST/ACME LIMITED",
      "status": "active"
    }
  ]
}

Field notes:

  • pending_out_minor is the BigInt sum of in-flight payouts (status queued or processing) that have already debited the wallet. Subtract from available_balance_minor to get the post-dispatch projected balance.
  • is_demo is only present on the single-wallet retrieve endpoint, not the list. It marks sandbox-auto-provisioned demo wallets seeded with starter balances.
  • virtual_accounts[] lists the funding accounts merchants can pay INTO. Customer-level Blaaiz VIBANs (per-end-user GBP/USD/EUR) are filtered out — those belong to a single end-user and live under GET /v1/customers/{id}/virtual_accounts.

List wallets

GET /v1/wallets

Returns every wallet for the current API key’s env.

curl https://api.swappr.me/v1/wallets \
  -H "Authorization: Bearer sk_test_..."

Retrieve a wallet

GET /v1/wallets/{id}

curl https://api.swappr.me/v1/wallets/ckwallet_xxx \
  -H "Authorization: Bearer sk_test_..."

Get wallet balance

GET /v1/wallets/{id}/balance

Lightweight point-in-time balance — no ledger history. Use this when you only need the balance and want the smallest possible response.

Response

{
  "object": "wallet_balance",
  "wallet_id": "ckwallet_xxx",
  "currency": "NGN",
  "env": "live",
  "available_balance_minor": "1234567890",
  "pending_out_minor": "0",
  "fetched_at": "2026-05-05T12:34:56Z"
}

pending_out_minor is the BigInt sum of in-flight payouts (queued + processing) that have already debited the wallet. The “post-dispatch projected balance” is available_balance_minor − pending_out_minor. fetched_at is a server-side stamp so a 200 response always carries the time the balance was read.


Summary balances

GET /v1/balances

Single-call summary across every wallet the merchant has. Useful for dashboards. Faster than GET /v1/wallets when you don’t need the assigned virtual accounts.

{
  "object": "list",
  "data": [
    {
      "object": "balance",
      "wallet_id": "ckwallet_ngn",
      "currency": "NGN",
      "env": "live",
      "available_balance_minor": "1234567890",
      "pending_out_minor": "0",
      "is_active": true,
      "is_frozen": false
    },
    {
      "object": "balance",
      "wallet_id": "ckwallet_gbp",
      "currency": "GBP",
      "env": "live",
      "available_balance_minor": "5000000",
      "pending_out_minor": "0",
      "is_active": true,
      "is_frozen": false
    }
  ],
  "fetched_at": "2026-05-05T12:34:56Z"
}

List wallet transactions

GET /v1/wallets/{id}/transactions

Full ledger history. Every wallet movement, in order, with running balance.

Query params

ParamNotes
limit1-100, default 50
starting_afterCursor
sourceFilter to one ledger source (e.g. payout_debit, virtual_account_credit)
directioncredit | debit

Response

{
  "object": "list",
  "has_more": true,
  "data": [
    {
      "object": "wallet_transaction",
      "id": "ckledger_xxx",
      "direction": "debit",
      "amount_minor": "500000",
      "currency": "NGN",
      "source": "payout_debit",
      "description": "Paid ADAEZE BLESSING NWAFOR",
      "balance_after_minor": "999500075",
      "source_ref_type": "Payout",
      "source_ref_id": "ckpayout_xxx",
      "created_at": "2026-05-05T12:34:56Z"
    }
  ]
}

To follow the source — e.g. fetch the originating Payout — combine source_ref_type + source_ref_id and call the matching endpoint (GET /v1/payouts/{source_ref_id} here).

Ledger sources

Common sources you’ll see:

  • virtual_account_credit — VA inflow
  • virtual_account_credit_fee — Merchant fee on VA inflow
  • payout_debit — Payout debited from wallet
  • payout_fee — Payout fee charged
  • payout_reversal — Refund of failed payout principal
  • payout_fee_reversal — Refund of fee on auto-reversed payout
  • admin_credit — Admin top-up
  • admin_debit — Admin debit (rare)
  • promotional_credit — Promotional credit
  • reconciliation_adjust — Reconciliation entry
  • stamp_duty_collected — NGN stamp duty (₦50 on payouts ≥ ₦10k)
  • fx_conversion — FX conversion leg

List funding events

GET /v1/wallets/{id}/funding-events

Inflow-only subset of the ledger — filtered to credit-direction sources that represent money landing in the wallet from external sources. Each row carries a top-level sender block when the underlying VA webhook captured the remitter’s identity.

Query params

ParamNotes
limit1-100, default 50
starting_afterCursor

Filtered sources

  • virtual_account_credit — VA payment from a 3rd-party bank
  • admin_credit — Top-up by Technest staff
  • promotional_credit — Promotional grant
  • reconciliation_adjust — Reconciliation entry
  • demo_seed — Sandbox auto-provisioned starter balance (sandbox only)
  • demo_self_fund — Sandbox merchant self-fund (sandbox only)

(Excludes payout_reversal — that’s a refund of money the merchant originally sent, not new inflow.)

Response

{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "object": "wallet_funding_event",
      "id": "ckledger_xxx",
      "direction": "credit",
      "amount_minor": "5000000",
      "currency": "NGN",
      "source": "virtual_account_credit",
      "description": "Inflow ₦5,000.00 NGN from ADAEZE OKONKWO",
      "balance_after_minor": "1239567890",
      "source_ref_type": "ProviderEvent",
      "source_ref_id": "ckevt_xxx",
      "sender": {
        "name": "ADAEZE OKONKWO",
        "account_number": "0123456789",
        "bank_code": "058",
        "bank_name": "Guaranty Trust Bank"
      },
      "created_at": "2026-05-05T12:34:56Z"
    }
  ]
}

When the underlying webhook didn’t capture sender info (e.g. admin top-ups, demo seeds), sender is null.