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

# Accept payments

> Three ways money comes in — pull a mobile money charge, give a bank account number, or give a crypto address — and when to use each.

Money arrives over three rails, and the API models each one honestly rather than pretending they're the same.

|                | Mobile money charge                                  | Virtual account                                                  | Crypto address                        |
| -------------- | ---------------------------------------------------- | ---------------------------------------------------------------- | ------------------------------------- |
| Endpoint       | `POST /v1/collections`                               | `POST /v1/virtual-accounts`                                      | `POST /v1/crypto-addresses`           |
| Who initiates  | **You** — the payer approves a prompt                | **The payer** transfers from their bank app                      | **The payer** sends from their wallet |
| Amount         | fixed by you                                         | whatever they send                                               | whatever they send                    |
| Payer needs    | a phone number                                       | a bank app                                                       | a wallet                              |
| Typical timing | seconds to minutes                                   | minutes                                                          | seconds to minutes (chain-dependent)  |
| Best for       | checkout, subscriptions, invoices with a known payer | top-ups, bank-first markets (Nigeria), amounts you don't control | cross-border, crypto-native customers |

If you'd rather not choose — or want all three on one page — use [payment links](/guides/payment-links) and let the payer pick.

## Mobile money charge

You know the payer's number and the amount. You ask; they approve on their phone.

```bash theme={null}
POST /v1/collections
{
  "from": { "code": "gh_mtn", "accountNumber": "233559630374", "amount": 85, "currency": "GHS" },
  "externalReference": "sub-2026-08-ama",
  "narration": "August subscription"
}
```

The collection is `pending` while the prompt sits on their phone; it becomes `completed` (balance credited, `collection.completed` fires) or `failed` (declined, timed out, wallet error — `collection.failed`). A timeout is normal: people put their phone down. Let them retry.

## Virtual account

A real bank account number that belongs to your organization. Give it to a customer; whatever they transfer credits your balance.

```bash theme={null}
POST /v1/virtual-accounts
{ "currency": "NGN", "externalReference": "customer-8812" }
→ { "virtualAccount": { "bank": "…", "accountNumber": "9070012345678", "accountName": "…", "status": "active" } }
```

Create one **per customer** and store the mapping — the `externalReference` is yours, so you can tell later whose money arrived. Each inbound transfer fires `account.credited` and shows up as a collection. Pause an account with `PATCH … { "status": "paused" }`.

This is the rail that makes Nigeria work, and the one to reach for whenever the payer, not you, decides the amount.

## Crypto address

A deposit address for one asset on one chain.

```bash theme={null}
POST /v1/crypto-addresses
{ "currency": "USDC", "chain": "Solana", "externalReference": "customer-8812" }
→ { "address": { "address": "G3eaq…", "tag": null, "currency": "USDC", "chain": "Solana" } }
```

Creating the same (currency, chain) pair again returns the existing address. Deposits are detected on-chain, wait for confirmations, then credit your balance — in the deposit's asset, converted at the live rate if your balance is fiat. The assets and chains available on each stack come from `GET /v1/capabilities` → `deposits` (testnets on sandbox).

**Tell your customer the asset and the chain.** USDC sent on the wrong network to a Solana address is gone.

## Funding your own balance

The same two mechanisms are how *you* top up in production: create a virtual account or a crypto address in your own name and transfer to it — or use **Add funds** in the dashboard, which does exactly that.

## What "received" means

All three end the same way: a ledger credit on your balance (`available` rises), an `account.credited` webhook, and a row in `GET /v1/transactions`. Reconcile on `externalReference` where you set one, or on the virtual account / address id where the payer chose the amount.
