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

# Transactions

> List and retrieve transactions — the immutable record of every payment, transfer, and verification that moves money through your account.

## Overview

A **transaction** is the canonical record of money moving into or out of your
account. Almost every money-related action in Hyparrow produces one: a customer
funding their [virtual account](/customers), a bank transfer you send out, a bill
payment, a card charge, an invoice being paid, or a paid verification check.

You don't create transactions directly. They are written for you when the
underlying action happens, then updated as the bank network confirms the outcome.
The Transactions endpoints let you **list** and **read** those records for
reconciliation, reporting, and reacting to payments.

<Note>
  Every `amount` is in **kobo**, the minor unit of the Naira. 1 NGN = 100 kobo, so a
  transaction `amount` of `50000` means `₦500.00`. The `currency` field is `NGN`.
</Note>

### Base URL & authentication

| Item          | Value                               |
| ------------- | ----------------------------------- |
| Base URL      | `https://api.hyparrow.cloud/api/v1` |
| Auth header 1 | `X-API-Key: pk_live_xxx`            |
| Auth header 2 | `X-API-Secret: sk_live_xxx`         |

<Note>
  Test against the sandbox first: send requests to
  `https://sandbox.hyparrow.cloud/api/v1` with a **`pk_test_`** key (and its matching
  `sk_test_` secret). Sandbox transfers and payments generate real-shaped
  transactions you can list and fetch without moving live money.
</Note>

## The transaction record

Each transaction carries a stable `id` (UUID), a unique `reference`, a `type`, a
`status`, and an `amount` in kobo. Optional link fields (`customerId`, `invoiceId`,
`productId`, `subscriptionId`, `receiptId`) connect the transaction back to whatever
produced it.

### Transaction types

| `type`                 | Meaning                                            |
| ---------------------- | -------------------------------------------------- |
| `virtual_account`      | Money received into a customer's virtual account.  |
| `bank_transfer`        | An outbound transfer to a bank account.            |
| `bill_payment`         | A bill or utility payment.                         |
| `card_payment`         | A card charge.                                     |
| `account_inquiry`      | A name/account lookup against the bank network.    |
| `credit` / `debit`     | A generic credit or debit to your balance.         |
| `invoice_payment`      | Payment against an invoice.                        |
| `product_purchase`     | Payment for a product.                             |
| `subscription_payment` | A recurring subscription charge.                   |
| `verification_payment` | A paid verification (e.g. identity/account check). |
| `ussd_payment`         | A payment initiated over USSD.                     |
| `virtual_card`         | A virtual-card related transaction.                |
| `transfer_fee`         | A fee charged on a transfer.                       |

### Transaction statuses

| `status`                | Meaning                                    |
| ----------------------- | ------------------------------------------ |
| `pending`               | Created, awaiting processing.              |
| `processing`            | In flight on the bank network.             |
| `completed` / `success` | Money has moved successfully.              |
| `failed`                | The action did not complete.               |
| `canceled`              | The action was canceled before completion. |

### How transactions relate to other actions

* **Payments (virtual accounts):** when a customer funds their virtual account, a
  `virtual_account` transaction is recorded and attributed to that `customerId`.
* **Transfers:** sending money out creates a `bank_transfer` (and may add a separate
  `transfer_fee`), moving from `pending` to `processing` to `completed`/`failed`.
* **Verifications:** a paid lookup produces a `verification_payment` (or
  `account_inquiry`) record so the spend is auditable.
* **Invoices, products, subscriptions:** paying one links the transaction via
  `invoiceId`, `productId`, or `subscriptionId`.

## Typical flow

<Steps>
  <Step title="An action happens">
    A customer pays into their virtual account, you send a transfer, or a
    verification runs. Hyparrow writes a transaction in `pending`.
  </Step>

  <Step title="The bank network processes it">
    The status advances to `processing`, then settles as `completed`/`success` or
    `failed`. A `completedAt` timestamp is set on success.
  </Step>

  <Step title="You list or fetch it">
    Poll `GET /transactions` (or fetch a single one by id) to reconcile, or react to
    the change via webhooks.
  </Step>
</Steps>

## List transactions

`GET /transactions`

Lists transactions for the authenticated account, newest first, with pagination and
optional filters.

### Query parameters

