> ## 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.

# Virtual Accounts API — issue NGN bank accounts

> Issue temporary or permanent NGN virtual bank accounts to customers and create onramps to receive NGN deposits that settle as USDC or USDT.

Virtual accounts give your customers a real Nigerian Naira bank account number they can fund from any local bank. When NGN arrives in the account, Dubu Pay converts it to USDC or USDT and routes the proceeds to your configured settlement destination. You can issue accounts directly to a customer via the Customers API, or create standalone onramps with flexible settlement options.

## Authentication

All endpoints require either a Bearer token or an API key.

```
Authorization: Bearer <access_token>
```

```
X-Api-Key: dubu_sk_live_...
```

***

## TEMPORARY vs PERMANENT accounts

| Feature         | TEMPORARY                 | PERMANENT                                  |
| --------------- | ------------------------- | ------------------------------------------ |
| Expiry          | 25 minutes after creation | No expiry                                  |
| Rate            | Locked at creation time   | Floating (current market rate)             |
| `amount` field  | Required                  | Not applicable                             |
| KYC requirement | None                      | Customer must have Tier 1 BVN verification |

Use **TEMPORARY** accounts for single-use checkout flows where you want to guarantee a fixed exchange rate for a short window. Use **PERMANENT** accounts for customers who deposit repeatedly over time.

***

## Issue an NGN virtual account to a customer

`POST https://api.dubupay.com/api/v1/customers/:id/ngn-virtual-account`

Creates a permanent NGN virtual bank account and links it to the specified customer. The customer must have completed at least Tier 1 KYC (BVN verification) before you can issue a permanent account.

### Path parameters

<ParamField path="id" type="string" required>
  The customer's UUID.
</ParamField>

### Response

<ResponseField name="data" type="object">
  The issued virtual account details.

  <Expandable title="data fields">
    <ResponseField name="accountNumber" type="string">
      The NGN bank account number assigned to the customer.
    </ResponseField>

    <ResponseField name="bankName" type="string">
      The name of the partner bank holding the virtual account.
    </ResponseField>

    <ResponseField name="accountName" type="string">
      The account name as it appears in the banking system.
    </ResponseField>

    <ResponseField name="status" type="string">
      Account status. Typically `ACTIVE` after successful creation.
    </ResponseField>

    <ResponseField name="customerId" type="string">
      UUID of the customer this account belongs to.
    </ResponseField>

    <ResponseField name="created_at" type="string">
      ISO 8601 timestamp of account creation.
    </ResponseField>
  </Expandable>
</ResponseField>

### Example

```bash theme={null}
curl -X POST "https://api.dubupay.com/api/v1/customers/cus_01HXYZ/ngn-virtual-account" \
  -H "X-Api-Key: dubu_sk_live_..."
```

***

## Get a customer's NGN virtual account

`GET https://api.dubupay.com/api/v1/customers/:id/ngn-virtual-account`

Retrieves the NGN virtual account currently assigned to a customer.

### Path parameters

<ParamField path="id" type="string" required>
  The customer's UUID.
</ParamField>

### Example

```bash theme={null}
curl "https://api.dubupay.com/api/v1/customers/cus_01HXYZ/ngn-virtual-account" \
  -H "X-Api-Key: dubu_sk_live_..."
```

***

## Create an onramp

`POST https://api.dubupay.com/api/v1/payments/onramps`

Creates an NGN virtual bank account (onramp) with configurable type, settlement mode, and target asset. This is the most flexible way to accept NGN deposits.

<Note>
  This endpoint supports idempotency. Pass an `X-Idempotency-Key` header to safely retry requests without creating duplicate onramps.
</Note>

### Request body

<ParamField body="type" type="string" required>
  The onramp type. One of `TEMPORARY` or `PERMANENT`. TEMPORARY accounts expire after 25 minutes with the rate locked at creation. PERMANENT accounts have no expiry and use the floating market rate at the time of deposit.
</ParamField>

<ParamField body="customer_id" type="string">
  UUID of the customer to associate with this onramp. Required for PERMANENT onramps.
</ParamField>

<ParamField body="rate_id" type="string">
  ID of a previously fetched rate to lock in for this onramp. See [Exchange Rates](/api-reference/payments/rates).
