Verify payments

Always confirm a charge on your server before delivering goods or unlocking access.

Why verify?

The browser may return to your callback_url with status=success, but that can be forged. Treat redirects as UX only. Fulfill after:

  • A signed webhook (charge.success), and/or
  • A successful Verify response with data.status === "paid".

Call Verify

curl https://waaguan.com/api/v1/transaction/verify/wa-6281126272 \
  -H "Authorization: Bearer sk_live_YOUR_SECRET_KEY"
Sample response
{
  "status": true,
  "message": "Verification successful",
  "data": {
    "id": "3f2a1b4c-5d6e-7f80-91a2-b3c4d5e6f708",
    "status": "paid",
    "reference": "wa-6281126272",
    "amount": 50,
    "amount_received": 50,
    "currency": "GHS",
    "paid_at": "2026-07-19T12:04:11.000Z",
    "customer_email": "customer@email.com",
    "customer_name": "AMA MENSAH",
    "metadata": { "order_id": "1001" }
  }
}

Polling vs webhooks

Webhooks are preferred for production. Polling Verify is useful for:

  • Callback pages that need to show “Payment confirmed”
  • Reconciliation jobs
  • Recovering if a webhook delivery failed

Statuses to handle

  • pending — waiting for MoMo
  • partial — some amount received; still waiting
  • paid — safe to fulfill
  • expired — window closed; create a new charge
  • cancelled — charge was cancelled

Fulfill only when status is paid. amount_received shows how much has been applied so far (useful while partial).

Full reference: Errors & statuses.