Bulk Payouts
Process multiple payouts at once by uploading a CSV file. This is useful for payroll, vendor payments, or mass disbursements.
Overview
Bulk payouts allow you to process hundreds or thousands of payouts in a single operation. The process involves:
- Preparing a CSV file with payout details
- Uploading the CSV file
- Initiating the bulk payout process
- Monitoring the batch status
Step 1: Upload CSV File
First, upload your payout CSV file using the files API:
1POST /files/v1/payout-csvCSV Format
Your CSV file should have the following format:
1phone,amount,gateway,reference
2+237612345678,10000,MTN_MOMO,Salary January
3+237690123456,15000,ORANGE_MONEY,Commission Q1
4+237670987654,5000,MTN_MOMO,BonusCSV Columns
| Column | Required | Description |
|---|---|---|
phone | Yes | Recipient phone number (with or without + prefix) |
amount | Yes | Payout amount (numeric value) |
gateway | Yes | Payment gateway (MTN_MOMO, ORANGE_MONEY) |
reference | No | Optional reference/description for the payout |
Upload Request
1const formData = new FormData();
2formData.append('file', csvFile);
3
4const response = await fetch('https://api.zopay.com/files/v1/payout-csv', {
5 method: 'POST',
6 headers: {
7 'x-zo-key': apiKey,
8 'x-zo-timestamp': timestamp,
9 'x-zo-nonce': nonce,
10 'x-zo-origin': origin,
11 'x-zo-signature': signature,
12 'x-zo-version': '1.0'
13 },
14 body: formData
15});
16
17const uploadResult = await response.json();
18console.log('File ID:', uploadResult.file_id);Upload Response
1{
2 "file_id": "file-uuid",
3 "filename": "payouts.csv",
4 "row_count": 100,
5 "uploaded_at": "2024-01-15T10:00:00.000Z"
6}Step 2: Process Bulk Payout
After uploading the CSV, process the bulk payout:
1POST /api/v1/disbursements/bulkRequest Body
1{
2 "file_id": "file-uuid",
3 "idempotency_key": "bulk-payout-2024-01-15"
4}Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
file_id | string | Yes | File ID from the CSV upload response |
idempotency_key | string | Yes | Unique identifier to prevent duplicate bulk payout processing |
Response
1{
2 "batch_id": "batch-uuid",
3 "total_payouts": 100,
4 "status": "PROCESSING",
5 "created_at": "2024-01-15T10:00:00.000Z"
6}Response Fields
| Field | Type | Description |
|---|---|---|
batch_id | string | Unique identifier for the bulk payout batch |
total_payouts | number | Total number of payouts in the batch |
status | string | Batch status (PROCESSING, COMPLETED, FAILED) |
created_at | string | Batch creation timestamp |
Step 3: Monitor Bulk Payout Status
Bulk payouts are processed asynchronously. You can check the status of individual payouts using the List Payouts endpoint with a batch filter, or set up webhooks to receive notifications for each payout.
Example: Check Batch Status
1// List payouts from a specific batch
2const response = await fetch('https://api.zopay.com/api/v1/disbursements?batch_id=batch-uuid', {
3 method: 'GET',
4 headers: {
5 'x-zo-key': apiKey,
6 'x-zo-timestamp': timestamp,
7 'x-zo-nonce': nonce,
8 'x-zo-origin': origin,
9 'x-zo-signature': signature,
10 'x-zo-version': '1.0'
11 }
12});
13
14const data = await response.json();
15const successful = data.payouts.filter(p => p.status === 'SUCCESS').length;
16const failed = data.payouts.filter(p => p.status === 'FAILED').length;
17console.log(`Successful: ${successful}, Failed: ${failed}`);Best Practices
- Validate CSV format: Ensure all required columns are present and data is valid before uploading
- Use unique references: Include meaningful references for each payout to help with reconciliation
- Monitor via webhooks: Set up webhooks to receive real-time notifications for each payout
- File size limits: Keep CSV files under 10MB (typically 10,000-50,000 rows)
- Test with small batches: Test with a small batch first (10-20 payouts) before processing large batches
- Handle failures: Some payouts in a batch may fail. Check individual payout statuses and retry failed ones if needed
- Idempotency: Use a unique idempotency key for each bulk payout to prevent duplicate processing
Error Handling
Individual payouts within a batch may fail. Common reasons include:
- Invalid phone numbers
- Insufficient funds in your account
- Gateway service unavailable
- Recipient account issues
Failed payouts will have their status set to "FAILED" with error details. You can query the list of payouts to identify and handle failures.
Important: Ensure you have sufficient funds in your account to cover all payouts in the batch, including fees. The system will process payouts sequentially, and if your account balance becomes insufficient, remaining payouts will fail.
Next Steps
Learn more about:
- Listing payouts to monitor batch progress
- Setting up webhooks for real-time notifications
- Getting payout status for individual payout details