Skip to main content

Payment Collection Flow

Overview

The payment collection flow describes the sequence of API calls, queue messages, and webhook notifications involved when a merchant initiates a charge against a customer's Mobile Money wallet, bank account, card, or USSD session. All four channels share the same /payment/collection entry point. The gateway routes to the correct operator based on the provider field in the request.

Sequence diagram

sequenceDiagram
autonumber
participant M as Merchant App
participant API as Central API
participant Q as Payment Queue
participant GW as Gateway Service
participant MNO as MNO / Bank Operator
participant C as Customer

M->>API: POST /payment/collection<br/>apiToken, amount, phone, provider
API->>API: validate apiToken &<br/>project quota
API-->>M: 201 Created<br/>{ reference, status: PROCESSING }

API->>Q: enqueue collection job
Q->>GW: dispatch to operator module
GW->>MNO: initiate USSD push /<br/>bank BillPay / card 3DS
MNO->>C: prompt (USSD / OTP / PIN)
C-->>MNO: enter PIN / approve
MNO-->>GW: callback with status
GW->>API: update payment + emit event

alt Payment successful
API->>M: webhook POST to merchant URL<br/>{ reference, status: SUCCESSFUL }
else Payment failed / timed out
API->>M: webhook POST to merchant URL<br/>{ reference, status: FAILED, reason }
end

Key endpoints

StepEndpointNotes
1POST /payment/collectionMerchant initiates the charge. Returns immediately with status: PROCESSING.
10POST <merchant webhook>Final status push from MALIPOPAY to the merchant's configured webhook URL.
GET /payment/reference/{reference}Poll-based status check (fallback if webhook is unavailable).

Webhook payload

The final webhook POST body follows this shape:

{
"reference": "ML008985",
"status": "SUCCESSFUL",
"amount": 1000,
"currency": "TZS",
"phoneNumber": "255742200105",
"provider": "airtel",
"operatorReference": "AT2026041008152300XJ",
"timestamp": "2026-04-10T08:15:32.000Z"
}

See Webhooks for signature verification and retry semantics.

Timeouts and retries

  • USSD push timeout: 90 seconds (customer must complete PIN entry). After that, the operator returns FAILED with reason TIMEOUT.
  • Webhook retry: MALIPOPAY retries the webhook up to 5 times with exponential backoff (1s, 5s, 30s, 2m, 10m) until the merchant returns HTTP 2xx.
  • Idempotency: repeated POST /payment/collection calls with the same reference field return the existing payment without re-charging.