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
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
page | integer | No | 1 | Page number for pagination |
page_size | integer | No | 50 | Number of records per page (max 100) |
status | string | No | - | Filter by status: pending, completed, failed |
date_from | string | No | - | Filter from date (YYYY-MM-DD) |
date_to | string | No | - | Filter to date (YYYY-MM-DD) |
phone | string | No | - | Filter by customer phone number |
ref_no | string | No | - | 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
| Field | Type | Description |
|---|---|---|
count | integer | Total number of collections |
next | string | URL to next page (null if last page) |
previous | string | URL to previous page (null if first page) |
results | array | Array of collection objects |
Collection Object Fields
| Field | Type | Description |
|---|---|---|
id | string | Unique collection identifier |
payfrom | string | Customer phone number |
amount | string | Collection amount (KES) |
ref_no | string | Your reference number |
account_number | string | Account number |
callback_url | string | Webhook URL |
status | string | Transaction status |
category | string | Transaction category |
created_at | string | Creation timestamp |
Status Codes
| Code | Status | Description |
|---|---|---|
| 200 | Success | Collections retrieved successfully |
| 400 | Bad Request | Invalid query parameters |
| 401 | Unauthorized | Invalid or expired token |
| 403 | Forbidden | Access denied |
| 500 | Server Error | Internal 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
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
page | integer | No | 1 | Page number for pagination |
page_size | integer | No | 50 | Number of records per page (max 100) |
status | string | No | - | Filter by status: pending, completed, failed |
date_from | string | No | - | Filter from date (YYYY-MM-DD) |
date_to | string | No | - | Filter to date (YYYY-MM-DD) |
phone | string | No | - | Filter by recipient phone number |
ref_no | string | No | - | 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
| Field | Type | Description |
|---|---|---|
count | integer | Total number of payouts |
next | string | URL to next page (null if last page) |
previous | string | URL to previous page (null if first page) |
results | array | Array of payout objects |
Payout Object Fields
| Field | Type | Description |
|---|---|---|
id | string | Unique payout identifier |
payto | string | Recipient phone number |
amount | string | Payout amount (KES) |
ref_no | string | Your reference number |
status | string | Transaction status |
category | string | Transaction category |
created_at | string | Creation 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)
| Status | Description |
|---|---|
pending | Transaction initiated, awaiting completion |
completed | Transaction successfully delivered |
failed | Transaction 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
- Initiate Collection - Create new collections
- Initiate Payout - Create new payouts
- Error Handling - Comprehensive error handling guide
- Best Practices - Integration best practices