Skip to main content

List Transactions

DEPRECATED

This endpoint is deprecated and will be removed in a future version. Please use the Wallet Transactions API (GET /wallets/transactions) instead for retrieving transaction history with improved filtering and performance.

Retrieve lists of collections (incoming payments) and payouts (outgoing payments) with filtering and pagination support. These endpoints allow you to manage and track your transactions.

List Collections

Retrieve a paginated list of all collections for your merchant account.

Endpoint

GET /payments/collections/list

Authentication

Required: Yes (Bearer Token)

Authorization: Bearer YOUR_ACCESS_TOKEN

Query Parameters

ParameterTypeRequiredDefaultDescription
pageintegerNo1Page number for pagination
page_sizeintegerNo50Number of records per page (max 100)
statusstringNo-Filter by status: pending, completed, failed
date_fromstringNo-Filter from date (YYYY-MM-DD)
date_tostringNo-Filter to date (YYYY-MM-DD)
phonestringNo-Filter by customer phone number
ref_nostringNo-Filter by reference number

Success Response (200 OK)

{
"count": 150,
"next": "https://sandbox.api.jpay.africa/api/v1/payments/collections/list?page=2",
"previous": null,
"results": [
{
"id": "COLL-2024-001-ABC123",
"payfrom": "+254712345678",
"amount": "1000.00",
"ref_no": "ORDER-2024-001",
"account_number": "1001",
"callback_url": "https://yourdomain.com/webhook",
"status": "completed",
"category": "ecommerce",
"created_at": "12/04/2024 14:30:45"
},
{
"id": "COLL-2024-002-XYZ789",
"payfrom": "+254787654321",
"amount": "2500.00",
"ref_no": "ORDER-2024-002",
"account_number": "1001",
"callback_url": "https://yourdomain.com/webhook",
"status": "pending",
"category": "ecommerce",
"created_at": "12/04/2024 13:15:30"
}
]
}

Response Fields

FieldTypeDescription
countintegerTotal number of collections
nextstringURL to next page (null if last page)
previousstringURL to previous page (null if first page)
resultsarrayArray of collection objects

Collection Object Fields

FieldTypeDescription
idstringUnique collection identifier
payfromstringCustomer phone number
amountstringCollection amount (KES)
ref_nostringYour reference number
account_numberstringAccount number
callback_urlstringWebhook URL
statusstringTransaction status
categorystringTransaction category
created_atstringCreation timestamp

Status Codes

CodeStatusDescription
200SuccessCollections retrieved successfully
400Bad RequestInvalid query parameters
401UnauthorizedInvalid or expired token
403ForbiddenAccess denied
500Server ErrorInternal server error

List Payouts

Retrieve a paginated list of all payouts for your merchant account.

Endpoint

GET /payments/payouts/list

Authentication

Required: Yes (Bearer Token)

Query Parameters

ParameterTypeRequiredDefaultDescription
pageintegerNo1Page number for pagination
page_sizeintegerNo50Number of records per page (max 100)
statusstringNo-Filter by status: pending, completed, failed
date_fromstringNo-Filter from date (YYYY-MM-DD)
date_tostringNo-Filter to date (YYYY-MM-DD)
phonestringNo-Filter by recipient phone number
ref_nostringNo-Filter by reference number

Success Response (200 OK)

{
"count": 85,
"next": null,
"previous": "https://sandbox.api.jpay.africa/api/v1/payments/payouts/list?page=1",
"results": [
{
"id": "PAYOUT-2024-001-ABC123",
"payto": "+254712345678",
"amount": "5000.00",
"ref_no": "PAYOUT-2024-001",
"status": "completed",
"category": "commission",
"created_at": "12/04/2024 10:20:15"
},
{
"id": "PAYOUT-2024-002-XYZ789",
"payto": "+254787654321",
"amount": "3000.00",
"ref_no": "PAYOUT-2024-002",
"status": "completed",
"category": "refund",
"created_at": "12/04/2024 09:45:30"
}
]
}

Response Fields

FieldTypeDescription
countintegerTotal number of payouts
nextstringURL to next page (null if last page)
previousstringURL to previous page (null if first page)
resultsarrayArray of payout objects

Payout Object Fields

FieldTypeDescription
idstringUnique payout identifier
paytostringRecipient phone number
amountstringPayout amount (KES)
ref_nostringYour reference number
statusstringTransaction status
categorystringTransaction category
created_atstringCreation timestamp

Examples

List Collections - Using cURL

# Get first page
curl -X GET "https://sandbox.api.jpay.africa/api/v1/payments/collections/list" \
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."

# Filter by status and date
curl -X GET "https://sandbox.api.jpay.africa/api/v1/payments/collections/list?status=completed&date_from=2024-12-01&date_to=2024-12-31" \
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."

# Specific page and custom page size
curl -X GET "https://sandbox.api.jpay.africa/api/v1/payments/collections/list?page=2&page_size=100" \
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."

List Collections - Using Python

import requests
from datetime import datetime, timedelta

def list_collections(access_token, status=None, date_from=None, page=1, page_size=50):
headers = {
'Authorization': f'Bearer {access_token}',
'Content-Type': 'application/json'
}

params = {
'page': page,
'page_size': page_size
}

if status:
params['status'] = status
if date_from:
params['date_from'] = date_from

response = requests.get(
'https://sandbox.api.jpay.africa/api/v1/payments/collections/list',
headers=headers,
params=params
)

if response.status_code == 200:
return response.json()
else:
print(f"Error: {response.status_code}")
print(response.json())
return None

# Usage - Get all completed collections from today
today = datetime.now().strftime('%Y-%m-%d')
collections = list_collections(
access_token='your_token',
status='completed',
date_from=today
)

