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

# Send to Africa with Zuba

> How to integrate Privy and Zuba to pay out USDC and USDT to bank accounts and mobile money across Africa

[Zuba](https://zuba.com) is Privy's preferred partner for African-corridor payouts. With Privy powering your wallets and Zuba handling the last mile, you can move stablecoins into local currency across Africa.

This recipe walks through the full flow:

1. Create a wallet with Privy
2. Fund your Zuba account with USDC/USDT from that wallet
3. Call the Zuba Payout API to pay out across Africa
4. Track the payout to completion

## Prerequisites

* A Privy app with your **App ID** and **App Secret** from the [Privy Dashboard](https://dashboard.privy.io)
* A Zuba account with API credentials (see [Zuba Authentication](https://docs.zuba.com/authentication))

Zuba uses OAuth 2.0 client credentials. Exchange your Client ID and Secret for a bearer token (valid 24 hours):

```bash cURL theme={"system"}
curl -X POST "https://zuba-test.us.auth0.com/oauth/token" \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "YOUR_ZUBA_CLIENT_ID",
    "client_secret": "YOUR_ZUBA_CLIENT_SECRET",
    "audience": "https://api.zuba.com",
    "grant_type": "client_credentials"
  }'
```

Use the returned `access_token` as `Authorization: Bearer <token>` on every Zuba request below.

## 1. Create a wallet with Privy

If your users already have Privy embedded wallets, skip ahead. Any Privy wallet holding USDC or USDT works. To create a server wallet:

```bash cURL theme={"system"}
curl -X POST "https://api.privy.io/v1/wallets" \
  -u "PRIVY_APP_ID:PRIVY_APP_SECRET" \
  -H "privy-app-id: PRIVY_APP_ID" \
  -H "Content-Type: application/json" \
  -d '{"chain_type": "ethereum"}'
```

See [Privy wallet docs](/wallets/overview) for embedded and user-owned wallet setups.

## 2. Fund your Zuba account

Provision a deposit address on the network you want to fund from:

```bash cURL theme={"system"}
curl -X POST "https://api.zuba.com/v1/deposits/crypto-address" \
  -H "Authorization: Bearer YOUR_ZUBA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"network": "eip155:1"}'
```

```json Response theme={"system"}
{
  "network": "eip155:1",
  "address": "0x1234567890abcdef1234567890abcdef12345678"
}
```

The address is reusable, so you can send to it as many times as you like. For EVM networks, the same address is valid on all supported EVM chains.

Supported networks and tokens:

| Network  | `network` value                           | Tokens     |
| -------- | ----------------------------------------- | ---------- |
| Ethereum | `eip155:1`                                | USDC, USDT |
| Base     | `eip155:8453`                             | USDC       |
| Solana   | `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp` | USDC, USDT |
| Tron     | `tron:mainnet`                            | USDT       |

Now send USDC/USDT from your Privy wallet to that address using Privy's transaction APIs. See [sending transactions on Ethereum](/wallets/using-wallets/ethereum/send-a-transaction) or [Solana](/wallets/using-wallets/solana/send-a-transaction).

Once the transfer confirms on-chain, the funds appear on your Zuba balance:

```bash cURL theme={"system"}
curl -X GET "https://api.zuba.com/ledger/balances" \
  -H "Authorization: Bearer YOUR_ZUBA_TOKEN"
```

## 3. Pay out across Africa

One request does it all: pass the beneficiary's local payment details inline. `inputCurrency` is the balance you're paying from (your USDC/USDT), while `currency` and `amount` are what the beneficiary receives. Zuba handles the conversion:

```bash cURL theme={"system"}
curl -X POST "https://api.zuba.com/v1/payouts" \
  -H "Authorization: Bearer YOUR_ZUBA_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 8f7d2a4e-payout-001" \
  -d '{
    "clientRef": "PAYOUT-001",
    "amount": "150000.00",
    "inputCurrency": "USDC",
    "currency": "NGN",
    "route": "bank_transfer",
    "beneficiary": {
      "name": "Amara Okafor",
      "country": "NG",
      "accounts": [
        {
          "type": "bank_account",
          "currency": "NGN",
          "data": {
            "bankCode": "044",
            "crAccount": "1234567890"
          }
        }
      ]
    },
    "reference": "Salary March",
    "description": "Monthly payroll"
  }'
```

For repeat payouts, create the beneficiary once via [`POST /v1/beneficiaries`](https://docs.zuba.com/concepts/payouts#beneficiaries) and reference it with `"beneficiary": { "id": "..." }`.

Use `route: "mobile_money"` for mobile money corridors (GHS, XOF, XAF). Field requirements per corridor are available at [`GET /v1/payouts/requirements`](https://docs.zuba.com/api-reference) and in the [Zuba payout docs](https://docs.zuba.com/concepts/payouts).

## 4. Track the payout

Register a webhook endpoint and listen for payout lifecycle events:

```bash cURL theme={"system"}
curl -X POST "https://api.zuba.com/v1/webhooks" \
  -H "Authorization: Bearer YOUR_ZUBA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://yourapp.com/webhooks/zuba", "events": ["payout.paid", "payout.failed"]}'
```

```json Event payload theme={"system"}
{
  "id": "evt_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "type": "payout.paid",
  "createdAt": "2026-03-23T14:30:00.000Z",
  "data": {
    "id": "pay_abc123",
    "clientRef": "PAYOUT-001",
    "amount": "150000.00",
    "currency": "NGN",
    "status": "paid"
  }
}
```

Verify deliveries with the `X-Zuba-Signature` header (see [Zuba webhook docs](https://docs.zuba.com/guides/webhooks)). You can also poll `GET /v1/payouts/{id}`.

## Test it in sandbox

Everything above works against `https://api.sandbox.zuba.com` with sandbox credentials. Magic beneficiary account numbers give deterministic outcomes (`0000000000` → `paid`, `0000000001` → `failed`). See the [sandbox testing guide](https://docs.zuba.com/guides/sandbox-testing).

That's it: a Privy wallet, one deposit address, and one API call to reach bank accounts and mobile money wallets across Africa.
