MAA INVEST Pay Docs
API reference

Status API

Signed server-to-server lookup to reconcile an order.

If a webhook was missed, or you simply want to double check an order, ask us. Works for both sandbox and live Merchant IDs.

Request#

GET https://maainvest.co.ke/pay/status.php?merchant_id=…&invoice_id=…&timestamp=…&signature=…

The signature is hex(HMAC-SHA256(merchant_id + "\n" + invoice_id + "\n" + timestamp, API_SECRET)). The timestamp must be within 5 minutes. Call it from your server only, never from the browser.

<?php
$ts  = (string)time();
$sig = hash_hmac('sha256', $MERCHANT_ID . "\n" . 'ORD-1001' . "\n" . $ts, $API_SECRET);
$url = 'https://maainvest.co.ke/pay/status.php?' . http_build_query([
    'merchant_id' => $MERCHANT_ID, 'invoice_id' => 'ORD-1001', 'timestamp' => $ts, 'signature' => $sig,
]);
$res = json_decode(file_get_contents($url), true);
// $res['status'] === 'paid'  =>  safe to treat as paid (also check amount_paid)

Response#

{
  "ok": true,
  "sandbox": false,
  "checkout_id": "9f2c1e7a0b…",
  "invoice_id": "ORD-1001",
  "status": "paid",
  "amount": "1500.00",
  "amount_paid": "1500.00",
  "currency": "KES",
  "receipt": "SGH4XXXXXX",
  "paid_at": "2026-10-23T10:15:30+03:00",
  "reason": null
}

status is one of created, pending, paid, failed, expired. amount_paid, receipt and paid_at are null until paid; reason carries the failure text when failed. If the same invoice has several checkouts, a paid one is returned first, otherwise the newest. Errors return {"ok": false, "error": "…"} with HTTP 400 (bad or stale request), 403 (signature) or 404 (no checkout for that invoice).

For lightweight polling of the customer's checkout page you can also use GET https://maainvest.co.ke/pay/ajax.php?action=status&t=<checkout token> (the t value in the checkout URL). The webhook and the signed Status API are the sources of truth.

Stuck on an integration? Open a ticket from the Support page in your account and include your invoice_id, the time, and the HTTP status you returned.