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

# Managing customers in the Dubu Pay API

> Learn how customer objects represent your end users, how KYC tiers work, and how customers connect to virtual accounts, balances, and ledger history.

A **customer** in Dubu Pay represents one of your end users — the individual who pays money into a virtual account, accumulates a balance, or receives funds. You create and manage customers through the API; Dubu Pay stores them on your behalf, scoped entirely to your merchant account. Every virtual bank account, deposit record, balance entry, and ledger line is tied to a customer, so creating customers before issuing accounts is the recommended starting point for any integration.

## The customer object

When you create or retrieve a customer, the API returns an object with the following shape:

```json theme={null}
{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "email": "ada@example.com",
  "first_name": "Ada",
  "last_name": "Lovelace",
  "kyc_tier": "TIER_1",
  "created_at": "2025-01-15T09:00:00Z",
  "updated_at": "2025-01-15T09:00:00Z"
}
```

| Field        | Type     | Description                                                              |
| ------------ | -------- | ------------------------------------------------------------------------ |
| `id`         | UUID     | Unique identifier for the customer. Use this in all subsequent requests. |
| `email`      | string   | Customer email address. Must be unique within your merchant account.     |
| `first_name` | string   | Given name (1–100 characters).                                           |
| `last_name`  | string   | Family name (1–100 characters).                                          |
| `kyc_tier`   | string   | Current verification level: `UNVERIFIED`, `TIER_1`, or `TIER_2`.         |
| `created_at` | ISO 8601 | Timestamp when the customer was created.                                 |
| `updated_at` | ISO 8601 | Timestamp of the most recent change.                                     |

## KYC tiers

Dubu Pay uses a two-tier KYC system. Each tier unlocks additional account features and higher transaction limits.

<Tabs>
  <Tab title="Tier 1 — Basic identity">
    Tier 1 verifies a customer's identity using their BVN (Bank Verification Number) and a selfie image. You submit both when calling `POST /customers/:id/tier1-verification`.

    **What you need:**

    * `bvn` — exactly 11 digits
    * `image_url` — a URL pointing to the customer's selfie

    **What it unlocks:**

    * Issuing NGN virtual bank accounts (onramps)
    * Standard deposit limits

    <Note>
      You can also initiate KYC via `POST /customers/:id/kyc/initiate` if you want Dubu Pay to drive the verification flow on your behalf — just supply the customer's BVN.
    </Note>
  </Tab>

  <Tab title="Tier 2 — Advanced identity">
    Tier 2 collects a full identity profile including residential address, nationality, date of birth, a government-issued ID document, and source-of-funds information. Submit it via `POST /customers/:id/tier2-verification`.

    **What you need:**

    * `residential_address` — street, city, subdivision, postal code, and ISO 3166-1 alpha-3 country code
    * `nationality` — ISO 3166-1 alpha-3 country code
    * `birth_date` — `YYYY-MM-DD` format
    * `identifying_information` — at least one document of type `passport`, `drivers_license`, or `national_id`, with `image_front` and expiration date
    * `source_of_funds` — one of: `salary`, `savings`, `company_funds`, `investments_loans`, `inheritance`, and others
    * `account_purpose` — e.g. `ecommerce_retail_payments`, `receive_payment_for_freelancing`
    * `expected_monthly_payments_usd` — one of `0_4999`, `5000_9999`, `10000_49999`, `50000_plus`
    * `employment_status` and `most_recent_occupation`
    * `acting_as_intermediary` — boolean, must be `false` for standard merchant use

    **What it unlocks:**

    * Permanent NGN virtual bank accounts (no expiry)
    * Higher transaction and balance limits

    <Warning>
      All Tier 2 document images must be hosted at publicly accessible URLs. Dubu Pay fetches them during verification — do not use presigned URLs that expire quickly.
    </Warning>
  </Tab>
</Tabs>

## Customer lifecycle

