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

# Virtual Cards

> Issue and manage business virtual cards for your customers via the Hyparrow API.

## Overview

A **business virtual card** is a payment card you issue, on behalf of one of your customers,
through your Hyparrow business account. The card is backed by a dedicated linked account and can
be `debit` or `prepaid`. Because the card is created under your client credentials and tied to a
customer, you can issue and track cards for many customers from a single integration.

Typical uses include giving customers a spendable card against a wallet balance, or provisioning
disposable cards for online payments.

<Note>
  **Base URL:** `https://api.hyparrow.cloud/api/v1`

  Business virtual card endpoints are authenticated with your API key pair:

  ```
  X-API-Key: pk_live_xxxxxxxxxxxx
  X-API-Secret: sk_live_xxxxxxxxxxxx
  ```

  Test the full create-and-list flow against `https://sandbox.hyparrow.cloud/api/v1` with your
  `pk_test_` keys before issuing live cards.
</Note>

<Warning>
  Creating a card charges a flat per-card creation fee (default ₦500) to your wallet. If your
  wallet balance is too low, the request fails with a message telling you the exact amount to fund.
  Fees are denominated in **kobo** internally (₦500 = 50,000 kobo).
</Warning>

## Card fields

A virtual card record contains:

| Field          | Description                                                     |
| -------------- | --------------------------------------------------------------- |
| `id`           | Card UUID                                                       |
| `cardType`     | `debit` or `prepaid`                                            |
| `status`       | `active`, `suspended`, or `terminated`                          |
| `nameOnCard`   | Cardholder name printed on the card                             |
| `customerId`   | The customer this card belongs to                               |
| `clientId`     | Your business client ID                                         |
| `accountId`    | The linked account number backing the card                      |
| `accountType`  | Linked account type (`current` / `savings`)                     |
| `pan`          | Card number — returned **in full only once**, masked afterwards |
| `expiryDate`   | Card expiry                                                     |
| `cvv` / `cvv2` | Security codes — returned **only once** at creation             |
| `createdAt`    | When the card was issued                                        |

<Warning>
  The full PAN, CVV, and CVV2 are returned **only once**, in the create response. Every subsequent
  list or fetch returns a sanitized record with the PAN masked (e.g. `************1234`) and the
  CVV fields cleared. Capture and store these securely at creation time — they cannot be retrieved
  again.
</Warning>

## Create a business virtual card

`POST /virtual-cards`

| Field           | Required | Notes                                |
| --------------- | -------- | ------------------------------------ |
| `customerId`    | yes      | UUID of the customer the card is for |
| `cardType`      | yes      | `debit` or `prepaid`                 |
| `pin`           | yes      | Numeric card PIN                     |
| `nameOnCard`    | yes      | Cardholder name                      |
| `city`          | yes      | Billing city                         |
| `streetAddress` | no       | Billing street address               |
| `postalCode`    | no       | Billing postal code                  |
| `state`         | no       | Billing state                        |

<Steps>
  <Step title="Fund your wallet">
    Ensure your wallet covers the per-card creation fee.
  </Step>

  <Step title="POST the card details">
    Send the customer ID, card type, PIN, and billing address.
  </Step>

  <Step title="Store the returned card secrets">
    The response includes full card details once. Persist them securely before moving on.
  </Step>
</Steps>

```bash theme={null}
curl -X POST https://api.hyparrow.cloud/api/v1/virtual-cards \
  -H "X-API-Key: pk_live_xxxxxxxxxxxx" \
  -H "X-API-Secret: sk_live_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "customerId": "c1a2b3c4-d5e6-7a8b-9c0d-1e2f3a4b5c6d",
    "cardType": "debit",
    "pin": 1234,
    "nameOnCard": "ADA OBI",
    "streetAddress": "12 Marina Road",
    "city": "Lagos",
    "state": "Lagos",
    "postalCode": "101001"
  }'
```

### Response

```json theme={null}
{
  "success": true,
  "message": "Virtual card created successfully. Save your card details — they will not be shown again.",
  "data": {
    "id": "a1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d",
    "cardType": "debit",
    "status": "active",
    "nameOnCard": "ADA OBI",
    "customerId": "c1a2b3c4-...",
    "clientId": "1a2b3c4d-...",
    "accountId": "7012345678",
    "accountType": "20",
    "createdAt": "2026-06-30T11:30:00Z"
  },
  "card": {
    "pan": "5061234567890123",
    "expiryDate": "06/29",
    "cvv": "123",
    "cvv2": "456"
  }
}
```

<Note>
  The `data` object is the stored card record; the `card` object holds the sensitive details that
  are surfaced only on this response. Subsequent reads will not include `card`.
</Note>

<Warning>
  Common failures:

  * **`400` invalid customer ID** — `customerId` is not a valid UUID.
  * **Insufficient wallet balance** — fund your wallet with the amount shown in the error.
  * **`400`** for a missing required field (`cardType`, `pin`, `nameOnCard`, or `city`).
</Warning>

## List business virtual cards

`GET /virtual-cards` returns the cards belonging to your business client. Pass an optional
`customerId` query parameter to filter to a single customer. PANs are masked.

```bash theme={null}
curl "https://api.hyparrow.cloud/api/v1/virtual-cards?customerId=c1a2b3c4-..." \
  -H "X-API-Key: pk_live_xxxxxxxxxxxx" \
  -H "X-API-Secret: sk_live_xxxxxxxxxxxx"
```

```json theme={null}
{
  "success": true,
  "data": [
    {
      "id": "a1b2c3d4-...",
      "cardType": "debit",
      "status": "active",
      "nameOnCard": "ADA OBI",
      "customerId": "c1a2b3c4-...",
      "clientId": "1a2b3c4d-...",
      "accountId": "7012345678",
      "pan": "************0123",
      "expiryDate": "06/29",
      "createdAt": "2026-06-30T11:30:00Z"
    }
  ]
}
```

<Note>
  An invalid `customerId` value returns `400 invalid customer ID`. Omit the parameter to list every
  card across all of your customers.
</Note>
