One API for pan-African payments
Globpay is a multi-country, multi-currency payment platform.
Pass currency + operator (what the customer uses).
Always discover enabled markets with GET /v1/operators.
Mental model
Two fields you control on every payment. Globpay routes to the right rail for that market.
| Layer | Field | Meaning | Examples |
|---|---|---|---|
| Currency / country | currency |
Local money unit | TZS, KES, UGX, MWK, BWP, GHS, XOF, XAF, CDF, NGN, RWF, ZAR |
| Operator | operator |
Brand / network the customer uses | mpesa, mpesake, airtelke, yc_ug_momo |
Markets & currencies
One Globpay API covers all markets below. Use the operator + currency for that country. New markets appear in GET /v1/operators when enabled for your account.
| Currency | Country | Phone prefix | Operators | Collection UX | Status |
|---|---|---|---|---|---|
TZS | Tanzania | 255 |
mpesa, tigopesa, airtelmoney, halopesa |
USSD push | Live |
KES | Kenya | 254 |
mpesake, airtelke, pesalink |
STK Push / Airtel prompt / bank | Live |
UGX | Uganda | 256 |
yc_ug_momo |
MoMo prompt | Live |
MWK | Malawi | 265 |
yc_mw_momo |
MoMo prompt | Live |
BWP | Botswana | 267 |
yc_bw_momo |
MoMo prompt | Live |
GHS | Ghana | 233 |
tp_gh_mtn |
MoMo prompt | Live |
XOF | CI / BF / TG | country dial | tp_ci_*, tp_bf_*, tp_tg_tmoney |
MoMo prompt; tp_ci_wave → payment_url redirect |
Live |
XOF | Mali | 223 |
swychr_ml_orange, swychr_ml_moov, swychr_ml_wave |
MoMo prompt (Swychr — not TransactPay) | Live |
XOF | Benin | 229 |
swychr_bj_mtn, swychr_bj_moov |
MoMo prompt (Swychr — not TransactPay) | Live |
XOF | Niger | 227 |
swychr_ne_airtel |
MoMo prompt (Swychr) | Live |
GNF | Guinea (Conakry) | 224 |
swychr_gn_mtn, swychr_gn_orange |
MoMo prompt (Swychr; Wave not available) | Live |
XAF | Congo-Brazzaville | 242 |
swychr_cg_mtn, swychr_cg_airtel |
MoMo prompt (Swychr) | Live |
XAF | Gabon | 241 |
swychr_ga_airtel, swychr_ga_moov |
MoMo prompt (Swychr) | Live |
XAF | Cameroon | 237 |
tp_cm_mtn, tp_cm_orange |
MoMo prompt | Live |
CDF | DRC | 243 |
tp_cd_airtel, tp_cd_orange, tp_cd_mpesa |
MoMo prompt | Live |
NGN | Nigeria | 234 |
tp_ng_bank, yc_ng_momo |
Bank transfer VA / P2P | Live |
RWF | Rwanda | 250 |
yc_rw_momo |
MoMo prompt | Live |
ZAR | South Africa | 27 |
yc_za_momo |
EFT | Live |
XOF | Senegal | 221 |
hayb_sn_* checkout, or swychr_sn_* direct. Orange direct accepts optional otp |
Merchant chooses checkout or direct | Live |
USD | Global / US VA | — | glideswipe |
Virtual account | Planned |
Phone & money rules
- Prefer full international digits without
+(e.g.256782674977,254712345678). - Local numbers starting with
0are rewritten fromcurrency(e.g.0712…+KES→254712…). - Amounts are in the local currency of the operator — no FX on collection/disbursement.
- Minimums vary by market (e.g. Uganda MoMo often 15,000 UGX; Malawi MoMo often 5,000 MWK; Botswana MoMo often 150 BWP).
Authentication
Most merchants send an API key and API secret. Globpay can require HMAC-SHA256 request signatures for a single merchant from Admin → merchant review → Signed API requests. Other merchants stay on the key and secret. The same rule applies to /api/v1 and /api/v2.
Default — API key and secret
Signed requests — enabled per merchant
When the admin switch is on, omit X-API-Secret. Sign the raw body with the signing secret Globpay issued for that account (shown once in the admin panel). It is not the webhook secret.
Step-by-step samples (cURL, PHP, Node, Python): API docs → Authentication.
Quick start
- Create a Globpay merchant account and get API keys.
GET /v1/operators— see which countries / currencies / operators your account can use.- Collect or disburse with
POST /v1/collectionorPOST /v1/disbursement— includecurrency. - Listen for webhooks and poll
GET /v1/status/{request_ref}. - Credit your user only after
status=completed(never on webhook alone).
Tanzania mobile money
M-Pesa / Tigo / Airtel / HaloPesa in Tanzania (TZS). Customer gets a USSD prompt.
| Currency | TZS |
|---|---|
| Phone | 255XXXXXXXXX (12 digits) |
| Operators | mpesa, tigopesa, airtelmoney, halopesa |
Collect (USSD push)
/v1/collectionResponse includes request_ref and status: "processing". Flow: processing → customer confirms USSD → completed | failed.
Disburse
/v1/disbursementKenya mobile money
M-Pesa Kenya (KES). Globpay sends an STK Push (Lipa na M-Pesa prompt) — not manual paybill by default.
| Operator | mpesake |
|---|---|
| Currency | KES |
| Phone | 2547XXXXXXXX |
Collect (STK Push)
/v1/collectionKeep KES wallets separate from TZS in your UI.
Disburse (KES M-Pesa)
Kenya Airtel Money
Airtel Money Kenya (KES). globpay.app calls api.globpay.ai; Intouch stays on the old stack and webhooks back through .ai. Pass operator=airtelke. Do not use mpesake for Airtel numbers.
| Operator | airtelke |
|---|---|
| Channel | intouch_ke |
| Currency | KES |
| Phone | 2547XXXXXXXX / 25410XXXXXXX (prefixes 010, 073, 0750–0756, 078) |
| Collection UX | Airtel Money prompt — customer confirms on the phone |
Collect (Airtel prompt)
/v1/collectionAuth is your Globpay merchant API key + secret. Typical 201 is status: processing. Credit your user only after webhook or GET /v1/status/{request_ref} shows completed.
Payout (NCBA B2C — same channel as M-Pesa)
Airtel Kenya collection stays on globpay.ai → Intouch. Payout uses the same NCBA B2C rail as mpesake. Still pass operator=airtelke so funds leave the Airtel Kenya disbursement wallet.
/v1/disbursementKenya bank transfer (PesaLink)
Pay any Kenya bank account via NCBA PesaLink. Requires bank selection (BIC) + account number + beneficiary name.
| Operator | pesalink |
|---|---|
| Channel | ncba_alias |
| Currency | KES |
| Limits | 50 – 999,999 KES · immediate · 24/7 |
| Banks list | GET /v1/merchant/ncba/banks — returns code + bic |
List supported banks + BIC
/v1/merchant/ncba/banksCall this before creating a PesaLink payout. Map banks[].code → bank_code and banks[].bic → bank_bic. Prefer rows where bic is not null.
Disburse to bank
/v1/disbursementProvide either bank_code or bank_bic (both accepted). Phone is not required for PesaLink.
Settle to saved bank
/v1/settlementKenya bank accounts must include swift_code (use banks[].bic from the banks list). Admin approval releases the PesaLink transfer.
Senegal mobile money
Orange Money, Wave and Free Money in Senegal (XOF). hayb_sn_* opens checkout. swychr_sn_orange and swychr_sn_wave are a direct phone prompt. Orange requires otp. swychr_sn_free returns checkout_url and does not take otp. Send a code that GET /v1/operators returns.
| Currency | XOF |
|---|---|
| Phone | 221XXXXXXXXX (12 digits) |
| Orange | hayb_sn_orange checkout, or swychr_sn_orange direct with optional otp |
| Wave | hayb_sn_wave checkout, or swychr_sn_wave direct |
| Free Money | hayb_sn_free or swychr_sn_free — redirect to checkout_url. No otp |
Collect
/v1/collectionOrange and Wave direct are a phone prompt. On Orange (swychr_sn_orange) send required otp (4–8 digits the customer already has from Orange Money). Globpay forwards it as customer.otp. Wave does not use otp. Free Money (swychr_sn_free) does not take otp; redirect the customer to checkout_url.
Response may include a checkout_url — redirect the customer there to approve the payment.
After checkout, the customer is returned to your success_url / failed_url
(Globpay appends ?ref=…&status=success|failed). If omitted, Globpay hosted result pages are shown.
Browser redirects are for UX only — confirm payment via webhook + GET /v1/status/{request_ref}.
Disburse (XOF)
/v1/disbursementKeep XOF wallets separate from other currencies. Payouts are debited from your Senegal disbursement wallet.
West & Central Africa + Nigeria
Ghana (GHS), Côte d’Ivoire / Burkina / Togo (XOF), Cameroon (XAF), DRC (CDF), and Nigeria (NGN bank transfer). Swychr markets: Mali, Benin, Niger (XOF), Guinea (GNF), Congo-Brazzaville / Gabon (XAF). Collection on all listed rails. Disbursement on GHS, Swychr corridors, and XOF MoMo. Cameroon, DRC, and Nigeria bank VA stay collection-only. Kenya and Senegal use their own operators.
| Country | Currency | Phone | Operators |
|---|---|---|---|
| Ghana | GHS | 233 | tp_gh_mtn |
| Côte d’Ivoire | XOF | 225 | tp_ci_mtn / moov / orange / wave |
| BF / TG | XOF | country dial | tp_bf_*, tp_tg_tmoney |
| Mali | XOF | 223 | swychr_ml_orange, swychr_ml_moov, swychr_ml_wave |
| Benin | XOF | 229 | swychr_bj_mtn, swychr_bj_moov |
| Niger | XOF | 227 | swychr_ne_airtel |
| Guinea (Conakry) | GNF | 224 | swychr_gn_mtn, swychr_gn_orange |
| Congo-Brazzaville | XAF | 242 | swychr_cg_mtn, swychr_cg_airtel |
| Gabon | XAF | 241 | swychr_ga_airtel, swychr_ga_moov |
| Cameroon | XAF | 237 | tp_cm_mtn, tp_cm_orange |
| DRC | CDF | 243 | tp_cd_airtel, tp_cd_orange, tp_cd_mpesa |
| Nigeria | NGN | 234 | tp_ng_bank (bank transfer VA) |
Collect — Ghana
/v1/collectionWave CI note: tp_ci_wave returns payment_url / checkout_url. Redirect the customer there (hosted Wave checkout). Other CI rails (tp_ci_mtn / moov / orange) use a MoMo prompt — payment_url is null.
Nigeria note: tp_ng_bank returns temporary account details in operator_response.bankInfo. Ask the customer to transfer the exact amount. Collection only — no TransactPay bank payout on this rail.
Disburse — Mali (Swychr) / Ghana MoMo
/v1/disbursementDiscover enabled tp_* codes with GET /v1/operators. Treat any channel on responses as opaque.
Other Africa markets
Uganda, Malawi, Botswana, Rwanda, Nigeria, South Africa, and more as Globpay enables them.
Ghana and West/Central Africa use operators above.
Same collection/disbursement API; change currency + operator + phone prefix.
| Code | Country | Currency | Rail |
|---|---|---|---|
yc_ug_momo | Uganda | UGX | Mobile money |
yc_mw_momo | Malawi | MWK | Mobile money (Airtel / TNM) |
yc_bw_momo | Botswana | BWP | Mobile money (MyZaka / Orange) |
yc_rw_momo | Rwanda | RWF | Mobile money |
yc_ng_momo | Nigeria | NGN | P2P / bank (Yellow Card) |
yc_za_momo | South Africa | ZAR | EFT |
GET /v1/operators are enabled for your account.
Collect — Uganda
/v1/collectionSame endpoint — other markets
Nigeria note: yc_ng_momo is bank/P2P (not MoMo). Pass the customer NUBAN in phone and the bank network_id from your enabled networks. For TransactPay temporary bank VA, use tp_ng_bank with the customer phone — see West & Central Africa + Nigeria.
Malawi / Botswana: MoMo rails — pass international phone digits (265… / 267…). Optionally pass network_id when the customer’s wallet network is known (Airtel/TNM or MyZaka/Orange).
Disburse — Malawi
Disburse — Botswana
Disburse — Uganda
Virtual accounts Live
Create a dedicated account number customers can pay into.
Share deposit_instructions with the payer — Globpay credits your wallet when the deposit webhook arrives
(no /v1/collection call per payment). Same capability as the merchant dashboard Virtual accounts tab.
| Item | Value |
|---|---|
| Create | POST /v1/virtual-accounts |
| List / show | GET /v1/virtual-accounts, GET /v1/virtual-accounts/{vaNumber} |
| Invoice | POST /v1/invoice with currency KES / USD / EUR (optional payment_method: "virtual_account") |
| Paylink | POST /v1/paylink with payment_method: "virtual_account" — virtual_account_id is optional |
| NCBA banks | GET /v1/merchant/ncba/banks — payer bank picker |
| Currencies | KES (M-Pesa PayBill or SWIFT), USD / EUR (NCBA SWIFT) |
| Limit | One active VA per currency |
NCBA deposit banks / PesaLink bank list
List banks supported for NCBA deposits and PesaLink payouts. Each row includes code, name, bic, and country:
/v1/merchant/ncba/banksOptional query: ?fresh=1 bypasses cache. For PesaLink disbursements, send code as bank_code or bic as bank_bic.
Create VA
/v1/virtual-accountsHow the payer pays (KES)
- M-Pesa → Lipa na M-Pesa → Pay Bill
- Business number =
deposit_instructions.paybill - Account / BillRef =
deposit_instructions.account_number(the VA) - Enter amount → PIN — wallet credits automatically
Or SWIFT / bank transfer: account number and payment reference = VA number; bank NCBA BANK; SWIFT CBAFKENXX; bank code 07000; account name D Bros Investment Limited. USD and EUR use SWIFT (same fields on deposit_instructions).
Invoice / paylink (auto-assign VA)
/v1/invoiceThe VA number becomes external_ref. Response includes deposit_instructions (PayBill + SWIFT). Hosted link: POST /v1/paylink with payment_method: "virtual_account" — omit virtual_account_id and Globpay creates or reuses the merchant VA.
USD rails (GlideSwipe) Planned
Separate from NCBA VAs above. USD virtual accounts / ACH payouts via operator=glideswipe are not self-serve yet.
Cards — Direct API (2D + 3DS) Live
Charge Visa / Mastercard by sending card details on your server
(POST /v1/card/collection).
2D Direct: no Globpay page and no redirect — the API response is the result.
3DS Direct: same endpoint returns a 3ds_url when the issuer requires authentication.
| Item | Value |
|---|---|
| Endpoint | POST /v1/card/collection |
| Auth modes | 2d (immediate) or 3ds (3ds_url) |
| Currencies | USD, EUR, GBP, KES, … |
| Operator | Brand | Notes |
|---|---|---|
vaultpay_card | Globpay Cards (VaultPay) | Direct API; may return 3ds_url |
orchestrate_card | Globpay Orchestrate | Direct PAN or hosted checkout / 3DS redirect. Confirm with GET /v1/operators. |
1. Charge a card (Direct)
/v1/card/collectionSame body for Globpay Orchestrate — set operator to orchestrate_card. Confirm the operator is on GET /v1/operators.
| Field | Required | Notes |
|---|---|---|
operator | yes | vaultpay_card or orchestrate_card (must be enabled on your account) |
amount | yes | Decimals allowed (min typically 2.00) |
currency | no | Defaults to operator currency (often USD) |
first_name / last_name / email | yes | Cardholder identity |
card_number | yes | Digits only; never logged or stored by Globpay |
card_expiry_month | yes | Two digits, e.g. 01 |
card_expiry_year | yes | Four digits, e.g. 2028 |
card_cvv | yes | 3–4 digits; never stored |
line1 / city / state / postal_code / country | no | Billing address (recommended) |
callback_url | no | Per-request webhook override |
return_url | recommended | Where the customer returns after 3DS after 3DS Direct |
On 2D success, checkout_url / 3ds_url are null —
do not send the customer to Globpay. Treat status: "completed"
as success; still keep your webhook as a backup.
2. 3DS Direct (same endpoint)
When 3-D Secure is required, the response is
auth_mode: "3ds" with a 3ds_url
(not a Globpay page). Open that URL for the customer, then poll
GET /v1/status/{request_ref} or wait for the webhook.
3. Test cards (test mode)
| Card number | Outcome |
|---|---|
4242424242424242 | 2D Direct success (immediate completed) |
4000000000000002 | Declined |
4000000000003220 | 3DS Direct required (3ds_url) |
4000000000009995 | Insufficient funds |
Cards — Hosted 3DS Live
Use this when you must not collect card data (SAQ A). The customer enters the card on a Globpay-hosted page; 3-D Secure is handled there. This path remains available even when Direct API is PCI-gated off. Prefer Direct API if your backend already collects the card.
| Item | Value |
|---|---|
| Channel | vaultpay / orchestrate |
| Operator | vaultpay_card or orchestrate_card |
| Auth mode | Hosted page + 3DS when required |
| Endpoint | POST /v1/card/session |
1. Create a card checkout session
/v1/card/session| Field | Required | Notes |
|---|---|---|
amount | yes | Charge amount (decimals allowed, e.g. 49.99) |
currency | no | Defaults to USD |
reference | no | Your order id (echoed back as external_ref) |
return_url | no | Where the customer lands after paying (bounced with ?ref=&status=) |
first_name / last_name / email | no | Prefill the hosted form |
callback_url | no | Per-request webhook override |
expires_in | no | Minutes until the link expires (default 120) |
Redirect the customer to pay_url. After payment they return to:
GET /v1/status/{request_ref} or the webhook.
2. Card payment link (share instead of redirect)
To send a link rather than redirect inline, create a paylink with payment_method: "card":
/v1/paylinkReturns a pay_url like https://login.globpay.app/p/PLAB12CD34. The customer opens it, pays by card (3DS handled), and — if redirect_url is set — is bounced back with ?ref=&status=.
3. Completion
Hosted card payments complete asynchronously via Globpay webhook. Rely on your callback_url webhook and/or GET /v1/status/{request_ref}.
List operators
/v1/operatorsReturns only operators enabled for your account. Always discover from this endpoint — do not hardcode markets.
Optional: GET /v1/operators/compare?currency=UGX&type=collection
Balances (multi-currency)
/v1/balanceEach operator has collection and disbursement wallets in its own currency. Group by currency for display and payouts.
wallets by currency (and wallet_type).
Core endpoints
| Method | Path | Purpose |
|---|---|---|
GET | /v1/operators | Enabled operators for your account |
POST | /v1/collection | Collect (C2B) |
POST | /v1/disbursement | Disburse (B2C) |
GET | /v1/status/{request_ref} | Payment status |
GET | /v1/balance | Multi-currency wallets |
GET | /v1/transactions | History |
POST | /v1/invoice | Invoice / QR (KES/USD/EUR auto-assigns NCBA VA) |
POST | /v1/paylink | Payment link (card, virtual_account, or crypto) |
POST / GET | /v1/virtual-accounts | Create / list NCBA VAs + SWIFT instructions |
POST | /v1/card/collection | Direct API 2D + 3DS — pass card data (3DS → 3ds_url) |
POST | /v1/card/session | Hosted 3DS checkout (Globpay page, SAQ A — remains available) |
POST | /v1/transfer | Collection → disbursement (requires Auto Transfer on account) |
GET | /v1/transfers | List internal transfers |
POST | /v1/send | Unified send (single or batch) |
POST | /v1/settlement | Bank settlement |
POST | /v1/settlement/usdt | USDT settlement (entitlement) |
GET | /v1/webhooks/{ref} | Outbound webhook delivery status |
Payment status
/v1/status/{request_ref}Internal transfer (collection → disbursement)
Requires Auto Transfer enabled on your merchant account by Globpay. Choose a collection wallet from GET /v1/balance, then move funds to the matching disbursement wallet.
/v1/transferoperator accepts a code (mpesake) or display name (M-Pesa Kenya). List history with GET /v1/transfers.
Corridor (preview) Premium
Merchant remittance path: TZS collection balance → USDT → cross-border local fiat payout.
Requires can_stablecoin and corridor features enabled on your account by Globpay.
| Method | Path | Purpose |
|---|---|---|
POST | /v1/corridor/quote | TZS → USDT quote |
POST | /v1/corridor | Start corridor |
GET | /v1/corridor/{corridor_ref} | Status |
Webhooks
Configure Dashboard → Webhook & API Keys → Callback URL (or pass callback_url per request). Globpay POSTs JSON when a payment completes or fails.
event | Meaning |
|---|---|
payin.completed | Collection succeeded |
payin.failed | Collection failed, cancelled, timed out or reversed |
payout.completed | Disbursement succeeded |
payout.failed | Disbursement failed, cancelled, timed out or reversed |
event as an opaque completion signal. Always confirm with
GET /v1/status/{request_ref} before fulfilling your customer.
Signature verification
Once your account has a webhook secret, every delivery carries two headers:
| Header | Value |
|---|---|
X-Payin-Signature | HMAC-SHA256 of the signed string, lowercase hex |
X-Payin-Timestamp | Unix timestamp (seconds) used to build that string |
Generate or rotate the secret in Dashboard → Webhook & API Keys → Webhook Signing Secret →
Regenerate Secret, or call POST /api/account/webhook-secret/regenerate with your
merchant bearer token. Until a secret exists, webhooks are delivered unsigned — the two
headers are simply absent.
- Return HTTP
200within ~10 seconds. - Use
operator_code+currencyfor analytics — not display name alone. - Handle idempotently: the same
request_refmay be delivered more than once.
Status & errors
| Status | Meaning |
|---|---|
pending | Created, not yet with the network |
processing | Sent; waiting customer / network |
waiting | Awaiting customer payment (Kenya paybill mode) |
completed | Success — credit/debit applied |
failed | Failed |
reversed | Reversed |
Common HTTP codes: 401 auth, 403 entitlement/IP, 404 unknown ref, 422 validation / network reject, 429 rate limit.
Typical multi-currency mistakes
- Wrong
currencyfor the operator (e.g.TZSwithmpesake) - Phone prefix not matching currency
- Disbursing from an empty local wallet while another currency still has balance
Integration checklist
Tanzania
- Operators:
mpesa|tigopesa|airtelmoney|halopesa - Pass
currency: "TZS", phones as255… - Expect USSD; poll until completed / failed
Kenya
- M-Pesa:
operator=mpesake,currency: "KES", phones as254…(STK Push) - Airtel collect:
operator=airtelke(Airtel prompt, not STK) - Airtel payout:
operator=airtelkeon the same NCBA B2C channel asmpesake - Bank:
operator=pesalink+bank_code/bank_bic+account_number+beneficiary_name(limits 50–999,999) - Banks list:
GET /v1/merchant/ncba/banks; KE bank accounts need BIC (swift_code) for settlements - Keep KES wallets separate from TZS
Senegal
- Checkout:
hayb_sn_orange,hayb_sn_wave,hayb_sn_free - Direct phone prompt:
swychr_sn_orange,swychr_sn_wave - Free Money redirect:
swychr_sn_freereturnscheckout_url. Nootp - Pass
currency: "XOF", phones as221…. Send the codeGET /v1/operatorsreturns - Orange direct: optional
otp(4–8 digits the customer already has from Orange Money). Omitotpand the customer still approves on the phone - Redirect to
checkout_urlwhen returned (hayb_sn_*,swychr_sn_free) - Set
success_url/failed_urlon HaybTech checkout - Confirm via webhook + status poll — never trust the browser redirect alone
Rest of Africa
- Boot with
GET /v1/operators— only use returnedyc_*codes - Map customer country → operator + currency + phone prefix
- Respect market minimums; keep each local-currency wallet separate
- Do not use
yc_*for Tanzania or Kenya
Environments
| Production | |
|---|---|
| API host | api.globpay.app |
| Base URL | https://api.globpay.app/api/v1 |
| Money | Real |
| Keys | Live keys from Dashboard → Settings → API Keys |
api.globpay.app only. Do not call api.sandbox.globpay.app — that host is not provisioned.