For the complete documentation index, see llms.txt. This page is also available as Markdown.

Supported countries and cryptocurrencies

The countries, payment channels, carriers and assets that are live today.

Countries and payment channels

On-ramp means the user pays local currency. Off-ramp means the user receives it.

Country
countryIsoCode
currencyIsoCode
On-ramp channels
Off-ramp channels
Notes

Nigeria

NG

NGN

bank

bank, airtime

On-ramp KYC needs a BVN on file — see KYC flow

Kenya

KE

KES

mobile_money

mobile_money, bank, paybill, buy_goods, airtime

paybill and buy_goods are off-ramp only

Ghana

GH

GHS

mobile_money

mobile_money, airtime

South Africa

ZA

ZAR

bank

bank, airtime

Bank transfers can take up to two business days, so a Friday order may only settle Monday or Tuesday. Currently the only country where off-ramp KYC is switched on. The live bank offer is redirect, not manual.

Tanzania

TZ

TZS

mobile_money

mobile_money, airtime

Uganda

UG

UGX

mobile_money

mobile_money, airtime

Zambia

ZM

ZMW

mobile_money

mobile_money, airtime

Brazil

BR

BRL

bank

bank

Philippines

PH

PHP

bank

bank

Ivory Coast

CI

XOF

mobile_money, digital_wallet

mobile_money, digital_wallet, airtime

Beta. Mobile money here is a redirect channel, not an STK push.

Senegal

SN

XOF

mobile_money, digital_wallet

mobile_money, digital_wallet, airtime

Beta

Benin

BJ

XOF

mobile_money

mobile_money, airtime

Burkina Faso

BF

XOF

mobile_money

mobile_money, airtime

Beta

Cameroon

CM

XAF

mobile_money

mobile_money, airtime

Gabon

GA

XAF

mobile_money

mobile_money

Beta

Republic of the Congo

CG

XAF

mobile_money

mobile_money

Democratic Republic of the Congo

CD

CDF

mobile_money

mobile_money

Beta

Gambia

GM

GMD

mobile_money, digital_wallet

mobile_money, digital_wallet

Beta

Rwanda

RW

RWF

—

airtime

Beta. Mobile money is configured but currently off

Malawi

MW

MWK

—

airtime

Beta

Things to note:

  • XOF and XAF are shared. Several countries use the same currency code, so currencyIsoCode alone does not identify a country. Always send countryIsoCode too.

  • Airtime is off-ramp only, everywhere. A user can be paid out in airtime; they cannot pay with it.

  • digital_wallet is a distinct channel from mobile_money, and it is redirect-based. See Fiat payment channels.

  • Beta means the country is live but young: fewer providers behind it, so an outage is more likely to take the whole country out rather than shift to another provider.

  • A channel listed here can still answer isDepositAllowed: false at any moment if its provider is unhealthy. That is what the endpoint is for.

Mobile carriers

The code column is what you pass as carrierCode. Mobile money, airtime and some digital wallet channels need it; bank does not. Some digital wallet offers carry no carriers at all.

Country
Carrier codes

Nigeria (NG)

ng_mtn, ng_airtel, ng_glo, ng_9mobile

Kenya (KE)

ke_safaricom, ke_airtel, ke_telkom

Ghana (GH)

gh_mtn, gh_vodafone, gh_airtel_tigo

South Africa (ZA)

za_vodacom

Tanzania (TZ)

tz_vodacom, tz_airtel, tz_tigo, tz_halotel

Uganda (UG)

ug_mtn, ug_airtel

Zambia (ZM)

zm_mtn, zm_airtel, zm_zamtel

Ivory Coast (CI)

ci_mtn, ci_orange, ci_moov, ci_wave

Senegal (SN)

sn_orange, sn_expresso, sn_wave

Benin (BJ)

bj_mtn, bj_moov

Burkina Faso (BF)

bf_orange, bf_moov

Cameroon (CM)

cm_mtn, cm_orange

Gabon (GA)

gb_airtel

Republic of the Congo (CG)

cg_mtn, cg_airtel

DR Congo (CD)

cd_vodacom, cd_orange, cd_airtel

Gambia (GM)

gm_africell

Rwanda (RW)

rw_mtn, rw_airtel

Malawi (MW)

mw_airtel, mw_tnm

Two traps in that table.

Gabon's carrier code really is gb_airtel, not ga_airtel. Send it exactly as the API returns it.

