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

# Ramps

> Let your customers buy stablecoins with local currency (on-ramp), or sell them for a bank payout (off-ramp). The money goes straight to them, not through your balance.

## The flow

| Step | On-ramp | Off-ramp |
| - | - | - |
| Quote | How much USDC ₦150,000 buys | How much naira 100 USDC pays out |
| Order | Returns a bank account to pay into | Returns an address to send stablecoin to |
| Customer pays | Bank transfer | On-chain transfer |
| Settles | Stablecoin to their wallet | Local currency to their bank account |

## 1. Quote

Quotes include fees. Show `destination.amount` to your customer before they commit.

```bash cURL theme={null}
curl -X POST "https://api.pay.flipeet.io/api/v1/public/on-ramp/quote" \
  -H "x-api-key: $FLIPEET_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "amount": 150000,
  "asset": "usdc",
  "network": "base",
  "currency": "NGN",
  "country": "NG",
  "channel": "BANK"
}'
```

```javascript Node.js theme={null}
const response = await fetch("https://api.pay.flipeet.io/api/v1/public/on-ramp/quote", {
  method: "POST",
  headers: {
    "x-api-key": process.env.FLIPEET_SECRET_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "amount": 150000,
    "asset": "usdc",
    "network": "base",
    "currency": "NGN",
    "country": "NG",
    "channel": "BANK"
  }),
});
const { data } = await response.json();
```

```python Python theme={null}
import os
import requests

response = requests.post(
    "https://api.pay.flipeet.io/api/v1/public/on-ramp/quote",
    headers={"x-api-key": os.environ["FLIPEET_SECRET_KEY"]},
    json={
        "amount": 150000,
        "asset": "usdc",
        "network": "base",
        "currency": "NGN",
        "country": "NG",
        "channel": "BANK"
    },
)
data = response.json()["data"]
```

```json Response theme={null}
{
  "message": "Quote retrieved successfully",
  "data": {
    "success": true,
    "data": {
      "rate": 1500,
      "fee": { "total": 750, "currency": "NGN" },
      "fee_inclusive": true,
      "source": { "amount": 150000, "currency": "NGN" },
      "destination": { "amount": 99.5, "currency": "USDC" }
    }
  }
}
```

`fee.total` is everything your customer pays in fees. With `fee_inclusive` true it's already taken out of `destination.amount`.

For an off-ramp quote, send the stablecoin amount to `/api/v1/public/off-ramp/quote` with the same fields.

## 2. Create the order

`reference` is your own ID for the order, in any format you like (for example `ramp_901` or your order number). Each one can be used once per business; a repeat gets `409`. Every response and webhook for the order carries it. `callback_url` receives every status change for the order.

> [tab] On-ramp
>
> The stablecoin goes to `beneficiary.wallet_address`.
>
> ```bash cURL theme={null}
> curl -X POST "https://api.pay.flipeet.io/api/v1/public/on-ramp/initialize" \
>   -H "x-api-key: $FLIPEET_SECRET_KEY" \
>   -H "Content-Type: application/json" \
>   -d '{
>   "amount": 150000,
>   "asset": "usdc",
>   "network": "base",
>   "currency": "NGN",
>   "country": "NG",
>   "channel": "BANK",
>   "reference": "ramp_901",
>   "callback_url": "https://app.example.com/hooks/flipeet",
>   "beneficiary": {
>     "holder_type": "INDIVIDUAL",
>     "holder_name": "Ngozi Eze",
>     "wallet_address": "0x5aE1c3B0d2F4e6A8b0C2d4E6f8A0b2C4d6E89c21"
>   }
> }'
> ```
>
> ```javascript Node.js theme={null}
> const response = await fetch("https://api.pay.flipeet.io/api/v1/public/on-ramp/initialize", {
>   method: "POST",
>   headers: {
>     "x-api-key": process.env.FLIPEET_SECRET_KEY,
>     "Content-Type": "application/json",
>   },
>   body: JSON.stringify({
>     "amount": 150000,
>     "asset": "usdc",
>     "network": "base",
>     "currency": "NGN",
>     "country": "NG",
>     "channel": "BANK",
>     "reference": "ramp_901",
>     "callback_url": "https://app.example.com/hooks/flipeet",
>     "beneficiary": {
>       "holder_type": "INDIVIDUAL",
>       "holder_name": "Ngozi Eze",
>       "wallet_address": "0x5aE1c3B0d2F4e6A8b0C2d4E6f8A0b2C4d6E89c21"
>     }
>   }),
> });
> const { data } = await response.json();
> ```
>
> ```python Python theme={null}
> import os
> import requests
>
> response = requests.post(
>     "https://api.pay.flipeet.io/api/v1/public/on-ramp/initialize",
>     headers={"x-api-key": os.environ["FLIPEET_SECRET_KEY"]},
>     json={
>         "amount": 150000,
>         "asset": "usdc",
>         "network": "base",
>         "currency": "NGN",
>         "country": "NG",
>         "channel": "BANK",
>         "reference": "ramp_901",
>         "callback_url": "https://app.example.com/hooks/flipeet",
>         "beneficiary": {
>             "holder_type": "INDIVIDUAL",
>             "holder_name": "Ngozi Eze",
>             "wallet_address": "0x5aE1c3B0d2F4e6A8b0C2d4E6f8A0b2C4d6E89c21"
>         }
>     },
> )
> data = response.json()["data"]
> ```