<Steps>
  <Step title="Create the customer">
    Call `POST /customers` with the customer's `email`, `first_name`, and `last_name`. You receive a customer `id` in the response.

    ```bash theme={null}
    curl -X POST https://api.dubupay.com/api/v1/customers \
      -H "X-Api-Key: dubu_sk_live_..." \
      -H "Content-Type: application/json" \
      -d '{"email": "ada@example.com", "first_name": "Ada", "last_name": "Lovelace"}'
    ```
  </Step>

  <Step title="Submit KYC verification">
    Submit Tier 1 verification to unlock virtual account issuance. Pass the customer's BVN and a selfie URL.

    ```bash theme={null}
    curl -X POST https://api.dubupay.com/api/v1/customers/{id}/tier1-verification \
      -H "X-Api-Key: dubu_sk_live_..." \
      -H "Content-Type: application/json" \
      -d '{"bvn": "12345678901", "image_url": "https://cdn.example.com/selfie.jpg"}'
    ```
  </Step>

  <Step title="Issue a virtual account">
    Once the customer is verified, create an NGN virtual bank account for them via `POST /customers/{id}/ngn-virtual-account`. For a permanent account, the customer must be Tier 2 verified.
  </Step>

  <Step title="Track balance and ledger">
    Poll `GET /customers/{id}/balance` to see the customer's current USDT balance, or `GET /customers/{id}/ledger` to retrieve a full transaction history.
  </Step>
</Steps>

## How customers relate to other resources

Each customer can have:

* **One permanent NGN virtual account** — linked for receiving deposits long-term
* **Multiple temporary virtual accounts** — short-lived accounts tied to a specific payment
* **Crypto wallets** — destination addresses on supported chains (APTOS, BASE, CELO, ETHEREUM, POLYGON, SOLANA, TRON)
* **A balance** — aggregated USDT value of settled deposits
* **A ledger** — paginated chronological record of all credits and debits

<Tip>
  Store the customer `id` in your own database alongside your internal user record. You will use it for every subsequent Dubu Pay operation — issuing accounts, checking balances, and retrieving ledger history.
</Tip>

## Endpoint overview

| Method  | Path                                 | Description                                                  |
| ------- | ------------------------------------ | ------------------------------------------------------------ |
| `POST`  | `/customers`                         | Create a new customer                                        |
| `GET`   | `/customers`                         | List customers (supports `email`, `limit`, `cursor` filters) |
| `GET`   | `/customers/:id`                     | Retrieve a single customer                                   |
| `PATCH` | `/customers/:id`                     | Update `first_name` or `last_name`                           |
| `POST`  | `/customers/:id/tier1-verification`  | Submit Tier 1 KYC (BVN + selfie)                             |
| `POST`  | `/customers/:id/tier2-verification`  | Submit Tier 2 KYC (full identity profile)                    |
| `POST`  | `/customers/:id/kyc/initiate`        | Initiate Tier 1 KYC flow via BVN                             |
| `POST`  | `/customers/:id/tier2-kyc/initiate`  | Initiate Tier 2 KYC flow                                     |
| `POST`  | `/customers/:id/ngn-virtual-account` | Issue a permanent NGN virtual account                        |
| `GET`   | `/customers/:id/ngn-virtual-account` | Retrieve the customer's NGN virtual account                  |
| `POST`  | `/customers/:id/crypto-wallet`       | Register a crypto wallet destination                         |
| `GET`   | `/customers/:id/crypto-wallets`      | List registered crypto wallets                               |
| `POST`  | `/customers/:id/crypto-funding`      | Create a crypto funding request                              |
| `GET`   | `/customers/:id/balance`             | Get the customer's current USDT balance                      |
| `GET`   | `/customers/:id/ledger`              | List the customer's transaction ledger                       |

<AccordionGroup>
  <Accordion title="List customers with pagination">
    The `GET /customers` endpoint uses cursor-based pagination. Pass `cursor` from the previous response to fetch the next page, and use `limit` (max 200) to control page size.

    ```bash theme={null}
    curl "https://api.dubupay.com/api/v1/customers?limit=50&cursor=eyJpZCI6IjEyMyJ9" \
      -H "X-Api-Key: dubu_sk_live_..."
    ```
  </Accordion>

  <Accordion title="Filter customers by email">
    Pass `email` as a query parameter to look up a specific customer without knowing their ID.

    ```bash theme={null}
    curl "https://api.dubupay.com/api/v1/customers?email=ada@example.com" \
      -H "X-Api-Key: dubu_sk_live_..."
    ```
  </Accordion>

  <Accordion title="Supported crypto chains for wallets and funding">
    When creating a crypto wallet or crypto funding request, `chain` must be one of:

    `APTOS`, `BASE`, `CELO`, `ETHEREUM`, `POLYGON`, `SOLANA`, `TRON`

    The `asset` field accepts `USDC` or `USDT`.
  </Accordion>
</AccordionGroup>