A carrier being configured for a country does not make it orderable. sn_wave is the current example: every Senegalese offer carrying it is switched off, so the live Senegalese wallet route does not use it. Take the carrier list from carriers on Get available currencies, which is per channel, rather than from the country.

Networks and assets

The currencyCode you pass to the API is NETWORK_ASSET, for example POLYGON_USDT.

Network
Assets

ARBITRUM

NATIVE, USDC, USDT

AVALANCHE

NATIVE, USDC, USDT

BASE

NATIVE, USDC, XDUS

BNB

NATIVE, USDC, USDT

CELO

NATIVE, CUSD, USDC, USDT, CKES, CGHS

ETHEREUM

NATIVE, USDC, USDT, RLUSD, XDUS

LISK

USDT

OPTIMISM

NATIVE, USDC, USDT

POLYGON

NATIVE, USDC, USDT, XDUS

SOLANA

NATIVE, USDC, USDT

STELLAR

NATIVE, USDC

TEMPO

PATHUSD, USDC_E

TON

NATIVE, USDT, USDE

TRON

NATIVE, USDT

XRP

RLUSD

NATIVE is the network's own coin — ETH on Ethereum, SOL on Solana, CELO on Celo, and so on. It has no contract address.

Almost every pair works in both directions, on-ramp and off-ramp. Two do not, as things stand:

  • STELLAR_NATIVE cannot be paid out, so it is off-ramp only — a user can sell XLM but not buy it.

  • TEMPO_USDC_E cannot be deposited, so it is on-ramp only — a user can buy it but not sell it.

Both are one flag away from changing in either direction, which is the argument for reading isDepositAllowed and isPayoutAllowed per pair instead of trusting a list.

Contract addresses

Production addresses. Sandbox uses different ones, so read currencyDetails.contractAddress from Get available currencies rather than hard-coding either set.

currencyCode
Contract

ARBITRUM_USDC

0xaf88d065e77c8cC2239327C5EDb3A432268e5831

ARBITRUM_USDT

0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9

AVALANCHE_USDC

0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E

AVALANCHE_USDT

0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7

BASE_USDC

0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913

BASE_XDUS

0x293d36b129F1E6538A036318499d83BD06eB17E9

BNB_USDC

0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d

BNB_USDT

0x55d398326f99059fF775485246999027B3197955

CELO_CUSD

0x765DE816845861e75A25fCA122bb6898B8B1282a

CELO_USDC

0xcebA9300f2b948710d2653dD7B07f33A8B32118C

CELO_USDT

0x48065fbbe25f71c9282ddf5e1cd6d6a887483d5e

CELO_CKES

0x456a3d042c0dbd3db53d5489e98dfb038553b0d0

CELO_CGHS

0xfAeA5F3404bbA20D3cc2f8C4B0A888F55a3c7313

ETHEREUM_USDC

0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48

ETHEREUM_USDT

0xdac17f958d2ee523a2206206994597c13d831ec7

ETHEREUM_RLUSD

0x8292bb45bf1ee4d140127049757c2e0ff06317ed

ETHEREUM_XDUS

0xa8719F9F4c23266a214112AAf4902c1000c02E7c

LISK_USDT

0x05D032ac25d322df992303dCa074EE7392C117b9

OPTIMISM_USDC

0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85

OPTIMISM_USDT

0x94b008aA00579c1307B0EF2c499aD98a8ce58e58

POLYGON_USDC

0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359

POLYGON_USDT

0xc2132D05D31c914a87C6611C10748AEb04B58e8F

POLYGON_XDUS

0xa8719F9F4c23266a214112AAf4902c1000c02E7c

SOLANA_USDC

EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v

SOLANA_USDT

Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB

STELLAR_USDC

GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN

TEMPO_PATHUSD

0x20c0000000000000000000000000000000000000

TEMPO_USDC_E

0x20c000000000000000000000b9537d11c60e8b50

TON_USDT

EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs

TON_USDE

EQAIb6KmdfdDR7CN1GBqVJuP25iCnLKCvBlJ07Evuu2dzP5f

TRON_USDT

TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t

XRP_RLUSD

524C555344000000000000000000000000000000

Some networks route by a memo or tag rather than by address alone — Stellar and TON are the ones the Pay Widget handles, via its memo URL param. Over the API, blockchainMemo is offered in fieldsToCreateOrder on every crypto payout; fill it in whenever the destination needs one. A transfer to an exchange without the right memo is usually unrecoverable.

Last updated