Rechargely Payouts API
Send money from your Rechargely wallet to mobile wallets and bank accounts from your own systems. Explore the REST API with interactive examples.
https://rechargely.online/api/wallet/v1Authentication
Create API credentials under Developers in the portal. Exchange them using HTTP Basic authentication at /authenticate/api-key. For every other request, include Authorization: Bearer <accessToken>, X-Channel-Id: API, and X-Portal-Id: DISBURSER_PORTAL. Tokens expire after 15 minutes and have no refresh token; exchange credentials again after expiry. Keep API secrets on your backend. Token exchange examples run server-side.
Payout Integration Flow
Use one unique requestId per payout; resending it is safe and never pays twice. Payouts end SUCCESS or FAILED; PENDING means poll the status endpoint. API payouts execute immediately; portal approval rules do not apply to API keys, so keep them on your backend.
Authentication
/authenticate/api-key Basic AuthExchange API Credentials
Create API credentials in the portal Developers tab. Send the API key as the HTTP Basic username and the API secret as the password from your backend. The bearer token lasts 15 minutes (900 seconds) and has no refresh token. In Postman, choose Authorization > Basic Auth and Body > x-www-form-urlencoded.
Required Headers
- Authorization
- Basic <base64(api-key:api-secret)>
- Content-Type
- application/x-www-form-urlencoded
- X-Channel-Id
- API
- X-Portal-Id
- DISBURSER_PORTAL
Form Fields (x-www-form-urlencoded)
grant_typestringrequiredMust be client_credentials.
scopestringrequiredMust be disbursement:write.
Response Fields
accessTokenstringUse as Authorization: Bearer <accessToken> for the remaining calls.
tokenTypestringBearer.
expiresInnumberToken lifetime in seconds (900). Exchange credentials again after expiry.
scopestringGranted scope: disbursement:write.
curl -i -X POST 'https://rechargely.online/api/wallet/v1/authenticate/api-key' \
-u '<api-key>:<api-secret>' \
-H 'X-Channel-Id: API' \
-H 'X-Portal-Id: DISBURSER_PORTAL' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'scope=disbursement:write'Example Response (HTTP 200)
{
"accessToken": "eyJhbGciOiJIUzI1NiIs...",
"tokenType": "Bearer",
"expiresIn": 900,
"scope": "disbursement:write"
}Destinations
/funds-disbursements/institutions Bearer AuthList Destinations
Wallets and banks you can currently pay out to, with the bankCode to send and the currencies available. Codes are stable; the list changes only when a destination is added or paused. The same list is public, without a token, at GET /public/funds-disbursements/institutions.
Required Headers
- X-Channel-Id
- API
- X-Portal-Id
- DISBURSER_PORTAL
- Authorization
- Bearer <partner-token>
Response Fields
bankCodestringSend as bankCode when disbursing.
namestringInstitution name, e.g. EcoCash.
typestringMOBILE_WALLET or BANK.
currenciesstring[]Currencies payouts are available in.
accountLookupSupportedbooleanWhether Account Lookup works for this destination.
curl -i -X GET 'https://rechargely.online/api/wallet/v1/funds-disbursements/institutions' \
-H 'X-Channel-Id: API' \
-H 'X-Portal-Id: DISBURSER_PORTAL' \
-H 'Authorization: Bearer <partner-token>'Example Response (HTTP 200)
[
{
"bankCode": "000013",
"name": "EcoCash",
"type": "MOBILE_WALLET",
"currencies": [
"USD",
"ZWG"
],
"accountLookupSupported": true
},
{
"bankCode": "000021",
"name": "CBZ Bank",
"type": "BANK",
"currencies": [
"USD"
],
"accountLookupSupported": false
}
]/funds-disbursements/account-lookup Bearer AuthAccount Lookup
Returns the registered holder of an account so you can confirm it before sending. Only available where accountLookupSupported is true; otherwise the call answers 400.
Required Headers
- X-Channel-Id
- API
- X-Portal-Id
- DISBURSER_PORTAL
- Authorization
- Bearer <partner-token>
- Content-Type
- application/json
Request Body (JSON)
bankCodestringrequiredDestination institution code.
accountNumberstringrequiredAccount or mobile number to look up.
currencystringUSD (default) or ZWG.
Response Fields
bankCodestringEchoed.
accountNumberstringEchoed.
foundbooleanfalse when the destination says the account does not exist.
accountNamestringnullableRegistered holder, when found.
messagestringnullableDetail from the destination.
curl -i -X POST 'https://rechargely.online/api/wallet/v1/funds-disbursements/account-lookup' \
-H 'X-Channel-Id: API' \
-H 'X-Portal-Id: DISBURSER_PORTAL' \
-H 'Authorization: Bearer <partner-token>' \
-H 'Content-Type: application/json' \
-d '{
"bankCode": "000013",
"accountNumber": "263771234567"
}'Example Response (HTTP 200)
{
"bankCode": "000013",
"accountNumber": "263771234567",
"found": true,
"accountName": "TENDAI MOYO",
"message": "Found"
}Payouts
/funds-disbursements Bearer AuthSend Funds
Debits your wallet (amount + fee) and sends the amount to the recipient. Generate a unique requestId per payout: resending the same request with the same requestId returns the original payout instead of paying again, so retry freely after a timeout. A requestId reused with different details is refused (409). A PENDING result means the destination has not confirmed yet; poll Payout Status — never send a replacement payout for a PENDING one.
Required Headers
- X-Channel-Id
- API
- X-Portal-Id
- DISBURSER_PORTAL
- Authorization
- Bearer <partner-token>
- Content-Type
- application/json
Request Body (JSON)
amountnumberrequiredAmount for the recipient, up to 2 decimals. The fee is added on top.
bankCodestringrequiredDestination institution code from List Destinations.
recipientAccountNumberstringrequiredRecipient account or mobile number (mobile wallets: 2637XXXXXXXX).
narrationstringPayment description, up to 255 characters.
requestIdstringrequiredYour unique id for this payout (letters, digits, _ . : -; up to 64).
currencystringUSD (default) or ZWG; the matching wallet is debited.
recipientNamestringRecipient name for your records.
Response Fields
referencestringRechargely reference for the payout. Quote it to support.
requestIdstringYour requestId, echoed back.
statusstringPENDING, SUCCESS or FAILED. Only SUCCESS and FAILED are final; poll the status endpoint while PENDING.
refundedbooleannullablePresent when FAILED: true once the amount and fee are back in your wallet.
amountnumberAmount sent to the recipient.
feenumberFee charged for the payout.
taxnumberTax charged (e.g. IMT), when applicable.
totalDebitnumberamount + fee + tax, taken from your wallet.
currencystringUSD or ZWG.
bankCodestringDestination institution code.
institutionNamestringDestination institution name.
recipientAccountNumberstringRecipient account or mobile number.
providerReferencestringnullableThe destination network’s reference, once it has one.
messagestringnullableHuman-readable detail, e.g. a decline reason. Use status for program logic.
createdAtstringWhen the payout was received.
completedAtstringnullableWhen it reached SUCCESS or FAILED.
curl -i -X POST 'https://rechargely.online/api/wallet/v1/funds-disbursements' \
-H 'X-Channel-Id: API' \
-H 'X-Portal-Id: DISBURSER_PORTAL' \
-H 'Authorization: Bearer <partner-token>' \
-H 'Content-Type: application/json' \
-d '{
"amount": 50,
"bankCode": "000013",
"recipientAccountNumber": "263771234567",
"narration": "Test Withdrawal",
"requestId": "DND3157858809885"
}'Example Response (HTTP 200)
{
"reference": "FD0S5SVG2VW557T",
"requestId": "DND3157858809885",
"status": "SUCCESS",
"amount": 50,
"fee": 0.5,
"tax": 0,
"totalDebit": 50.5,
"currency": "USD",
"bankCode": "000013",
"institutionName": "EcoCash",
"recipientAccountNumber": "263771234567",
"narration": "Test Withdrawal",
"providerReference": "MP260108.1234.A12345",
"message": "Approved or completed successfully",
"createdAt": "2026-11-08T15:23:09",
"completedAt": "2026-11-08T15:23:10"
}/funds-disbursements/{requestId} Bearer AuthPayout Status
Current state of a payout, by your requestId or our reference. Poll PENDING payouts with a back-off (e.g. 30s, 1m, 2m, 5m…); most settle within minutes.
Required Headers
- X-Channel-Id
- API
- X-Portal-Id
- DISBURSER_PORTAL
- Authorization
- Bearer <partner-token>
Path Parameters
requestIdstringrequiredYour requestId, or the reference we returned.
Response Fields
referencestringRechargely reference for the payout. Quote it to support.
requestIdstringYour requestId, echoed back.
statusstringPENDING, SUCCESS or FAILED. Only SUCCESS and FAILED are final; poll the status endpoint while PENDING.
refundedbooleannullablePresent when FAILED: true once the amount and fee are back in your wallet.
amountnumberAmount sent to the recipient.
feenumberFee charged for the payout.
taxnumberTax charged (e.g. IMT), when applicable.
totalDebitnumberamount + fee + tax, taken from your wallet.
currencystringUSD or ZWG.
bankCodestringDestination institution code.
institutionNamestringDestination institution name.
recipientAccountNumberstringRecipient account or mobile number.
providerReferencestringnullableThe destination network’s reference, once it has one.
messagestringnullableHuman-readable detail, e.g. a decline reason. Use status for program logic.
createdAtstringWhen the payout was received.
completedAtstringnullableWhen it reached SUCCESS or FAILED.
curl -i -X GET 'https://rechargely.online/api/wallet/v1/funds-disbursements/{requestId}' \
-H 'X-Channel-Id: API' \
-H 'X-Portal-Id: DISBURSER_PORTAL' \
-H 'Authorization: Bearer <partner-token>'Example Response (HTTP 200)
{
"reference": "FD0S5SVG2VW557T",
"requestId": "DND3157858809885",
"status": "SUCCESS",
"amount": 50,
"fee": 0.5,
"tax": 0,
"totalDebit": 50.5,
"currency": "USD",
"bankCode": "000013",
"institutionName": "EcoCash",
"recipientAccountNumber": "263771234567",
"narration": "Test Withdrawal",
"providerReference": "MP260108.1234.A12345",
"message": "Approved or completed successfully",
"createdAt": "2026-11-08T15:23:09",
"completedAt": "2026-11-08T15:23:10"
}Wallet
/partner/wallet/balances Bearer AuthWallet Balances
Your wallets and their available balances, to check float before sending.
Required Headers
- X-Channel-Id
- API
- X-Portal-Id
- DISBURSER_PORTAL
- Authorization
- Bearer <partner-token>
Response Fields
currencystringUSD or ZWG.
accountNumberstringWallet account number.
statusstringWallet status.
balancenumberAvailable balance.
curl -i -X GET 'https://rechargely.online/api/wallet/v1/partner/wallet/balances' \
-H 'X-Channel-Id: API' \
-H 'X-Portal-Id: DISBURSER_PORTAL' \
-H 'Authorization: Bearer <partner-token>'Example Response (HTTP 200)
[
{
"currency": "USD",
"accountNumber": "2100000001",
"status": "ACTIVE",
"balance": 413.5
}
]Statuses and error handling
An accepted payout always answers HTTP 200 with a status. Requests refused before anything is debited answer 4xx with a message explaining why.
Example: HTTP 400, insufficient funds
{
"timestamp": "2026-11-08 15:23:23",
"status": 400,
"errors": null,
"message": "Insufficient funds: 5000.50 USD needed (including fees), 439.00 available"
}| status | HTTP status | Meaning |
|---|---|---|
| SUCCESS | 200 | Delivered to the recipient. Final. |
| PENDING | 200 | Accepted; awaiting confirmation from the destination. Poll status; do not resend with a new requestId. |
| FAILED | 200 | Not delivered. Final; refunded tells you whether the debit is back in your wallet. |
| — | 400 | Validation error: unknown bankCode, unsupported currency, invalid account number, insufficient funds or limits exceeded. Nothing was debited. |
| — | 401 | Missing, expired or invalid token. |
| — | 403 | Token not permitted for this endpoint or portal (check X-Portal-Id). |
| — | 404 | No payout with that requestId or reference on your account. |
| — | 409 | requestId already used for a different payout. |
Pending outcomes and retries
Some destinations confirm asynchronously, so a payout can come back PENDING. The funds stay reserved until it is resolved: SUCCESS (delivered) or FAILED with refunded: true (returned to your wallet). Poll GET /funds-disbursements/{requestId} with a back-off.
{
"reference": "FD0S5SV8600556R",
"requestId": "PAYROLL-2026-11-0042",
"status": "PENDING",
"amount": 10,
"fee": 0.5,
"totalDebit": 10.5,
"currency": "USD",
"bankCode": "000013",
"message": "Awaiting provider confirmation"
}After a network timeout, resend the identical request with the same requestId: you get the original payout back, never a second payment. Never send a replacement payout with a new requestId while one is PENDING.
Webhooks
Instead of polling, register an HTTPS endpoint under Developers in the portal. Each status change is POSTed as {"id", "type", "createdAt", "data"} where data is the payout (same fields as above) and type is one of payout.awaiting_approval, payout.pending, payout.succeeded, payout.failed, payout.refunded or payout.rejected. Verify X-Rechargely-Signature: v1=<hex>: hex is HMAC-SHA256 of X-Rechargely-Timestamp + "." + raw body with your signing secret. Reject stale timestamps, answer 2xx within 10 seconds and de-duplicate on id — failed deliveries are retried for about a day.
Authentication and request errors
Token exchange rejects invalid credentials, scope, grant type or channel/portal values with HTTP 401:
{
"error": "invalid_client",
"errorDescription": "Invalid API credentials"
}HTTP 401 also covers invalid or expired partner tokens and inactive credentials. HTTP 403 can indicate an endpoint outside the partner scope or a portal mismatch. Missing required headers or form fields and malformed JSON can return HTTP 400. Authentication filters and framework-level errors may use a different body; read the HTTP status first.
Rechargely API v1 · Need help? Contact support