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.

Base URL
https://rechargely.online/api/wallet/v1

Authentication

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

1POSTAuthenticate
2GETList Destinations
3POSTSend Funds
4GETPoll Status

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

POST/authenticate/api-key Basic Auth

Exchange 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_typestringrequired

Must be client_credentials.

scopestringrequired

Must be disbursement:write.

Response Fields

accessTokenstring

Use as Authorization: Bearer <accessToken> for the remaining calls.

tokenTypestring

Bearer.

expiresInnumber

Token lifetime in seconds (900). Exchange credentials again after expiry.

scopestring

Granted 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

GET/funds-disbursements/institutions Bearer Auth

List 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

bankCodestring

Send as bankCode when disbursing.

namestring

Institution name, e.g. EcoCash.

typestring

MOBILE_WALLET or BANK.

currenciesstring[]

Currencies payouts are available in.

accountLookupSupportedboolean

Whether 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
  }
]
POST/funds-disbursements/account-lookup Bearer Auth

Account 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)

bankCodestringrequired

Destination institution code.

accountNumberstringrequired

Account or mobile number to look up.

currencystring

USD (default) or ZWG.

Response Fields

bankCodestring

Echoed.

accountNumberstring

Echoed.

foundboolean

false when the destination says the account does not exist.

accountNamestringnullable

Registered holder, when found.

messagestringnullable

Detail 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

POST/funds-disbursements Bearer Auth

Send 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)

amountnumberrequired

Amount for the recipient, up to 2 decimals. The fee is added on top.

bankCodestringrequired

Destination institution code from List Destinations.

recipientAccountNumberstringrequired

Recipient account or mobile number (mobile wallets: 2637XXXXXXXX).

narrationstring

Payment description, up to 255 characters.

requestIdstringrequired

Your unique id for this payout (letters, digits, _ . : -; up to 64).

currencystring

USD (default) or ZWG; the matching wallet is debited.

recipientNamestring

Recipient name for your records.

Response Fields

referencestring

Rechargely reference for the payout. Quote it to support.

requestIdstring

Your requestId, echoed back.

statusstring

PENDING, SUCCESS or FAILED. Only SUCCESS and FAILED are final; poll the status endpoint while PENDING.

refundedbooleannullable

Present when FAILED: true once the amount and fee are back in your wallet.

amountnumber

Amount sent to the recipient.

feenumber

Fee charged for the payout.

taxnumber

Tax charged (e.g. IMT), when applicable.

totalDebitnumber

amount + fee + tax, taken from your wallet.

currencystring

USD or ZWG.

bankCodestring

Destination institution code.

institutionNamestring

Destination institution name.

recipientAccountNumberstring

Recipient account or mobile number.

providerReferencestringnullable

The destination network’s reference, once it has one.

messagestringnullable

Human-readable detail, e.g. a decline reason. Use status for program logic.

createdAtstring

When the payout was received.

completedAtstringnullable

When 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"
}
GET/funds-disbursements/{requestId} Bearer Auth

Payout 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

requestIdstringrequired

Your requestId, or the reference we returned.

Response Fields

referencestring

Rechargely reference for the payout. Quote it to support.

requestIdstring

Your requestId, echoed back.

statusstring

PENDING, SUCCESS or FAILED. Only SUCCESS and FAILED are final; poll the status endpoint while PENDING.

refundedbooleannullable

Present when FAILED: true once the amount and fee are back in your wallet.

amountnumber

Amount sent to the recipient.

feenumber

Fee charged for the payout.

taxnumber

Tax charged (e.g. IMT), when applicable.

totalDebitnumber

amount + fee + tax, taken from your wallet.

currencystring

USD or ZWG.

bankCodestring

Destination institution code.

institutionNamestring

Destination institution name.

recipientAccountNumberstring

Recipient account or mobile number.

providerReferencestringnullable

The destination network’s reference, once it has one.

messagestringnullable

Human-readable detail, e.g. a decline reason. Use status for program logic.

createdAtstring

When the payout was received.

completedAtstringnullable

When 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

GET/partner/wallet/balances Bearer Auth

Wallet 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

currencystring

USD or ZWG.

accountNumberstring

Wallet account number.

statusstring

Wallet status.

balancenumber

Available 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"
}
statusHTTP statusMeaning
SUCCESS200Delivered to the recipient. Final.
PENDING200Accepted; awaiting confirmation from the destination. Poll status; do not resend with a new requestId.
FAILED200Not delivered. Final; refunded tells you whether the debit is back in your wallet.
—400Validation error: unknown bankCode, unsupported currency, invalid account number, insufficient funds or limits exceeded. Nothing was debited.
—401Missing, expired or invalid token.
—403Token not permitted for this endpoint or portal (check X-Portal-Id).
—404No payout with that requestId or reference on your account.
—409requestId 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