12-Jun-2026
Home / Documentation / Status & callbacks
EN sandbox@lipapay.test Sign in LP

Operating model

Status checks & callbacks

Every product uses the same reliability pattern: push when the platform notifies you, pull when you query the latest state. Implement both before go-live.

1

Initiate

Create payment (engine, portal, airtime, or disbursement). Capture every reference returned.

2

Pending

Customer completes USSD/bank/checkout or voucher flow.

3

Push (callback)

Platform or engine notifies your endpoint with settlement payload.

4

Pull (status)

Your backend queries status or getPayments if callback is late or ambiguous.

5

Fulfill

Mark order paid only when references match and amount/status are consistent.

Product matrix

Product Initiate Pull (status) Push (callback) Key reference
LipaPay Ver2 pay_mobile, initiate-payment/mno|bank, or initiate-secure-payment POST /api/sandbox/transaction/status

After login — on-demand reconciliation when a callback is delayed or missing.

GET or POST /api/sandbox/callback

Simulates LipaPay engine settlement; updates in-memory txn then visible via status.

reference (engine)
controlNumber (portal MNO/bank)
external_reference (secure)
LipaAirtime POST /api/sandbox/airtime/customer/payments or balancerecharge GET /api/sandbox/airtime/user

Wallet balance and profile pull — use callbackUrl to confirm recharge by controlNumber.

POST /api/sandbox/airtime/callbackUrl

Matches production Lipa_Airtime callbackUrl — marks pending recharge successful.

controlNumber
LipaDisbursement POST /api/sandbox/disbursement/payment POST /api/sandbox/disbursement/getPayments

Pull model: list historical payouts for reconciliation (no push callback in sandbox).

List/history only

Use getPayments and payment response txnid/refid in production integrations.

txnid
refid (in response JSON)

Sandbox contracts (copy-ready)

LipaPay status POST /api/sandbox/transaction/status
{
  "ref_id": "CONTROL_OR_ENGINE_REF"
}

Authorization: Bearer <Sanctum token>

LipaPay engine callback /api/sandbox/callback
{
  "message": "success",
  "code": "200",
  "status": true,
  "description": "Payment received",
  "data": {
    "providerType": "MNO",
    "providerName": "Vodacom",
    "amount": 1000,
    "paymentReference": "YOUR_ENGINE_REFERENCE",
    "payerMobile": "255712345678",
    "transactionDate": "2026-05-29 12:00:00",
    "transactionID": "TXN-ABC123",
    "transactionChannel": "USSD"
  }
}
LipaAirtime callbackUrl POST /api/sandbox/airtime/callbackUrl
{
  "controlNumber": "FROM_RECHARGE_RESPONSE",
  "status": true
}
LipaDisbursement history POST /api/sandbox/disbursement/getPayments
{
  "payments": {
    "data": [
      { "txnid": "…", "refid": "…", "amount": 1000 }
    ]
  }
}

Best practices

  • Treat callbacks as the primary signal, but never as the only source of truth — always support a status or list pull for recovery.
  • Make callback handlers idempotent: the same controlNumber or paymentReference may be delivered more than once.
  • Persist merchant reference, platform control number, and engine paymentReference in separate columns before calling fulfill logic.
  • Respond with HTTP 200 quickly on callbacks; perform heavy work asynchronously in your system.
  • For LipaPay engine callback, validate the full nested data.* payload — sandbox returns 422 with field errors when incomplete.
  • For secure checkout, verify amount and external_reference on your server when the browser hits callback_url, not only in the browser.

Sign in to open testing lab Interactive callback tester

Sandbox API testers

Interactive forms for /api/sandbox — same JSON as production, sandbox settlement only. LipaPay callback requires a prior pay_mobile with matching reference.

1 · Engine callback

POST /api/sandbox/callback — updates txn; then verify with status.

paymentReference (engine reference)
amount
payerMobile
transactionID

Sign in to use the full testing lab flow: pay_mobile → callback → status with Sanctum token.

Response

// Submit the form

2 · LipaAirtime callbackUrl

POST /api/sandbox/airtime/callbackUrl — after wallet recharge returns controlNumber.

controlNumber
status (success?)

Response

// Submit the form

3 · LipaPay status (pull)

POST /api/sandbox/transaction/status — requires Sanctum Bearer from POST /api/sandbox/login.

Authorization (Sanctum)
ref_id

Response

// Submit the form