Disburse payouts
POST /payments/send disburses funds to one or many beneficiaries
via mobile money or e-wallet. Up to 100 beneficiaries per call.
Supports immediate, scheduled, and recurring schedules.
This is a server-side endpoint — neither SDK exposes a method for it. Call it from your backend.
Choosing a sending type
Section titled “Choosing a sending type”sending_type | Use case |
|---|---|
immediate | One-shot payout. The default. |
scheduled | Disburse on a list of explicit future dates (scheduled_dates). |
recurring | Recurring payroll, allowance, etc. Set frequency, start date, and number of occurrences. |
For payroll, recurring is almost always the right choice — the
gateway tracks each occurrence and emits a webhook per occurrence.
Immediate payout
Section titled “Immediate payout”curl https://app.api.gtwy.pdirect.com/api/v1/payments/send \ -X POST \ -H "Authorization: Bearer sess_AbCdEf..." \ -H "Content-Type: application/json" \ -H "Idempotency-Key: 8d3f0e2b-5c7d-4e9f-aab2-2e4f3d8c0b6e" \ -d '{ "customer_reference": "payout_2026_05_05_001", "currency": "usd", "receipt_mode": "mobile_money", "notify_url": "https://merchant.example.com/pdirect/webhook", "sending_type": "immediate", "beneficiaries": [ { "phone_number": "+243998857000", "amount": "10.00" } ], "note": "Payout for May 5" }'Response:
{ "batch_id": "batch_xyz789", "customer_reference": "payout_2026_05_05_001", "total_amount": "10.00", "total_fee": "0.10", "successful_count": 1, "failed_count": 0, "pending_count": 0, "status": "completed", "beneficiaries": [ { "phone_number": "+243998857000", "amount": "10.00", "currency": "usd", "status": "completed", "transaction_id": "txn_b2c_8f3a4c", "message": "Payout sent", "fee_amount": "0.10" } ], "created_at": "2026-05-05T10:15:00Z", "completed_at": "2026-05-05T10:15:05Z"}The status of the batch can be completed, partial_success,
pending, processing, or failed. Each beneficiary has its own
status — read both.
Bulk payouts
Section titled “Bulk payouts”Up to 100 beneficiaries per request. Mix mobile money and e-wallet
on different lines (set receipt_mode per call, not per
beneficiary):
{ "customer_reference": "payroll_2026_05", "currency": "usd", "receipt_mode": "mobile_money", "notify_url": "https://merchant.example.com/pdirect/webhook", "sending_type": "immediate", "beneficiaries": [ { "phone_number": "+243998857000", "amount": "1500.00" }, { "phone_number": "+243998857001", "amount": "1500.00" }, { "phone_number": "+243998857002", "amount": "1750.00" } ], "note": "May payroll"}Validators:
- Total of all
amounts must be> 0and<= 1,000,000. - No duplicate
phone_number(orwallet_numberforwalletreceipt mode). - Each beneficiary must have the relevant identifier for the
receipt_mode.
If you need to send to a wallet and a mobile-money number in the
same logical batch, issue two separate calls — they share a
customer_reference but have different batch_ids.
Scheduled payouts
Section titled “Scheduled payouts”{ "customer_reference": "rent_2026", "currency": "usd", "receipt_mode": "wallet", "notify_url": "https://merchant.example.com/pdirect/webhook", "sending_type": "scheduled", "scheduled_dates": ["2026-06-01", "2026-07-01", "2026-08-01"], "beneficiaries": [ { "wallet_number": "3005710720108954", "amount": "850.00" } ], "note": "Quarterly rent"}The gateway holds the batch and disburses on each scheduled_dates
entry. Each disbursement gets its own transaction_id and webhook.
Recurring payouts
Section titled “Recurring payouts”{ "customer_reference": "payroll_2026_jane_doe", "currency": "usd", "receipt_mode": "wallet", "notify_url": "https://merchant.example.com/pdirect/webhook", "sending_type": "recurring", "recurring_frequency": "monthly", "recurring_start_date": "2026-05-15", "recurring_occurrences": 12, "beneficiaries": [ { "wallet_number": "3005710720108954", "amount": "1500.00" } ], "note": "Monthly salary"}recurring_frequency accepts daily, weekly, biweekly,
monthly. Combine with recurring_start_date (ISO date) and
recurring_occurrences (>= 1).
Each occurrence emits its own webhook. Cancelling a recurring schedule mid-flight isn’t yet exposed in the API — contact your Pdirect rep.
Idempotency for payouts
Section titled “Idempotency for payouts”Always send Idempotency-Key. A network blip during a payroll
disbursement is the worst possible time to issue duplicate
transfers.
-H "Idempotency-Key: payroll-2026-05-15-jane"The key can be deterministic (a hash of (customer_reference, period)) or a fresh UUID — as long as you can re-send the same
key on retry.
Reconciliation
Section titled “Reconciliation”Two webhooks per transaction:
- One when the batch is created (status:
pendingorprocessing). - One when each beneficiary settles (status:
completedorfailed).
Match incoming webhooks to your local records by
transaction_id for individual lines and batch_id for the
batch-level update.
If you’re polling instead, use
GET /payments/status/{transaction_id}
on each beneficiary’s transaction_id. There is no batch-level
status query in v1.
Common errors
Section titled “Common errors”error_code | Meaning | Fix |
|---|---|---|
1101 INVALID_AMOUNT | A beneficiary amount is <= 0 or batch total > 1,000,000 | Validate before sending |
1103 INVALID_PAYMENT_METHOD | receipt_mode not in [mobile_money, wallet] | Fix the field |
1109 MISSING_REQUIRED_FIELD | E.g. phone_number missing for mobile_money | Validate per beneficiary |
1207 BENEFICIARY_LIMIT_EXCEEDED | More than 100 beneficiaries | Split into multiple batches |
See also
Section titled “See also”- API reference:
/payments/send - Webhooks overview — receiving the per-beneficiary settlement events
- Idempotency — why payouts especially benefit from this