Endpoints
Two endpoints — trigger a payment prompt, then poll for the result.
/api/stk-push
Trigger STK Push
Sends an M-Pesa PIN prompt to the customer's phone. When QUEUE_CONNECTION=sync the full record is returned immediately (200). With a real queue driver only the tracking_id is returned (202).
| Field | Type | Description | |
|---|---|---|---|
phone | string | required | Accepts 07xx, 254xx, or +254xx |
amount | integer | required | Amount in KES, minimum 1 |
reference | string | required | Account reference shown to the customer |
tag | string | optional | Internal label, not shown to customer |
Request
{
"phone": "0712345678",
"amount": 1500,
"reference": "INV-2024-001",
"tag": "loan-repayment"
}
200 — Sync (full record)
{
"success": true,
"data": {
"id": 1,
"tracking_id": "550e8400-...",
"status": 0,
"status_label": "Pending",
"response_code": null,
"transaction_code": null,
...
}
}
In async mode the response is 202 with only { "success": true, "tracking_id": "...", "message": "..." }. Use the tracking_id to poll below.
/api/stk-push/{tracking_id}
Check Payment Status
Returns the full STK Push record. Poll every 10 seconds until status is 1. Payment confirmation from Safaricom typically arrives within 10–60 seconds.
200 — Success
{
"success": true,
"data": {
"tracking_id": "550e8400-...",
"phone_number": "254712345678",
"amount": "1500",
"reference": "INV-2024-001",
"transaction_code": "RBC12ABC34",
"status": 1,
"status_label": "Success",
"response_code": "0",
"meta": {
"transaction_date": "2024-03-21 14:30:55"
}
}
}
200 — Pending
{
"success": true,
"data": {
"tracking_id": "550e8400-...",
"status": 0,
"status_label": "Pending",
"response_code": null,
"transaction_code": null,
...
}
}
404 — Not Found
{
"success": false,
"message": "Record not found."
}
A 404 immediately after triggering is normal in async mode — the job may not have run yet. Retry after a few seconds.
/hooks/stk-push
Safaricom Callback
Receives async payment results from Safaricom. This endpoint is public, CSRF-exempt, and should not be called directly. It updates the STK Push record and sets status, response_code, and transaction_code.