Statuses & webhooks
The lifecycle of a transfer and the webhook events to listen for to track it reliably.
6 min read
A Mobile Money payout is asynchronous: the API returns 201 Created immediately, then the
status evolves as the operator processes the request.
Lifecycle
| Status | Meaning | Terminal? |
|---|---|---|
pending | Accepted, not yet sent to the operator. | no |
processing | Submitted to the operator. | no |
succeeded | The beneficiary has received the funds. | yes |
failed | Declined (invalid number, limit, unavailability). | yes |
cancelled | Cancelled before completion. | yes |
Listen for webhooks
transfer.succeededeventThe payout has succeeded. Update your accounting.
{
"id": "evt_3pQ9aZ7",
"type": "transfer.succeeded",
"data": {
"id": "po_9Kdm2Lp",
"status": "succeeded",
"amount": 100000,
"channel": "cm.mtn"
}
}transfer.failedeventThe payout has failed; the amount is re-credited to the balance held by our licensed partner.
{
"id": "evt_5sRt8Uv",
"type": "transfer.failed",
"data": {
"id": "po_7Hn3Qw",
"status": "failed",
"amount": 100000,
"reason": "invalid_recipient"
}
}Never consider a transfer successful on a 201
201 Created means "accepted", not "paid". Wait for
transfer.succeeded before marking a seller as settled. When in doubt, re-read the
status via GET /transfers/{uid}.
Reconciliation
For end-of-day reconciliations, list transfers by period (see Pagination) and compare with your received webhooks — any discrepancy can be diagnosed in Konsole → API Logs.