Skip to main content

Payment Statuses

Status values

StatusApplies toMeaning
PENDINGCollectionCreated, but the customer has not acted yet: the push is waiting for a PIN, or a link has not been opened.
PROCESSINGBothDispatch is in flight inside MALIPOPAY.
PROCESSEDBothHanded to the operator, who accepted it and will call back with the final outcome.
AWAITING_APPROVALPayoutCreated and waiting for approval. No money has moved.
APPROVEDPayoutApproved and debited from your wallet; being dispatched.
SUCCESSFULBothCompleted. Money has moved.
PARTIALCollectionSome of the amount has been paid. Compare paidAmount with amount.
PAIDCollectionThe requested amount has been received in full.
FAILEDBothCould not complete. failureReason says why. A failed payout is refunded automatically.
CUSTOMER_REJECTEDCollectionThe customer declined the prompt.
REJECTEDBothRejected by MALIPOPAY or the operator before reaching the customer.
CANCELLEDBothCancelled before completion.

Treat SUCCESSFUL, PAID, FAILED, REJECTED, CUSTOMER_REJECTED and CANCELLED as terminal. Anything else can still change.

Collection flow

PENDING → PROCESSING → PROCESSED → SUCCESSFUL / PAID
↘ PARTIAL
↘ FAILED
↘ CUSTOMER_REJECTED
↘ CANCELLED

Disbursement flow

AWAITING_APPROVAL → APPROVED → PROCESSING → SUCCESSFUL
↘ FAILED (balance refunded)

A payout never skips AWAITING_APPROVAL. If you are waiting for a payout that never arrives, check that it was approved before you look at anything else. See Payment Disbursement Flow.

Which transitions fire a webhook

Not every status change notifies you. Only the outcomes do:

EventFired when
payment.confirmedA collection reaches SUCCESSFUL, PAID or PARTIAL
payment.failedA collection reaches FAILED, REJECTED, CANCELLED or expires
payment.refundedA collection is refunded or reversed
payout.approvedA payout reaches APPROVED
payout.confirmedA payout reaches SUCCESSFUL
payout.failedA payout fails

PROCESSING and the initial creation fire nothing. Do not build a state machine that waits for an "in progress" webhook, because none is coming.

Polling vs webhooks

Use webhooks. If you must poll, use GET /api/v1/payment/reference/{reference}, no more than once every 10 seconds, and stop after 5 minutes. A collection that has not resolved within the 90-second USSD window is not going to resolve because you asked again.