> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.senjaropay.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.senjaropay.com/_mcp/server.

# Payouts

Pay out funds from your SenjaroPay merchant wallet to a beneficiary bank account.

Look up the account name first, confirm it with your beneficiary, then create the transfer. Bank payouts are available in **TZS** today. Always send `currency` explicitly — additional currencies (for example USD) and mobile money payouts will be documented when they go live.

All calls are **POST** to `https://api.senjaropay.com` and require **`x-api-key`** and **`x-api-secret`**. Transfer also requires **`x-idempotency-key`**.

## How it works

#### Look up the account

Call account-name lookup with the bank code and account number. Show `account_name` to the user for confirmation.

#### Create the payout

Send amount, currency, bank, account, and the confirmed name. Include a new UUID in `x-idempotency-key`. Store `withdrawal_id` and `transaction_reference`.

#### Track the result

A successful create often returns `status: PROCESSING` while the bank settles the transfer. Treat that as accepted, not final completion, until your reconciliation flow confirms it.

## Authentication

| Header              | Lookup | Transfer | Description                                                  |
| ------------------- | ------ | -------- | ------------------------------------------------------------ |
| `Content-Type`      | Yes    | Yes      | `application/json`                                           |
| `x-api-key`         | Yes    | Yes      | Dashboard **Public Key** ([Authentication](/authentication)) |
| `x-api-secret`      | Yes    | Yes      | Secret key. Server-side only.                                |
| `x-idempotency-key` | No     | Yes      | A new UUID for each payout transfer                          |

```js
import { randomUUID } from "node:crypto";

const idempotencyKey = randomUUID();
```

```python
import uuid

idempotency_key = str(uuid.uuid4())
```

Reuse an idempotency key only when retrying the **same** transfer (same amount, currency, bank, account, and name).

## Currency

| Currency           | Channel      | Status      |
| ------------------ | ------------ | ----------- |
| `TZS`              | Bank account | Available   |
| `USD`              | —            | Coming soon |
| Mobile money (MNO) | —            | Coming soon |

Always pass `currency` on transfer. Do not assume the wallet default.

## Bank short codes

Pass the bank shortcode in the `bank` field for account-name lookup and transfer. Prefer the same value for both calls.

| Bank                                | Shortcode      |
| ----------------------------------- | -------------- |
| ABSA Bank                           | `ABSA`         |
| Akiba Commercial Bank               | `AKIBA`        |
| Amana Bank                          | `AMANABANK`    |
| Azania Bancorp Bank                 | `AZANIA`       |
| Access Bank Tanzania                | `BANCABC`      |
| Bank of Africa (Tanzania) Ltd       | `BOA`          |
| Bank of Baroda (T) Ltd              | `BANKOFBARODA` |
| Bank of India (T) Ltd               | `BANKOFINDIA`  |
| China Dasheng Bank Ltd              | `CHINADASHENG` |
| Citibank Tanzania Limited           | `CITIBANK`     |
| CRDB Bank Limited                   | `CRDBBANK`     |
| DCB Commercial Bank                 | `DCBBANK`      |
| Diamond Trust Bank                  | `DTB`          |
| Ecobank Tanzania Ltd                | `ECOBANK`      |
| Equity Bank (T) Ltd                 | `EQUITYBANK`   |
| Exim Bank                           | `EXIMBANK`     |
| FINCA Microfinance Bank             | `FINCA`        |
| Guaranty Trust Bank Tanzania Ltd    | `GTBANK`       |
| Habib African Bank                  | `HABIBBANK`    |
| I\&M Bank (T) Ltd                   | `IMBANK`       |
| International Commercial Bank (T)   | `ICB`          |
| KCB Bank Tanzania Limited           | `KCB`          |
| Coop Bank Tanzania                  | `KILIMANJARO`  |
| Letshego Bank Tanzania Ltd          | `LETSHEGO`     |
| Maendeleo Bank                      | `MAENDELEO`    |
| Mkombozi Commercial Bank Public Ltd | `MKOMBOZI`     |
| Mwalimu Commercial Bank of Tanzania | `MWALIMU`      |
| Mwanga Hakika Microfinance Bank     | `MWANGA`       |
| National Microfinance Bank          | `NMB`          |
| NBC Limited                         | `NBC`          |
| NCBA Bank Tanzania Ltd              | `NCBA`         |
| People's Bank of Zanzibar           | `PBZ`          |
| Stanbic Bank Tanzania               | `STANBIC`      |
| Tanzania Commercial Bank PLC        | `TCB`          |
| Uchumi Commercial Bank              | `UCHUMI`       |
| United Bank for Africa              | `UBA`          |

## 1. Look up account name

```
POST https://api.senjaropay.com/senjaropay/merchant/fundtransfer/api/account-name-lookup
```

Validates the bank account and returns the registered name. Do not create a payout until the name matches what your beneficiary expects.

### Request

```json
{
  "bank": "ABSA",
  "account": "0001234567"
}
```

