> ## Documentation Index
> Fetch the complete documentation index at: https://docs.usenumero.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Wallet-as-a-Service — Overview

> Create end-customers, give each a wallet, receive money, and move it — all through one customer model and one set of endpoints.

Wallet-as-a-Service (WaaS) lets you build wallets for your own end-users on top of Numero. You create a **customer**, give the customer one or more **wallets**, and — as the customer clears each KYC step — attach a virtual account so the wallet can receive external money, move money between wallets, pay out to banks, and link a card.

There is **one customer model** across the whole platform. The same customer you create here is the customer you attach a card to — you do not create the customer twice.

## The three objects

| Object              | What it is                                                                                                                | Addressed by                        |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------- | ----------------------------------- |
| **Customer**        | A durable record for one of your end-users. Carries identity + KYC tier.                                                  | `id` (ours) or `externalId` (yours) |
| **Wallet**          | A currency balance belonging to a customer. Usable for internal value the moment it exists — no virtual account required. | `walletReference`                   |
| **Virtual account** | A NUBAN attached to a wallet so it can receive money from **outside** Numero. Optional.                                   | `virtualAccountNumber`              |

A wallet holds four balances, always returned together:

| Balance            | Meaning                                           |
| ------------------ | ------------------------------------------------- |
| `ledgerBalance`    | Everything the wallet has, including held/pending |
| `availableBalance` | What can be spent right now (`ledger − held`)     |
| `pendingBalance`   | Inbound money awaiting settlement                 |
| `heldBalance`      | Reserved against in-flight payouts                |

<Note>
  Wallet balances are a strictly-maintained **sub-ledger** of your merchant pooled wallet. A customer wallet can never spend another customer's balance — every debit is guarded against that wallet's own available balance.
</Note>

## The KYC ladder

Capabilities unlock as the customer verifies more. You never provide more than a step needs — a wallet that only holds value asks for nothing but a name. This is the **default** ladder; the requirements and per-tier limits are configurable by your Numero admin, so what a given tier unlocks (and its transaction limits) may differ for your account.

| Tier  | Customer has verified                                                 | Unlocks                                               |
| ----- | --------------------------------------------------------------------- | ----------------------------------------------------- |
| **0** | Name + one contact (email or phone)                                   | Exist; hold a wallet; receive **internal** transfers  |
| **1** | + BVN                                                                 | Attach a virtual account → receive **external** money |
| **2** | + NIN + a government ID (passport, driver's licence, or voter's card) | Pay out to a bank; be issued a card                   |
| **3** | + address                                                             | Elevated limits                                       |

This reflects CBN's identity requirements — full identity for moving money out is **BVN and NIN and a government ID**. Each item is a real, billable verification Numero performs; a tier only rises when the check genuinely passes.

Each endpoint below states the tier it requires. Calling an endpoint above the customer's current tier returns a clear `403` telling you which step is missing — never a silent failure.

## A typical integration

```text theme={null}
1.  POST /customers                         → create the customer (tier 0)
2.  POST /customers/{id}/wallets            → create an NGN wallet (no NUBAN yet)
3.  POST /customers/{id}/kyc                → submit BVN            → customer reaches tier 1
4.  POST /wallets/{ref}/virtual-account     → attach a NUBAN       → wallet can now receive
5.  (money arrives on the NUBAN)            → lands in pendingBalance, settles to available
6.  POST /wallets/{ref}/transfer            → move to another wallet (internal, instant)
7.  POST /wallets/{ref}/payout              → send to a bank (requires tier 2)
```

## Base URL, auth, and test mode

* **Base URL:** `https://api.usenumero.com/numeroaccount`
* **Auth:** every request sends `X-Numero-Api-Key`. Money-moving `POST`s also require a request **signature** — see [Request Signing](/03-request-signing). WaaS endpoints are additionally **scope-gated**: your key must carry `customers:write`, `customer_wallet:read`, `customer_wallet:write`, and/or `kyc:write` as appropriate.
* **Test mode:** send a `test_key_…` key and everything below runs against simulated providers on an isolated test wallet — same base URL, same endpoints, live balances never touched. See [Test Mode](/05-test-mode).

Every response uses the standard envelope: `{ status, message, code, version, data, error }`.

## Webhooks

Numero emits an event to your configured webhook endpoint for every wallet action, so you don't have to poll. Each event body is `{ "event": "<name>", "data": { … } }`, where `data` is the same shape as the corresponding API response.

| Event                                      | Fires when                                             |
| ------------------------------------------ | ------------------------------------------------------ |
| `customer.kyc_updated`                     | A KYC item is verified and the customer's tier changes |
| `customer_wallet.created`                  | A wallet is created                                    |
| `customer_wallet.virtual_account_attached` | A NUBAN is attached to a wallet                        |
| `customer_wallet.credited`                 | Money lands in a wallet (inflow)                       |
| `customer_wallet.transfer`                 | A wallet-to-wallet transfer completes                  |
| `customer_wallet.payout.sent`              | A payout leaves for the beneficiary bank               |
| `customer_wallet.payout.pending`           | A payout is accepted and in flight (not yet confirmed) |
| `customer_wallet.payout.failed`            | A payout was rejected; the held funds are returned     |

A payout returns immediately in `Held`/`pending`; the `payout.sent` or `payout.failed` event tells you the final outcome once the bank transfer resolves.