if collections:
print(f"Total collections: {collections['count']}")
for item in collections['results']:
print(f"{item['ref_no']}: {item['amount']} KES - {item['status']}")

# Check for next page
if collections['next']:
print("More results available")

List Collections - Using JavaScript

async function listCollections(accessToken, options = {}) {
const params = new URLSearchParams({
page: options.page || 1,
page_size: options.pageSize || 50
});

if (options.status) {
params.append('status', options.status);
}
if (options.dateFrom) {
params.append('date_from', options.dateFrom);
}
if (options.dateTo) {
params.append('date_to', options.dateTo);
}

const response = await fetch(
`https://sandbox.api.jpay.africa/api/v1/payments/collections/list?${params}`,
{
method: 'GET',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
}
}
);

if (!response.ok) {
const error = await response.json();
throw new Error(error.detail);
}

return response.json();
}

// Usage - Get completed collections with pagination
try {
const collections = await listCollections('your_token', {
status: 'completed',
dateFrom: new Date().toISOString().split('T')[0],
pageSize: 100
});

console.log(`Total: ${collections.count}`);
collections.results.forEach(item => {
console.log(`${item.ref_no}: ${item.amount} KES - ${item.status}`);
});

// Pagination
if (collections.next) {
console.log('Next page available');
}
} catch (error) {
console.error('Failed to list collections:', error);
}

List Payouts - Using cURL

# Get payouts from last 30 days
curl -X GET "https://sandbox.api.jpay.africa/api/v1/payments/payouts/list?status=completed&date_from=2024-11-12" \
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."

Pagination Example

def list_all_collections(access_token):
"""Fetch all collections across all pages"""
all_collections = []
page = 1

while True:
response = list_collections(
access_token,
page=page,
page_size=100
)

if not response:
break

all_collections.extend(response['results'])

# Check if there's a next page
if response['next'] is None:
break

page += 1

return all_collections

# Usage
all_collections = list_all_collections('your_token')
print(f"Total collections fetched: {len(all_collections)}")

Filtering Example

def get_collections_by_date_range(access_token, start_date, end_date):
"""Get collections within a date range"""
return list_collections(
access_token,
date_from=start_date.strftime('%Y-%m-%d'),
date_to=end_date.strftime('%Y-%m-%d'),
page_size=100
)

def get_failed_payouts(access_token):
"""Get all failed payouts"""
return requests.get(
'https://sandbox.api.jpay.africa/api/v1/payments/payouts/list',
headers={'Authorization': f'Bearer {access_token}'},
params={'status': 'failed', 'page_size': 100}
).json()

# Usage
from datetime import datetime, timedelta

start = datetime.now() - timedelta(days=30)
end = datetime.now()

collections = get_collections_by_date_range(access_token, start, end)
print(f"Collections in last 30 days: {collections['count']}")

failed_payouts = get_failed_payouts(access_token)
for payout in failed_payouts['results']:
print(f"Failed payout: {payout['ref_no']} - {payout['amount']} KES")

Transaction Status Values

Collection Status Flow

pending → completed (successful delivery)

└→ failed (delivery failed, automatic refund)

Payout Status Flow

pending → completed (successful delivery)

└→ failed (delivery failed, automatic refund)
StatusDescription
pendingTransaction initiated, awaiting completion
completedTransaction successfully delivered
failedTransaction failed, refund/reversal applied

Reporting and Analytics

Get Daily Transaction Summary

def get_daily_summary(access_token, date):
"""Get summary of transactions for a specific date"""
date_str = date.strftime('%Y-%m-%d')

# Get completed collections
collections = list_collections(
access_token,
status='completed',
date_from=date_str,
page_size=1000
)

# Get completed payouts
payouts = requests.get(
'https://sandbox.api.jpay.africa/api/v1/payments/payouts/list',
headers={'Authorization': f'Bearer {access_token}'},
params={'status': 'completed', 'date_from': date_str}
).json()

total_collected = sum(
float(item['amount'])
for item in collections['results']
)

total_paid_out = sum(
float(item['amount'])
for item in payouts['results']
)

return {
'date': date_str,
'collections_count': collections['count'],
'collections_total': total_collected,
'payouts_count': payouts['count'],
'payouts_total': total_paid_out,
'net_flow': total_collected - total_paid_out
}

Best Practices

1. Pagination Efficiency

Always use pagination for large datasets:

# Good: Use pagination
page = 1
while True:
response = list_collections(token, page=page, page_size=100)
# Process response
if not response['next']:
break
page += 1

# Bad: Try to get all at once
collections = requests.get(endpoint, headers=headers).json()
# May timeout or exceed memory

2. Filter Before Processing

Use filters to reduce data transferred:

# Good: Filter at API level
today = datetime.now().strftime('%Y-%m-%d')
collections = list_collections(
token,
status='completed',
date_from=today,
page_size=100
)

# Bad: Fetch everything then filter
all_collections = list_collections(token)
today_collections = [c for c in all_collections if c['created_at'].startswith(today)]

3. Cache Results

Cache API results to reduce requests:

from functools import lru_cache
from datetime import datetime, timedelta

cache_time = datetime.now()

@lru_cache(maxsize=128)
def get_collections_cached(access_token, status, date_from):
# Check if cache is fresh (less than 5 minutes)
if datetime.now() - cache_time < timedelta(minutes=5):
return cached_result

return list_collections(access_token, status=status, date_from=date_from)

Error Handling

def handle_list_error(response):
"""Handle errors from list endpoints"""
status = response.status_code

if status == 400:
print("Invalid query parameters")
elif status == 401:
print("Token expired, need to refresh")
elif status == 403:
print("Access denied to this resource")
elif status == 404:
print("Endpoint not found")
else:
print(f"Unexpected error: {status}")

Next Steps