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

# Bank transfer

> Generate a temporary account for the customer to pay into, and reconcile the transfer automatically.

Bank transfer collections work by generating a **temporary account** for a specific amount. The
customer sends the exact amount to it before it expires, and the payment is reconciled to your
Zerocash account automatically.

<Warning>
  This collection method is available for **Kenya (`KES`) and Nigeria (`NGN`) only**.
</Warning>

Use it for larger payments, invoice-style collections, and customers who prefer bank transfer over
mobile money or card.

## Happy path

<Steps>
  <Step title="Create the account">
    Generate a temporary account for the expected amount and currency.
  </Step>

  <Step title="Show the details">
    Display the account number, bank name, amount, and expiry to the customer.
  </Step>

  <Step title="Customer transfers">
    They send the exact amount before the account expires.
  </Step>

  <Step title="Confirm">
    Listen for the webhook or query the transaction status.
  </Step>

  <Step title="Fulfil">
    Only once the transfer is successful.
  </Step>
</Steps>

## 1. Create the account

Send a request to [Bank Transfer](/api-reference/endpoint/bank-transfer).

| Field               | Type   | Required | Description                                 |
| :------------------ | :----- | :------: | :------------------------------------------ |
| `amount`            | Number |    Yes   | Amount to be charged, e.g. `1000`           |
| `currency`          | String |    Yes   | `KES` or `NGN`                              |
| `externalReference` | String |    Yes   | Your own unique ID for reconciliation       |
| `email`             | String |    Yes   | Email address of the customer being charged |

```json Request theme={null}
{
  "amount": 1000,
  "currency": "NGN",
  "externalReference": "invoice_5678",
  "email": "customer@example.com"
}
```

```json Response theme={null}
{
  "success": true,
  "message": "Account created successfully.",
  "data": {
    "transactionId": "BFiR6ISntYyii9h1GUe6",
    "virtualAccount": {
      "permanent": false,
      "accountNumber": "1250837235",
      "bankName": "78 Finance Company limited (Bank78)",
      "createdAt": "2025-09-05T20:35:21+00:00",
      "expiresAt": "2025-09-05T22:35:21.205979Z",
      "note": "Please make a bank transfer to 78 Finance Company limited (Bank78)",
      "amount": "1000",
      "bankLogo": "https://test.com"
    }
  }
}
```

## 2. Show the details to your customer

Render these fields from the response so the customer can complete the transfer:

| Field           | Show it as                     |
| :-------------- | :----------------------------- |
| `accountNumber` | The account to transfer to     |
| `bankName`      | The receiving bank             |
| `amount`        | The **exact** amount to send   |
| `note`          | Instructions for the customer  |
| `expiresAt`     | A countdown or deadline        |
| `bankLogo`      | Visual identifier for the bank |

<Warning>
  The customer must transfer the **exact amount** to the account before `expiresAt`. A partial or
  late transfer will not reconcile cleanly.
</Warning>

## 3. Check the transaction status

Call [Get Transaction](/api-reference/endpoint/get-transaction) with the `transactionId` or your
`externalReference`.

<CodeGroup>
  ```json Successful theme={null}
  {
    "success": true,
    "data": {
      "transactionId": "BFiR6ISntYyii9h1GUe6",
      "amount": 1000,
      "type": "deposit",
      "currency": "NGN",
      "senderCurrency": "NGN",
      "senderAmount": 1000,
      "receiverCurrency": "NGN",
      "receiverAmount": 1000,
      "chargeStatus": "successful",
      "status": "SUCCESSFUL",
      "method": "bank",
      "note": "Bank transfer received from account 1234567890",
      "fullTimestamp": "2025-09-05T20:40:44+03:00",
      "externalReference": "invoice_5678",
      "thirdPartyReference": "BANK_REF_12345",
      "accountNumber": "1250837235"
    }
  }
  ```

  ```json Failed theme={null}
  {
    "success": true,
    "data": {
      "transactionId": "BFiR6ISntYyii9h1GUe6",
      "amount": 1000,
      "type": "deposit",
      "currency": "NGN",
      "chargeStatus": "failed",
      "status": "FAILED",
      "method": "bank",
      "fullTimestamp": "2025-09-05T22:40:44+03:00",
      "externalReference": "invoice_5678",
      "accountNumber": "1250837235"
    }
  }
  ```
</CodeGroup>

## 4. Handle webhooks

<CodeGroup>
  ```json Created theme={null}
  {
    "event": "transaction_created",
    "data": {
      "transactionId": "BFiR6ISntYyii9h1GUe6",
      "status": "pending",
      "type": "deposit",
      "externalReference": "invoice_5678",
      "method": "bank"
    },
    "timestamp": "2025-09-05T20:35:21.600Z"
  }
  ```

  ```json Successful theme={null}
  {
    "event": "transaction_updated",
    "data": {
      "transactionId": "BFiR6ISntYyii9h1GUe6",
      "status": "successful",
      "type": "deposit",
      "externalReference": "invoice_5678",
      "method": "bank",
      "amount": 1000,
      "currency": "NGN"
    },
    "timestamp": "2025-09-05T20:40:44.600Z"
  }
  ```

  ```json Failed theme={null}
  {
    "event": "transaction_updated",
    "data": {
      "transactionId": "BFiR6ISntYyii9h1GUe6",
      "status": "failed",
      "type": "deposit",
      "externalReference": "invoice_5678",
      "method": "bank",
      "amount": 1000,
      "currency": "NGN"
    },
    "timestamp": "2025-09-05T22:40:44.600Z"
  }
  ```
</CodeGroup>

## 5. Handle expiry

Accounts created this way are temporary and expire at `expiresAt`. After that:

* The account can no longer receive new transfers.
* Transfers received after expiry may not reconcile automatically.
* Create a **new** account if the customer needs more time.

<Note>
  If a transfer lands after expiry, you may need to reconcile manually. Contact
  [support@zerocash.tech](mailto:support@zerocash.tech) for help.
</Note>

## Best practices

<CardGroup cols={2}>
  <Card title="Verify before fulfilling" icon="shield-check">
    Confirm the status even after receiving a webhook. Never release goods on account creation
    alone.
  </Card>

  <Card title="Store both references" icon="database">
    Keep `transactionId` and `externalReference` for reconciliation and support tickets.
  </Card>

  <Card title="Surface the deadline" icon="clock">
    Show the customer a live countdown to `expiresAt`, and re-issue an account when it lapses.
  </Card>

  <Card title="Prefer webhooks" icon="bell">
    Use webhooks for real-time updates rather than polling the status endpoint in a loop.
  </Card>
</CardGroup>
