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

# Money Transfer

> Send bank transfers to any Nigerian bank account: list banks, resolve the account name, send, and track status.

## Overview

The Money Transfer API sends funds from your Hyparrow wallet to any Nigerian bank
account over the bank network. The flow is always the same: list the supported
banks, resolve the recipient's account name from their account number, initiate
the transfer, then poll for the final status.

When you initiate a transfer, Hyparrow debits the **principal** from your wallet
**before** calling the bank network, then books the **fee** as a separate debit
only after the network accepts the transfer. If the network rejects or errors, the
principal debit is automatically **reversed** — so a failed transfer never leaves
your wallet short.

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

  **Auth:** every request requires `X-API-Key` and `X-API-Secret` headers.

  **Sandbox:** point at `https://sandbox.hyparrow.cloud/api/v1` and use your
  `pk_test_` key. Simulate outcomes with magic amounts — an amount ending in `.01`
  forces a **failed** transfer (and you can observe the automatic reversal), and
  `.99` forces a **pending** transfer so you can test status polling. Everything
  else succeeds.
</Note>

<Warning>
  **Amounts are in kobo.** All transfer amounts are integers in minor units passed
  as strings — `"500000"` means ₦5,000.00. Fees are quoted in Naira and charged on
  top of the principal.
</Warning>

## The transfer flow

<Steps>
  <Step title="List banks">
    `GET /money-transfer/banks` returns supported banks. Each entry has a
    `bankCode` — use this exact value for inquiry and send.
  </Step>

  <Step title="Resolve the account name">
    `POST /money-transfer/account-inquiry` (or `GET`) with the account number and
    bank code returns the registered account name. Show it to the user to confirm.
  </Step>

  <Step title="Send">
    `POST /money-transfer/send` debits the wallet (principal first, then fee on
    success) and initiates the transfer over the bank network.
  </Step>

  <Step title="Poll status">
    `GET /money-transfer/status?reference=<transferCode>` (or `POST`) returns the
    current status until it settles.
  </Step>
</Steps>

## List banks

```bash List banks theme={null}
curl https://api.hyparrow.cloud/api/v1/money-transfer/banks \
  -H "X-API-Key: $HYPARROW_KEY" \
  -H "X-API-Secret: $HYPARROW_SECRET"
```

```json Response theme={null}
{
  "success": true,
  "data": {
    "banks": [
      {
        "bankCode": "058",
        "code": "0001",
        "bankName": "Guaranty Trust Bank",
        "logo": "https://.../gtb.png"
      },
      {
        "bankCode": "044",
        "code": "0002",
        "bankName": "Access Bank",
        "logo": "https://.../access.png"
      }
    ]
  }
}
```

<Note>
  Always use the `bankCode` field (the CBN code) for `account-inquiry` and `send`.
  The separate `code` field is an internal identifier and is not used for transfers.
</Note>

## Resolve the account name

Confirm the recipient before you send. Supply the `accountNumber` and the
`bankCode` from the bank list. This endpoint accepts both `GET` (query params) and
`POST` (JSON body).

```bash Account inquiry (GET) theme={null}
curl "https://api.hyparrow.cloud/api/v1/money-transfer/account-inquiry?accountNumber=0123456789&bankCode=058" \
  -H "X-API-Key: $HYPARROW_KEY" \
  -H "X-API-Secret: $HYPARROW_SECRET"
```

```bash Account inquiry (POST) theme={null}
curl -X POST https://api.hyparrow.cloud/api/v1/money-transfer/account-inquiry \
  -H "X-API-Key: $HYPARROW_KEY" \
  -H "X-API-Secret: $HYPARROW_SECRET" \
  -H "Content-Type: application/json" \
  -d '{ "accountNumber": "0123456789", "bankCode": "058" }'
```

```json Response theme={null}
{
  "success": true,
  "data": {
    "accountName": "JANE DOE",
    "accountNumber": "0123456789",
    "bankCode": "058"
  }
}
```

The `accountName` you get back is what you pass as `recipientName` when you send.

<Warning>
  **Account couldn't be resolved.** If the name lookup fails on every network, you
  get a `503` with a retry-friendly message instead of an error code. Do not proceed
  to send — re-check the account number and bank, then retry shortly:

  ```json theme={null}
  {
    "success": false,
    "error": "We couldn't verify this account right now. Please double-check the account number and bank, then try again in a moment."
  }
  ```
</Warning>

## Send a transfer

`POST /money-transfer/send` initiates the transfer. The wallet is checked for the
principal **plus** the fee up front; the principal is debited before the bank
network is called, and the fee is debited only after the network accepts.

### Request body

| Field               | Required | Description                             |
| ------------------- | -------- | --------------------------------------- |
| `amount`            | yes      | Principal in **kobo**, as a string      |
| `recipientAccount`  | yes      | Beneficiary account number              |
| `recipientBankCode` | yes      | `bankCode` from the bank list           |
| `recipientName`     | yes      | Beneficiary name (from account inquiry) |
| `senderPhone`       | yes      | Sender phone number                     |
| `senderEmail`       | yes      | Sender email                            |
| `senderLastname`    | yes      | Sender last name                        |
| `senderOthernames`  | yes      | Sender other names                      |
| `narration`         | no       | Free-text note for the transfer         |

