Move money across borders on Bitcoin rails.
Orange settles fast, low-cost remittances over the Lightning Network. These guides walk you through complete flows end-to-end — from generating credentials to watching funds land in a bank account — with the request, response, and data model for every call kept right beside the story.
401 or
403, just request a fresh one.Release notes
- Kenya / M-Pesa: full M-Pesa account management with a default payout number, rail-specific limits, a live Kenyan bank list, and fee-inclusive STK-push amounts.
- South Africa: self-service ZAR onboarding with KYC status, plus self-service CDV and Travel-Rule controls (including KYC capture on payment links).
- More reliable payments — stuck-payment monitoring, full status-log history via
?includeStatusLog=true, duplicate-webhook protection, and safer settlement-timeout handling — plus a hardened Quote endpoint, API-key audit logging, and the start of PayShap for ZAR.
- Fixed PayShap fee calculations (ZAR outbound).
- More robust payment-failure handling for niche edge cases.
- Customisable proof-of-payment PDFs for whitelabel clients.
- Limited rollout of PayShap integration.
- New iframe-wrapper config for whitelabel clients.
- Added
otcFeesto the payment response model.
Three flows, start to finish
Each guide reads like a walkthrough. The narrative stays on the left; the request, response, and typed model for the call you're reading stay pinned on the right.
Bitcoin → South African bank account
Set up API access, register a South African merchant, and send a Bitcoin payment that settles into a ZAR bank account. Pay a Lightning invoice; Orange handles the conversion and the bank transfer.
Create your API credentials
Generate an API key and secret from the Orange dashboard — these prove who you are when you ask for a token.
- Open portal.useorange.com and sign in.
- Go to Settings in the sidebar.
- Under API Credentials, click Generate New Credentials.
- Copy your
apiKeyandapiSecretsomewhere safe.
apiSecret is only displayed a single time. Lose it
and you'll need to generate a fresh pair.Authenticate
Exchange your credentials for a JWT. Send it as a Bearer token on every request that
follows.
401/403, request a new one.{
"apiKey": "your-api-key",
"apiSecret": "your-api-secret"
}Create a South African merchant
A merchant represents the bank account that will receive the funds. Create one for the South African recipient.
bankName must match a valid name — pull the list from the Utils endpoint.{
"name": "My SA Merchant",
"bankName": "CAPITEC BANK",
"accountNumber": "1325558779",
"country": "SouthAfrica"
}Create the BTC → ZAR payment
Point a payment at your merchant. amount is in ZAR; the response carries the
lightningInvoice you'll pay next.
{
"merchantId": "0c83ca77-c1e2-4e04-9932-9541e535b3e6",
"amount": 500,
"reference": "INV001",
"fromCountry": "BTC",
"type": "PURCHASE"
}Pay the Lightning invoice
Open any Lightning wallet, paste the lightningInvoice, and confirm. Once it's
received, Orange converts BTC to ZAR and pushes the bank transfer automatically.
Track payment status
Poll the payment, or let a webhook tell you. Each status moves the money one step closer to the bank.
{
"id": "abc123-payment-id",
"status": "success",
"amount": 500,
"amountSettled": 500,
"amountBtc": 52000,
"destinationCurrency": "ZAR",
"reference": "INV001"
}Fiat → Bitcoin on a Lightning Address
Send fiat and have Orange convert it and deliver Bitcoin to any Lightning Address (user@wallet.com) or LNURL.
Create a BTC merchant
The merchant holds the destination Lightning Address that will receive the sats.
{
"name": "My Lightning Wallet",
"country": "BTC",
"lnurl": "username@walletofsatoshi.com"
}Create the onramp payment
Specify the source fiat amount and the BTC merchant. The response returns
depositBankDetails — where to send your deposit.
reference on your bank transfer so the deposit is matched.{
"merchantId": "f06a6a90-9b19-469e-951b-f91db200d74d",
"amount": 100,
"fromCountry": "Europe"
}Deposit fiat & receive sats
Transfer the exact amount with the given reference. Once confirmed, Orange converts it and sends
Bitcoin to your Lightning Address — amountBtc shows the sats received.
M-Pesa (KES) → South African bank
A Kenyan payer funds in KES; it settles into a South African account in ZAR. Register an M-Pesa account, point the payment at an SA merchant, then choose how the payer funds it.
Register an M-Pesa account
A KES-funded payment needs a registered M-Pesa account on your profile — the number that receives the STK push. The first one becomes your default.
{
"phoneNumber": "+254700000000",
"mobileNetwork": "MPESA",
"countryCode": "KE",
"label": "My Safaricom"
}Create the KES → ZAR payment
amount is in ZAR (what the recipient gets); the payer funds it in KES. Set
fromCountry to "Kenya".
"Kenya" or "KE" — never
"KES".{
"merchantId": "0c83ca77-c1e2-4e04-9932-9541e535b3e6",
"amount": 15,
"fromCountry": "Kenya",
"reference": "Invoice 12345",
"meta": { "collectionMethod": "MPESA" }
}Fund the payment — two ways
How the payer covers the KES leg is controlled by meta.collectionMethod.
{
"depositBankDetails": {
"instructions": "Confirm 158 KES on your phone.",
"amount": 158,
"currency": "KES",
"expiry": "2026-06-10T23:36:49Z"
}
}BANK_TRANSFER and the response returns PesaLink instructions instead.{
"depositBankDetails": {
"accountName": "PAVILION ECOMMERCE LTD",
"accountNumber": "46013000193549",
"reference": "KP59683609",
"amount": 15800,
"currency": "KES"
}
}15800 = KES 158. The human-readable
figure is in instructions.