> [tab] Off-ramp
>
> The local currency goes to the bank account in `beneficiary`. Get the `bank_code` from [List institutions](https://docs.flipeet.io/api-reference/ramps/list-institutions.md), and check the name with [Verify an account](https://docs.flipeet.io/api-reference/ramps/verify-an-account.md).
>
> ```bash cURL theme={null}
> curl -X POST "https://api.pay.flipeet.io/api/v1/public/off-ramp/initialize" \
>   -H "x-api-key: $FLIPEET_SECRET_KEY" \
>   -H "Content-Type: application/json" \
>   -d '{
>   "amount": 100,
>   "asset": "usdc",
>   "network": "base",
>   "currency": "NGN",
>   "country": "NG",
>   "channel": "BANK",
>   "reference": "ramp_902",
>   "callback_url": "https://app.example.com/hooks/flipeet",
>   "beneficiary": {
>     "holder_type": "INDIVIDUAL",
>     "holder_name": "Chidi Okafor",
>     "account_number": "0123456789",
>     "bank_code": "044"
>   }
> }'
> ```
>
> ```javascript Node.js theme={null}
> const response = await fetch("https://api.pay.flipeet.io/api/v1/public/off-ramp/initialize", {
>   method: "POST",
>   headers: {
>     "x-api-key": process.env.FLIPEET_SECRET_KEY,
>     "Content-Type": "application/json",
>   },
>   body: JSON.stringify({
>     "amount": 100,
>     "asset": "usdc",
>     "network": "base",
>     "currency": "NGN",
>     "country": "NG",
>     "channel": "BANK",
>     "reference": "ramp_902",
>     "callback_url": "https://app.example.com/hooks/flipeet",
>     "beneficiary": {
>       "holder_type": "INDIVIDUAL",
>       "holder_name": "Chidi Okafor",
>       "account_number": "0123456789",
>       "bank_code": "044"
>     }
>   }),
> });
> const { data } = await response.json();
> ```
>
> ```python Python theme={null}
> import os
> import requests
>
> response = requests.post(
>     "https://api.pay.flipeet.io/api/v1/public/off-ramp/initialize",
>     headers={"x-api-key": os.environ["FLIPEET_SECRET_KEY"]},
>     json={
>         "amount": 100,
>         "asset": "usdc",
>         "network": "base",
>         "currency": "NGN",
>         "country": "NG",
>         "channel": "BANK",
>         "reference": "ramp_902",
>         "callback_url": "https://app.example.com/hooks/flipeet",
>         "beneficiary": {
>             "holder_type": "INDIVIDUAL",
>             "holder_name": "Chidi Okafor",
>             "account_number": "0123456789",
>             "bank_code": "044"
>         }
>     },
> )
> data = response.json()["data"]
> ```

Show `data.deposit` to your customer: the bank, account number and exact amount for an on-ramp, or the address and amount for an off-ramp. Deposit details are for this order only, and they expire.

## 3. Follow its status

Your `callback_url` gets the order each time it moves, with its `reference` and `status`:

| `status` | Means |
| - | - |
| `AWAITING_DEPOSIT` | Waiting for the customer to pay. |
| `COMPLETED` | Paid and delivered to the customer. |
| `FAILED` | Couldn't complete. Nothing was delivered. |
| `EXPIRED` | The customer didn't pay in time. |

> [!NOTE]
>
> Ramp callbacks are signed the same way as all webhooks. See [Verify signatures](https://docs.flipeet.io/webhooks.md#verify-signatures).

## Networks and tokens

Send `network` and `asset` as below. Not every token is on every network.

| Network | `network` | USDC | USDT | cNGN |
| :- | :- | :-: | :-: | :-: |
| Arbitrum | `arbitrum` | ✓ | ✓ | |
| Avalanche | `avalanche` | ✓ | ✓ | |
| Base | `base` | ✓ | | ✓ |
| BNB Chain | `bnb-smart-chain` or `bsc` | ✓ | ✓ | ✓ |
| Celo | `celo` | ✓ | ✓ | |
| Ethereum | `ethereum` | ✓ | ✓ | |
| Gnosis | `gnosis` | ✓ | ✓ | |
| Monad | `monad` | ✓ | ✓ | |
| Optimism | `optimism` | ✓ | ✓ | |
| Plasma | `plasma` | | ✓ | |
| Polygon | `polygon` | ✓ | ✓ | |
| Solana | `solana` | ✓ | ✓ | |
| Tron | `tron` | | ✓ | |

cNGN is bought and sold for naira (NGN) only.

## Countries and banks

Use [List institutions](https://docs.flipeet.io/api-reference/ramps/list-institutions.md) to see the banks for a country. If a network, asset, currency or channel isn't supported, you get `400` with a message saying which.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.