Payment Disbursement Flow
Overview
Disbursement (aka payout) sends funds from the merchant's Malipopay balance to a customer's Mobile Money wallet or bank account. Unlike collection, disbursement is a push from MALIPOPAY. No customer interaction is required. For projects configured with the approval workflow, disbursements above a configurable threshold require admin approval before execution.
Sequence diagram
sequenceDiagram
autonumber
participant M as Merchant App
participant API as Central API
participant Admin as Admin (optional)
participant Q as Payout Queue
participant GW as Gateway Service
participant MNO as MNO / Bank Operator
participant C as Customer Account
M->>API: POST /payment/disbursement<br/>apiToken, amount, phone, provider
API->>API: validate apiToken,<br/>balance, quota
API-->>M: 201 Created<br/>{ reference, status: PENDING_APPROVAL }
opt Amount above approval threshold
API->>Admin: POST /payment/approve<br/>(admin bearerAuth)
Admin-->>API: approve<br/>(requires OTP)
API->>API: mark payment APPROVED
end
API->>Q: enqueue disbursement
Q->>GW: dispatch to operator module
GW->>MNO: B2C payout request
MNO->>C: credit wallet / account
MNO-->>GW: callback with status
GW->>API: update payment + emit event
alt Disbursement successful
API->>M: webhook { reference, status: SUCCESSFUL }
else Disbursement failed
API->>API: refund merchant balance
API->>M: webhook { reference, status: FAILED, reason }
end
Key endpoints
| Step | Endpoint | Notes |
|---|---|---|
| 1 | POST /payment/disbursement | Merchant initiates the payout. Returns immediately. |
| 5 | POST /payment/approve | Admin-only. Requires bearerAuth JWT + OTP confirmation. |
| 5b | POST /payment/approve/confirm | Confirms the approval after OTP verification. |
| 11 | POST <merchant webhook> | Final status push. |
Approval workflow
Approval is configured per project in the dashboard under Settings → Payments → Approval Threshold. When enabled:
- Any disbursement with
amount > thresholdenters thePENDING_APPROVALstate instead of going straight to the queue. - An admin in the project must POST to
/payment/approvewith the payment reference. - The admin receives an OTP and confirms via
/payment/approve/confirm. - Only after confirmation does the payment enter the queue.
If approval isn't configured, step 5 is skipped and the flow goes straight from step 4 to step 6.
Refund semantics
If the MNO/bank returns FAILED, MALIPOPAY automatically refunds the merchant's balance. The funds are never lost. The merchant sees this as a state transition from PROCESSING → FAILED, and the balance is restored before the webhook fires.
Rate limits and caps
- Daily cap: per-project disbursement limit (configurable, default TZS 50M/day).
- Per-transaction cap: TZS 3M/transaction for MNO, TZS 20M/transaction for bank.
- Velocity check: max 100 disbursements per minute per project; exceeding this returns HTTP 429.