Orange DOCS
Orange API · Reference & integration guide

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.

Base URL
https://api.app.useorange.com
Settlement
Seconds, not days
🔑
Tokens rotate often. We deploy frequently and generate a new JWT secret on each deploy, so a token can expire sooner than its stated time. If you get a 401 or 403, just request a fresh one.

Release notes

What changed, newest first
June 2026
  • 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.
Read the full summary →
Nov 24, 2025
Added CDV validation for South African bank accounts. No integration changes needed — ZAR payouts are now check-digit verified to cut failed payments.
Nov 14, 2025
  • Fixed PayShap fee calculations (ZAR outbound).
  • More robust payment-failure handling for niche edge cases.
  • Customisable proof-of-payment PDFs for whitelabel clients.
Oct 31, 2025
  • Limited rollout of PayShap integration.
  • New iframe-wrapper config for whitelabel clients.
  • Added otcFees to the payment response model.
Guides

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.

Offramp 6 steps · ~10 min
01

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.

01 · 02
Token & merchant
03 · 04
Create payment
05
Pay LN invoice
06
ZAR settles
1

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.

  1. Open portal.useorange.com and sign in.
  2. Go to Settings in the sidebar.
  3. Under API Credentials, click Generate New Credentials.
  4. Copy your apiKey and apiSecret somewhere safe.
⚠️
Shown once. Your apiSecret is only displayed a single time. Lose it and you'll need to generate a fresh pair.
🔐
No API call yet — credentials come from the dashboard. The first call appears in Step 2.
2

Authenticate

Exchange your credentials for a JWT. Send it as a Bearer token on every request that follows.

💡
Tokens expire after about an hour. On a 401/403, request a new one.
POST /token
{
  "apiKey": "your-api-key",
  "apiSecret": "your-api-secret"
}
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
3

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.
POST /merchants
{
  "name": "My SA Merchant",
  "bankName": "CAPITEC BANK",
  "accountNumber": "1325558779",
  "country": "SouthAfrica"
}
4

Create the BTC → ZAR payment

Point a payment at your merchant. amount is in ZAR; the response carries the lightningInvoice you'll pay next.

⚠️
Reference required for SA. 1–20 characters, letters, numbers and spaces only.
POST /payments
{
  "merchantId": "0c83ca77-c1e2-4e04-9932-9541e535b3e6",
  "amount": 500,
  "reference": "INV001",
  "fromCountry": "BTC",
  "type": "PURCHASE"
}
5

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.

Wallet of Satoshi Phoenix Blink
Scan or paste the invoice in your wallet to fund the transaction.
6

Track payment status

Poll the payment, or let a webhook tell you. Each status moves the money one step closer to the bank.

createdAwaiting Lightning payment
depositedLN received, converting
transferringBank transfer initiated
successZAR settled into the bank account
GET /payments/{id}
{
  "id": "abc123-payment-id",
  "status": "success",
  "amount": 500,
  "amountSettled": 500,
  "amountBtc": 52000,
  "destinationCurrency": "ZAR",
  "reference": "INV001"
}
Done — ZAR has landed in the merchant's account.
Onramp Beta EUR · GBP · NGN → Lightning
02

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.

1

Create a BTC merchant

The merchant holds the destination Lightning Address that will receive the sats.

POST /merchants
{
  "name": "My Lightning Wallet",
  "country": "BTC",
  "lnurl": "username@walletofsatoshi.com"
}
2

Create the onramp payment

Specify the source fiat amount and the BTC merchant. The response returns depositBankDetails — where to send your deposit.

⚠️
Use the exact reference on your bank transfer so the deposit is matched.
POST /payments
{
  "merchantId": "f06a6a90-9b19-469e-951b-f91db200d74d",
  "amount": 100,
  "fromCountry": "Europe"
}
3

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.

Send €100.00 ref ORG-ABC123
Receive 125,000 sats success
Cross-border KES → ZAR · M-Pesa or PesaLink
03

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.

1

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.

POST /profile/mpesa
{
  "phoneNumber": "+254700000000",
  "mobileNetwork": "MPESA",
  "countryCode": "KE",
  "label": "My Safaricom"
}
2

Create the KES → ZAR payment

amount is in ZAR (what the recipient gets); the payer funds it in KES. Set fromCountry to "Kenya".

⚠️
Use the country name, not the currency code. "Kenya" or "KE" — never "KES".
POST /payments
{
  "merchantId": "0c83ca77-c1e2-4e04-9932-9541e535b3e6",
  "amount": 15,
  "fromCountry": "Kenya",
  "reference": "Invoice 12345",
  "meta": { "collectionMethod": "MPESA" }
}
3

Fund the payment — two ways

How the payer covers the KES leg is controlled by meta.collectionMethod.

Option A · default
M-Pesa STK push
An STK push hits the payer's phone — they just approve the prompt. No account to copy.
{
  "depositBankDetails": {
    "instructions": "Confirm 158 KES on your phone.",
    "amount": 158,
    "currency": "KES",
    "expiry": "2026-06-10T23:36:49Z"
  }
}
Option B
PesaLink bank transfer
Set BANK_TRANSFER and the response returns PesaLink instructions instead.
{
  "depositBankDetails": {
    "accountName": "PAVILION ECOMMERCE LTD",
    "accountNumber": "46013000193549",
    "reference": "KP59683609",
    "amount": 15800,
    "currency": "KES"
  }
}
⚠️
Bank-transfer amount is in cents. 15800 = KES 158. The human-readable figure is in instructions.