</ParamField>

<ParamField body="amount" type="number">
  The NGN amount to lock for this virtual account. Required for TEMPORARY onramps.
</ParamField>

<ParamField body="settlement" type="object">
  How and where proceeds are settled after a deposit converts.

  <Expandable title="settlement fields">
    <ParamField body="mode" type="string" required>
      Settlement destination type. One of `ONCHAIN` (send to a blockchain address) or `INTERNAL_BALANCE` (credit your merchant balance).
    </ParamField>

    <ParamField body="asset" type="string" required>
      Asset to receive. One of `USDC` or `USDT`.
    </ParamField>

    <ParamField body="chain" type="string">
      Blockchain network for `ONCHAIN` settlement (e.g., `TRON`, `SOLANA`, `BASE`).
    </ParamField>

    <ParamField body="destination_address" type="string">
      Wallet address for `ONCHAIN` settlement.
    </ParamField>
  </Expandable>
</ParamField>

### Response

<ResponseField name="data" type="object">
  The created onramp.

  <Expandable title="data fields">
    <ResponseField name="id" type="string">
      Unique ID for the onramp.
    </ResponseField>

    <ResponseField name="type" type="string">
      `TEMPORARY` or `PERMANENT`.
    </ResponseField>

    <ResponseField name="accountNumber" type="string">
      The NGN bank account number for this onramp.
    </ResponseField>

    <ResponseField name="bankName" type="string">
      The partner bank name.
    </ResponseField>

    <ResponseField name="accountName" type="string">
      The account name as it appears in the banking system.
    </ResponseField>

    <ResponseField name="expiresAt" type="string">
      ISO 8601 expiry timestamp. Present only for `TEMPORARY` onramps.
    </ResponseField>

    <ResponseField name="status" type="string">
      Onramp status: `ACTIVE`, `EXPIRED`, or `INACTIVE`.
    </ResponseField>

    <ResponseField name="created_at" type="string">
      ISO 8601 creation timestamp.
    </ResponseField>
  </Expandable>
</ResponseField>

### Example — TEMPORARY onramp

```bash theme={null}
curl -X POST https://api.dubupay.com/api/v1/payments/onramps \
  -H "X-Api-Key: dubu_sk_live_..." \
  -H "X-Idempotency-Key: checkout-12345" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "TEMPORARY",
    "amount": 50000,
    "rate_id": "rate_abc123",
    "settlement": {
      "mode": "ONCHAIN",
      "asset": "USDT",
      "chain": "TRON",
      "destination_address": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE"
    }
  }'
```

### Example — PERMANENT onramp with internal balance

```bash theme={null}
curl -X POST https://api.dubupay.com/api/v1/payments/onramps \
  -H "X-Api-Key: dubu_sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "type": "PERMANENT",
    "customer_id": "b2c3d4e5-f6a7-8901-bcde-f01234567890",
    "settlement": {
      "mode": "INTERNAL_BALANCE",
      "asset": "USDT"
    }
  }'
```

***

## List onramps

`GET https://api.dubupay.com/api/v1/payments/onramps`

Returns a paginated list of onramps created under your merchant account.

### Query parameters

<ParamField query="page" type="number">
  Page number (1-indexed).
</ParamField>

<ParamField query="limit" type="number">
  Results per page. Up to 100.
</ParamField>

<ParamField query="status" type="string">
  Filter by status: `ACTIVE`, `EXPIRED`, or `INACTIVE`.
</ParamField>

### Example

```bash theme={null}
curl "https://api.dubupay.com/api/v1/payments/onramps?status=ACTIVE&limit=20" \
  -H "X-Api-Key: dubu_sk_live_..."
```

***

## Get an onramp

`GET https://api.dubupay.com/api/v1/payments/onramps/:id`

Retrieves a single onramp by ID, including its current status and account details.

### Path parameters

<ParamField path="id" type="string" required>
  The onramp ID.
</ParamField>

### Example

```bash theme={null}
curl "https://api.dubupay.com/api/v1/payments/onramps/onr_01HXYZ" \
  -H "X-Api-Key: dubu_sk_live_..."
```