| Parameter  | Type    | Default | Description                                            |
| ---------- | ------- | ------- | ------------------------------------------------------ |
| `page`     | integer | `1`     | Page number.                                           |
| `limit`    | integer | `20`    | Results per page.                                      |
| `type`     | string  | —       | Filter by a transaction type (e.g. `virtual_account`). |
| `status`   | string  | —       | Filter by a status (e.g. `completed`).                 |
| `dateFrom` | string  | —       | Inclusive start date, `YYYY-MM-DD`.                    |
| `dateTo`   | string  | —       | Inclusive end date, `YYYY-MM-DD`.                      |

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://api.hyparrow.cloud/api/v1/transactions?type=virtual_account&status=completed&page=1&limit=20" \
    -H "X-API-Key: pk_live_xxx" \
    -H "X-API-Secret: sk_live_xxx"
  ```

  ```bash With date range theme={null}
  curl "https://api.hyparrow.cloud/api/v1/transactions?dateFrom=2026-06-01&dateTo=2026-06-30" \
    -H "X-API-Key: pk_live_xxx" \
    -H "X-API-Secret: sk_live_xxx"
  ```
</CodeGroup>

### Response

`200 OK`

```json theme={null}
{
  "success": true,
  "data": [
    {
      "id": "b71e0c2d-9f48-4a1c-8e3b-2d6a7c4f1e90",
      "customerId": "9f1c2e6a-3b4d-4c8e-9a12-7d6f5b8c0e21",
      "type": "virtual_account",
      "status": "completed",
      "amount": 50000,
      "currency": "NGN",
      "reference": "HYP-TXN-20260630-0001",
      "description": "Inbound transfer to virtual account",
      "channel": "bank_transfer",
      "senderName": "Chidi Eze",
      "senderAccountNumber": "0123456789",
      "senderBankCode": "058",
      "metadata": {},
      "completedAt": "2026-06-30T10:02:11Z",
      "createdAt": "2026-06-30T10:02:05Z",
      "updatedAt": "2026-06-30T10:02:11Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 1,
    "totalPages": 1
  }
}
```

The `pagination.totalPages` value is derived from `total` and `limit`, so you can
loop until `page` reaches `totalPages`.

## Get a transaction

`GET /transactions/{transactionId}`

Retrieves a single transaction by its UUID. The transaction must belong to your
account.

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://api.hyparrow.cloud/api/v1/transactions/b71e0c2d-9f48-4a1c-8e3b-2d6a7c4f1e90" \
    -H "X-API-Key: pk_live_xxx" \
    -H "X-API-Secret: sk_live_xxx"
  ```
</CodeGroup>

### Response

`200 OK`

```json theme={null}
{
  "success": true,
  "data": {
    "id": "b71e0c2d-9f48-4a1c-8e3b-2d6a7c4f1e90",
    "customerId": "9f1c2e6a-3b4d-4c8e-9a12-7d6f5b8c0e21",
    "type": "virtual_account",
    "status": "completed",
    "amount": 50000,
    "currency": "NGN",
    "reference": "HYP-TXN-20260630-0001",
    "description": "Inbound transfer to virtual account",
    "channel": "bank_transfer",
    "responseCode": "00",
    "responseMessage": "Successful",
    "senderName": "Chidi Eze",
    "senderAccountNumber": "0123456789",
    "senderBankCode": "058",
    "metadata": {},
    "completedAt": "2026-06-30T10:02:11Z",
    "createdAt": "2026-06-30T10:02:05Z",
    "updatedAt": "2026-06-30T10:02:11Z"
  }
}
```

For an inbound `virtual_account` payment, the `senderName`, `senderAccountNumber`,
and `senderBankCode` fields tell you who paid. For outbound and other transaction
types these may be absent.

## Errors & edge cases

| Status             | When                                                 | Example `error`            |
| ------------------ | ---------------------------------------------------- | -------------------------- |
| `400 Bad Request`  | `transactionId` is not a valid UUID.                 | `"invalid transaction ID"` |
| `401 Unauthorized` | Missing or invalid `X-API-Key` / `X-API-Secret`.     | `"user not authenticated"` |
| `404 Not Found`    | No transaction with that id belongs to your account. | `"transaction not found"`  |

```json theme={null}
{
  "success": false,
  "error": "invalid transaction ID"
}
```

Other things to keep in mind:

* Transactions are **immutable history** — you read them, you never edit them. The
  bank network advances `status` and sets `completedAt`.
* A transaction can sit in `pending`/`processing` briefly before settling; reconcile
  on `completed`/`success` or `failed`, not on creation.
* Use `reference` (unique per transaction) as your idempotent key when matching
  Hyparrow records to your own ledger.
* Filters combine: passing `type`, `status`, and a `dateFrom`/`dateTo` range narrows
  the list to transactions matching all of them.
