Transaction Lifecycle
Payments should not be a black box. Know exactly where every transaction is at all times.
Both STK Push and B2C payouts share the same state model. Understanding the lifecycle lets you handle every outcome correctly — including failures.
Transaction states
| Status | What it means |
|---|
PENDING | Request accepted. Waiting for customer action (STK) or provider acceptance (B2C). |
PROCESSING | Provider accepted. Final confirmation pending. |
SUCCESS | Complete. Funds moved. |
FAILED | Failed — provider declined, timeout, or customer cancelled. |
REVERSED | B2C wallet balance credited back after failure. |
CANCELLED | Cancelled before processing began. |
Terminal states — no further updates: SUCCESS, FAILED, REVERSED, CANCELLED
STK Push lifecycle
POST /payments/stk
│
▼
PENDING ──── Customer receives phone prompt ──── Customer cancels
│ │
Customer enters PIN FAILED / CANCELLED
│
▼
PROCESSING ──── Provider processing ──── Provider timeout / error
│ │
M-Pesa confirms FAILED
│
▼
SUCCESS
Typical completion: 30–90 seconds after the customer enters their PIN.
| State | What to do |
|---|
PENDING | Request sent. Wait for the customer to act. |
PROCESSING | PIN entered. Wait for M-Pesa confirmation. |
SUCCESS | Fulfil the order. |
FAILED | Notify the customer. Service fee is not refunded. |
CANCELLED | Customer dismissed the prompt. Retry if appropriate. |
B2C payout lifecycle
POST /b2c/payouts
│
▼
PENDING ──── Queued for processing
│
▼
PROCESSING ──── Provider sends to M-Pesa ──── Provider error / timeout
│ │
M-Pesa confirms FAILED
│ │
▼ REVERSED
SUCCESS (B2C balance credited back)
Typical completion: 30 seconds to 5 minutes.
| State | What to do |
|---|
PENDING | Request queued. No action needed. |
PROCESSING | Provider accepted. Wait for M-Pesa. |
SUCCESS | Payout delivered. |
FAILED | B2C wallet reversal is automatic. Retry when ready. |
REVERSED | Wallet credited. Safe to retry the payout. |
Receiving state updates
Webhooks (recommended)
Supply a callbackUrl on every payment request. PalPluss delivers a POST to that URL when the transaction reaches a terminal state.
See the Webhooks guide for payload structure and retry policy.
Polling
Poll GET /transactions/{id} if webhooks are unavailable.
curl https://api.palpluss.com/v1/transactions/{transactionId} \
-u "$PALPLUSS_API_KEY:"
Recommended polling intervals:
- Wait 15 seconds after initiation.
- Poll every 10 seconds while status is
PENDING or PROCESSING.
- Stop at any terminal state.
- After 5 minutes without a terminal state, treat the transaction as likely failed.
Aggressive polling consumes your rate limit (60 requests/minute). Use webhooks as your primary mechanism.
Idempotency
- Each
POST /payments/stk creates a distinct transaction and a distinct M-Pesa checkout.
- Retrying without customer action sends a new prompt — do not retry unless the customer requests it.
- Service wallet top-ups support the
Idempotency-Key header to prevent duplicate funding requests.