Skip to main content

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

StepEndpointNotes
1POST /payment/disbursementMerchant initiates the payout. Returns immediately.
5POST /payment/approveAdmin-only. Requires bearerAuth JWT + OTP confirmation.
5bPOST /payment/approve/confirmConfirms the approval after OTP verification.
11POST <merchant webhook>Final status push.

Approval workflow

Approval is configured per project in the dashboard under Settings → Payments → Approval Threshold. When enabled:

  1. Any disbursement with amount > threshold enters the PENDING_APPROVAL state instead of going straight to the queue.
  2. An admin in the project must POST to /payment/approve with the payment reference.
  3. The admin receives an OTP and confirms via /payment/approve/confirm.
  4. 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 PROCESSINGFAILED, 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.