| Field     | Type   | Required | Description                                                                                       |
| --------- | ------ | -------- | ------------------------------------------------------------------------------------------------- |
| `bank`    | string | Yes      | Bank shortcode from [Bank short codes](#bank-short-codes) (for example `ABSA`, `CRDBBANK`, `NMB`) |
| `account` | string | Yes      | Beneficiary account number                                                                        |

### Response

```json
{
  "status": "success",
  "code": 200,
  "data": {
    "resultcode": "000",
    "result": "SUCCESS",
    "message": "Success",
    "reference": "20261029141001953",
    "transid": "LOOKUP-MOCK-7f3a91c2",
    "bank": "ABSA",
    "account": "0001234567",
    "account_name": "Test Customer",
    "data": {
      "name": "Test Customer"
    }
  }
}
```

| Field                   | Description                                                  |
| ----------------------- | ------------------------------------------------------------ |
| `account_name`          | Confirmed beneficiary name. Pass this as `name` on transfer  |
| `result` / `resultcode` | Lookup outcome. `SUCCESS` / `000` means the account is valid |

```bash
curl -sS -X POST "https://api.senjaropay.com/senjaropay/merchant/fundtransfer/api/account-name-lookup" \
  -H "Content-Type: application/json" \
  -H "x-api-key: ${SENJARO_API_KEY}" \
  -H "x-api-secret: ${SENJARO_API_SECRET}" \
  -d '{"bank":"ABSA","account":"0001234567"}'
```

## 2. Create a bank payout

```
POST https://api.senjaropay.com/senjaropay/merchant/cashout/api/transfer
```

Debits your merchant wallet and sends the funds to the beneficiary bank account. `x-idempotency-key` is **required**.

### Request

```json
{
  "amount": 10000,
  "currency": "TZS",
  "bank": "ABSA",
  "account": "0001234567",
  "name": "Test Customer"
}
```

| Field      | Type    | Required | Description                                                                                     |
| ---------- | ------- | -------- | ----------------------------------------------------------------------------------------------- |
| `amount`   | integer | Yes      | Gross amount to debit, in major units                                                           |
| `currency` | string  | Yes      | Must be `TZS` for bank payouts today                                                            |
| `bank`     | string  | Yes      | Bank shortcode from [Bank short codes](#bank-short-codes). Prefer the same value used at lookup |
| `account`  | string  | Yes      | Beneficiary account number                                                                      |
| `name`     | string  | Yes      | Beneficiary name from account-name lookup                                                       |

### Response

```json
{
  "status": "success",
  "code": 200,
  "data": {
    "success": true,
    "withdrawal_id": "c4fbdacb-6ac4-4159-ad23-50286a001ba4",
    "transaction_reference": "WDMVTEJ1P9VXJ8",
    "amount": 10000,
    "fee": 500,
    "net_amount": 9500,
    "currency": "TZS",
    "payout_amount": 9500,
    "payout_currency": "TZS",
    "fx_rate": null,
    "balance": {
      "currency": "TZS",
      "collections": 50000,
      "bill_payments": 5000,
      "withdrawals": 20000,
      "international_transfers": 10000,
      "available": 15000
    },
    "status": "PROCESSING",
    "account_name": "Test Customer",
    "account": "0001234567",
    "bank": "ABSA"
  }
}
```

| Field                          | Description                                                  |
| ------------------------------ | ------------------------------------------------------------ |
| `withdrawal_id`                | SenjaroPay payout ID. Store for reconciliation               |
| `transaction_reference`        | Provider / ledger reference                                  |
| `amount`                       | Requested debit                                              |
| `fee`                          | Fee charged for this payout                                  |
| `net_amount` / `payout_amount` | Amount the beneficiary receives                              |
| `currency` / `payout_currency` | Wallet and payout currencies. Same for TZS bank payouts      |
| `fx_rate`                      | FX rate when currencies differ. `null` for same-currency TZS |
| `status`                       | `PROCESSING` means the transfer was accepted and is settling |
| `balance.available`            | Remaining available wallet balance after acceptance          |

```bash
curl -sS -X POST "https://api.senjaropay.com/senjaropay/merchant/cashout/api/transfer" \
  -H "Content-Type: application/json" \
  -H "x-api-key: ${SENJARO_API_KEY}" \
  -H "x-api-secret: ${SENJARO_API_SECRET}" \
  -H "x-idempotency-key: $(uuidgen)" \
  -d '{
    "amount": 10000,
    "currency": "TZS",
    "bank": "ABSA",
    "account": "0001234567",
    "name": "Test Customer"
  }'
```

## Errors

| HTTP status | Typical `error_code` | When                                                         |
| ----------- | -------------------- | ------------------------------------------------------------ |
| **400**     | `validation_error`   | Missing field, invalid bank/account, or unsupported currency |
| **401**     | `unauthorized`       | Missing or invalid `x-api-key` or `x-api-secret`             |

```json
{
  "status": "error",
  "code": 400,
  "error_code": "validation_error",
  "message": "currency is required"
}
```

Examples on this page are mock values. Keep API keys in server-side secrets.