Skip to main content

Get Wallet Balance

The Get Wallet Balance endpoint allows you to retrieve the current balances of your collection and payout wallets.

Endpoint

GET /wallets/balance

Authentication

Required: Yes (Bearer Token)

Authorization: Bearer YOUR_ACCESS_TOKEN

Request

No request body or query parameters required.

Example Request

curl -X GET https://sandbox.api.jpay.africa/api/v1/wallets/balance \
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." \
-H "Content-Type: application/json"

Response

Success Response (200 OK)

{
"collection_wallet_balance": "45000.00",
"payout_wallet_balance": "12000.00",
"total_balance": "57000.00"
}

Response Fields

FieldTypeDescription
collection_wallet_balancestring (Decimal)Balance in your collection wallet (KES)
payout_wallet_balancestring (Decimal)Balance in your payout wallet (KES)
total_balancestring (Decimal)Combined total of both wallets (KES)

Status Codes

CodeStatusDescription
200SuccessBalances retrieved successfully
401UnauthorizedInvalid or expired token
403ForbiddenIP address not allowed (if IP restrictions configured)
500Server ErrorInternal server error

Error Responses

401 Unauthorized

{
"detail": "Invalid or expired token"
}

403 Forbidden - IP Not Allowed

{
"detail": "Access denied: IP address not allowed"
}
info

This error occurs when your app has IP restrictions configured and the request is coming from an IP address that is not in the allowed list.

Examples

curl -X GET https://sandbox.api.jpay.africa/api/v1/wallets/balance \
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." \
-H "Content-Type: application/json"

Understanding Wallet Types

Collection Wallet

  • Purpose: Holds funds from successful collections (payments received)
  • Credits: Incoming payments from customers
  • Debits: Transfers to payout wallet or withdrawals

Payout Wallet

  • Purpose: Holds funds available for sending payouts
  • Credits: Transfers from collection wallet or deposits
  • Debits: Outgoing payouts to recipients

Total Balance

The combined balance of both wallets, representing your total available funds.

Use Cases

Check Balance Before Payout

Always check your payout wallet balance before initiating a payout:

def safe_initiate_payout(access_token, amount, recipient):
# Get current balance
balance = get_wallet_balance(access_token)

payout_balance = float(balance['payout_wallet_balance'])

if payout_balance < amount:
print(f"Insufficient funds: KES {payout_balance} available, KES {amount} required")
return None

# Proceed with payout
return initiate_payout(access_token, recipient, amount)

Monitor Wallet Health

Set up alerts when balances fall below thresholds:

def monitor_wallet_health(access_token, min_collection=10000, min_payout=5000):
balance = get_wallet_balance(access_token)

collection = float(balance['collection_wallet_balance'])
payout = float(balance['payout_wallet_balance'])

alerts = []

if collection < min_collection:
alerts.append(f"Collection wallet low: KES {collection}")

if payout < min_payout:
alerts.append(f"Payout wallet low: KES {payout}")

return alerts

Dashboard Integration

Display balances in your application dashboard:

async function updateDashboard(accessToken) {
const balance = await getWalletBalance(accessToken);

// Update UI elements
document.getElementById('collection-balance').textContent =
`KES ${parseFloat(balance.collection_wallet_balance).toLocaleString()}`;

document.getElementById('payout-balance').textContent =
`KES ${parseFloat(balance.payout_wallet_balance).toLocaleString()}`;

document.getElementById('total-balance').textContent =
`KES ${parseFloat(balance.total_balance).toLocaleString()}`;
}

Best Practices

Cache Balance Data

Cache balance data for a short period to reduce API calls:

from datetime import datetime, timedelta

class BalanceCache:
def __init__(self, access_token):
self.access_token = access_token
self.balance = None
self.last_fetch = None
self.cache_duration = timedelta(minutes=5)

def get_balance(self, force_refresh=False):
now = datetime.now()

# Check if cache is still valid
if not force_refresh and self.balance and self.last_fetch:
if now - self.last_fetch < self.cache_duration:
return self.balance

# Fetch fresh balance
self.balance = get_wallet_balance(self.access_token)
self.last_fetch = now
return self.balance

Handle Errors Gracefully

def get_balance_with_retry(access_token, max_retries=3):
for attempt in range(max_retries):
try:
balance = get_wallet_balance(access_token)
return balance
except requests.RequestException as e:
if attempt < max_retries - 1:
time.sleep(2 ** attempt) # Exponential backoff
continue
else:
print(f"Failed to get balance after {max_retries} attempts")
raise

Important Notes

danger

Balance Accuracy:

  • Balances are real-time and reflect all completed transactions
  • Pending transactions are not included in the balance
  • Always check balance before initiating payouts to avoid insufficient fund errors
tip

Performance:

  • This endpoint is fast and lightweight
  • Safe to call frequently for real-time balance displays
  • Consider caching for high-traffic applications

Next Steps