Create and track payments
Creating a payment is asynchronous — you get a payment ID immediately, then poll for status or
receive a webhook when it changes. Every payment targets a merchantId, and
amount is always a whole number in the destination currency (ZAR, NGN, KES…).
webhookUrl and webhookSecret are optional
but strongly recommended — they replace polling with real-time status updates. See
Webhooks.The payment object
Every endpoint on this page returns or accepts this object. Fields are grouped by how you use
them — what you send, what comes back, and the lifecycle the status moves through.
BTCmeta. A JSON string for extensible metadata. On a request you
can set meta.collectionMethod (Kenya funding — MPESA by default, or
BANK_TRANSFER). For a sub-payment in a payment group it carries
{ paymentGroupExecutionId, isMemberPayout, memberIndex, memberName, lnurl? }.
Internal keys (e.g. RefundConfig) are stripped from API responses.{
"id": "eafdea43-63a7-4f61-b8ae-823c1b3aa236",
"merchantId": "9f430126-99da-42e8-afb1-4cab619cda5a",
"amount": 100,
"amountSettled": 102.28,
"status": "success",
"statusLog": "payment completed successfully",
"fromCountry": "BTC",
"destinationCountry": "RSA",
"destinationCurrency": "ZAR",
"reference": "INV12345",
"tag": "ORDER-2024-001",
"type": "PURCHASE",
"otcFees": 15,
"date": "2024-09-27T21:01:49.535Z"
}Transaction limits
South Africa (ZAR)
Regulatory limits depend on time of day (SARB rules, Africa/Johannesburg time).
Kenya (KES)
Max depends on the recipient merchant's payout rail. amount is the KES the recipient
receives.
fromCountry, prefer the country name "Kenya" or
"KE" ("KES" is also accepted).Optional parameters
Extra fields you can include on POST /payments. Expand any to see what it does.
Endpoints
List all payments
Retrieve a paginated list of your payments. Pass the offsetMarker from one response as
the next request's offset. It returns null when there are no more results.
{
"items": [
{
"id": "eafdea43-63a7-4f61-b8ae-823c1b3aa236",
"merchantId": "9f430126-99da-42e8-afb1-4cab619cda5a",
"amount": 10,
"amountSettled": 10.22,
"status": "success",
"destinationCurrency": "ZAR",
"reference": "test4",
"type": "PURCHASE",
"otcFees": 20,
"date": "2024-09-27T21:01:49.535Z"
}
],
"offsetMarker": "%7B%22id%22%3A%22e029...%22%7D"
}Retrieve a payment
Fetch a single payment by its ID — the same shape as the objects in the list endpoint.
isSlowPayment only appears in the response when it was set to true on the
request.{
"id": "700293cc-5ab7-4869-9f8a-a3f0558e25eb",
"merchantId": "9f430126-99da-42e8-afb1-4cab619cda5a",
"amount": 12,
"amountSettled": 12.28,
"status": "expired",
"statusLog": "payment has expired",
"destinationCurrency": "ZAR",
"reference": "test1",
"type": "PURCHASE",
"otcFees": 15,
"date": "2024-09-16T19:45:45.750Z"
}Create a payment
The payload varies by destination country (where the recipient is). Pick one to see its requirements and example.
referenceis required (≤20 chars,/^[a-zA-Z0-9 ]{1,20}$/).tagoptional, for your own tracking.- All other optional fields can be omitted.
{
"merchantId": "9f430126-99da-42e8-afb1-4cab619cda5a",
"amount": 100,
"reference": "INV12345",
"type": "PURCHASE",
"tag": "ORDER-2024-001"
}Fiat → Fiat bank transfer
Move money bank-to-bank across borders. Set fromCountry for the source;
amount is in the destination currency.
Nigeria, Kenya, UK, EuropeUK/Europe: references must be exact. Any extra characters cause
payment mismatches and slow settlement.{
"merchantId": "323b268b-c802-4ac6-86a6-18a69e46ca6a",
"amount": 50,
"fromCountry": "Nigeria",
"reference": "test1",
"type": "PURCHASE"
}depositBankDetails then carries the source-currency
account to deposit into.USDT → Fiat or BTC
Fund a payment with USDT (Tether) on Ethereum. Orange returns a one-time deposit address; once it settles, proceeds route to the merchant's configured off-ramp.
amount: 151 means send 1.51 USDT.
Divide by 100.{
"merchantId": "your-merchant-id",
"amount": 20,
"fromCountry": "USDT",
"reference": "INV12345",
"type": "PURCHASE"
}Attach an invoice
For SARB compliance, payments above 50,000 ZAR should include supporting documents. Attach multiple files by calling once per file — re-uploading never overwrites.
curl --location \
'https://api.useorange.com/payments/{id}/document' \
--header 'Authorization: Bearer YOUR_JWT_TOKEN' \
--form 'file=@/path/to/invoice.pdf'List payment documents
Returns every attached document with short-lived presigned URLs you can download directly — no auth header needed on the presigned URL itself.
900 s (15 min). Call again for fresh ones.{
"items": [
{
"paymentId": "590054d6-567e-4329-b7a2-e46577079df0",
"documentId": "590054d6-...#1777319066904",
"presignedUrl": "https://...s3...X-Amz-Expires=900...",
"createdAt": "2026-04-27T19:44:27.244Z"
}
],
"presignedUrlExpiresInSeconds": 900
}