```bash Send theme={null}
curl -X POST https://api.hyparrow.cloud/api/v1/money-transfer/send \
  -H "X-API-Key: $HYPARROW_KEY" \
  -H "X-API-Secret: $HYPARROW_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "500000",
    "recipientAccount": "0123456789",
    "recipientBankCode": "058",
    "recipientName": "JANE DOE",
    "senderPhone": "08030000000",
    "senderEmail": "sender@example.com",
    "senderLastname": "Smith",
    "senderOthernames": "John",
    "narration": "Invoice 1042"
  }'
```

```json Response theme={null}
{
  "success": true,
  "message": "Transfer initiated successfully and wallet debited",
  "data": {
    "TransferCode": "14531719772800000",
    "FeeClass": "default",
    "Fee": 2500,
    "TransactionID": "9f1c2b7e-2a3d-4f6a-8b1e-7c0d9e2f1a34",
    "WalletBalance": 1247500,
    "ResponseCode": "00",
    "ResponseMessage": "Transaction Successful"
  }
}
```

Keep `data.TransferCode` — it is the `reference` you use to check status.

### Wallet debit and fees

The total debited is **principal + fee**:

* The wallet must cover the principal *and* the fee, or the send is rejected
  before anything is charged.
* The principal is debited first (atomically, with a row lock) so funds can't leak
  if the network call partially fails.
* The fee is a flat amount based on your transfer fee class and the amount tier. It
  is booked as a separate debit and only **after** the network accepts the
  transfer — a failed or reversed transfer is never charged a fee.

`data.Fee` is the fee in kobo, `data.FeeClass` is the fee class applied, and
`data.WalletBalance` is your remaining balance after principal + fee.

## Fee schedule

`GET /money-transfer/fee-class` returns the fee ladder for **your own** account, so
you can quote the fee before sending and reconcile it after.

```bash Fee class theme={null}
curl https://api.hyparrow.cloud/api/v1/money-transfer/fee-class \
  -H "X-API-Key: $HYPARROW_KEY" \
  -H "X-API-Secret: $HYPARROW_SECRET"
```

```json Response theme={null}
{
  "success": true,
  "feeClass": "default",
  "data": [
    { "max": 10000,  "fee": 25 },
    { "max": 39000,  "fee": 35 },
    { "max": 50000,  "fee": 47 },
    { "max": 100000, "fee": 58 },
    { "max": 150000, "fee": 69 },
    { "max": null,   "fee": 77 }
  ]
}
```

| Field        | Description                                                                                                                  |
| ------------ | ---------------------------------------------------------------------------------------------------------------------------- |
| `feeClass`   | The class assigned to your account. Everyone is on `default` unless Hyparrow moves you to another schedule.                  |
| `data[].max` | Inclusive upper bound of the band, in **Naira**. `null` marks the top tier, which applies to everything above the last band. |
| `data[].fee` | Flat fee for that band, in **Naira**.                                                                                        |

Tiers come back ordered ascending: to price a transfer, convert the principal to
Naira and take the `fee` of the first band whose `max` is `null` or `>= amount`.
A ₦5,000 transfer on the response above costs ₦25; a ₦200,000 transfer costs ₦77.

<Warning>
  **Read the ladder, don't hardcode it.** Fee tiers are tunable at runtime and your
  class can change, so a copied table will silently drift. Fetch this endpoint (cache
  it briefly if you like) and quote from the response. Note the unit switch: transfer
  amounts are in **kobo**, but the fee ladder is in **Naira** — `data.Fee` on the send
  response is in kobo.
</Warning>

## Check status

`GET /money-transfer/status?reference=<transferCode>` (or `POST` with a JSON body)
returns both Hyparrow's local transaction record and the latest network status.

```bash Status theme={null}
curl "https://api.hyparrow.cloud/api/v1/money-transfer/status?reference=14531719772800000" \
  -H "X-API-Key: $HYPARROW_KEY" \
  -H "X-API-Secret: $HYPARROW_SECRET"
```

```json Response theme={null}
{
  "success": true,
  "data": {
    "transaction": {
      "id": "9f1c2b7e-2a3d-4f6a-8b1e-7c0d9e2f1a34",
      "reference": "14531719772800000",
      "amount": 500000,
      "currency": "NGN",
      "status": "completed",
      "type": "bank_transfer",
      "responseCode": "00",
      "responseMessage": "Transaction Successful",
      "createdAt": "2026-06-30T10:00:00Z",
      "completedAt": "2026-06-30T10:00:05Z"
    },
    "provider": {
      "ResponseCode": "00",
      "TransactionStatus": "Completed"
    }
  }
}
```

## Edge cases

<Warning>
  **Insufficient balance.** If the wallet can't cover principal + fee, the send is
  rejected before any debit, and the error spells out the shortfall:

  ```json theme={null}
  {
    "success": false,
    "error": "Insufficient wallet balance. Available: ₦40.00, Required: ₦5,025.00 (₦5,000.00 transfer + ₦25.00 fee)"
  }
  ```
</Warning>

<Warning>
  **Failed transfer is reversed.** If the bank network errors or rejects the
  transfer after the principal was debited, Hyparrow automatically credits the
  principal back to your wallet (a reversal transaction referenced `REV_<code>`) and
  returns the failure. No fee is charged on a failed transfer.

  ```json theme={null}
  {
    "success": false,
    "error": "Transfer rejected by network",
    "data": { }
  }
  ```
</Warning>

<Note>
  A **pending** result (e.g. a `.99` magic amount in sandbox, or a slow settlement
  in production) means the network has accepted the transfer but not yet settled it.
  Keep polling `/money-transfer/status` until the status moves to `completed` or
  `failed`. The principal stays debited while pending.
</Note>
