API Reference

Verify a Payment

Mobile-money collections are often asynchronous — the payer approves the charge on their phone moments after you initiate it. Use this endpoint to check where a transaction stands at any time.

 1POST /api/v1/payment/verify

The switch looks up the transaction, asks the same provider that processed it for the latest status, saves it, and returns the normalised result. If the transaction has settled and you supplied a callback_url when initiating it, the switch also notifies that URL — see Callbacks below.

#Authentication

Required. Send your API token as a Bearer token — see Authentication.

#Request body

Field Type Rules Description
transaction_id string required The transaction_id returned by Request a Payment.

#Example request

 1curl -X POST https://your-domain.com/api/v1/payment/verify \
 2  -H "Authorization: Bearer YOUR_API_TOKEN" \
 3  -H "Content-Type: application/json" \
 4  -H "Accept: application/json" \
 5  -d '{
 6    "transaction_id": "9b6c2f1e-2a4d-4c7e-9f3a-1b2c3d4e5f6a"
 7  }'

#Response

200 OK — verification always returns HTTP 200 because the request itself succeeded. The top-level status mirrors the transaction's real outcome (success, failed, or pending) — it is not a generic "the API call worked" flag — so you can branch on it directly.

A successful payment:

 1{
 2  "status": "success",
 3  "message": "Transaction completed successfully",
 4  "data": {
 5    "transaction_id": "9b6c2f1e-2a4d-4c7e-9f3a-1b2c3d4e5f6a",
 6    "reference": "lenco_ref_abc123",
 7    "status": "success",
 8    "provider_status": "successful",
 9    "amount": 50.0,
10    "currency": "ZMW"
11  }
12}

A failed payment (note the top-level status is failed, not success):

 1{
 2  "status": "failed",
 3  "message": "Transaction failed",
 4  "data": {
 5    "transaction_id": "9b6c2f1e-2a4d-4c7e-9f3a-1b2c3d4e5f6a",
 6    "reference": "lenco_ref_abc123",
 7    "status": "failed",
 8    "provider_status": "failed",
 9    "amount": 50.0,
10    "currency": "ZMW"
11  }
12}

A pending payment (still awaiting the payer / provider):

 1{
 2  "status": "pending",
 3  "message": "Transaction is still pending",
 4  "data": { "status": "pending", "provider_status": "pay-offline", "...": "..." }
 5}
Field Description
status (top-level) The transaction's normalised outcome: success, failed, or pending. Branch on this.
message A human-readable summary of the outcome.
data.status The same normalised status (mirrors the top-level status).
data.provider_status The raw status string from the provider (e.g. Lenco's successful, pay-offline).
data.reference The provider's reference for the transaction.

A genuine error (e.g. the provider can't be reached, or the transaction isn't found) is different — those return status: "error" with a 4xx/5xx code, so error always means "verification failed", never "the payment failed".

#Status mapping

The switch normalises each provider's statuses onto three states, so your integration only ever deals with success, failed, or pending:

Switch status Lenco statuses
success successful
failed failed
pending pending, pay-offline, 3ds-auth-required

#Errors

Status message Meaning
404 Transaction not found No transaction with that transaction_id belongs to your account.
422 The provider for this transaction is no longer available The driver that created the transaction is missing.
4xx/5xx (provider message) The provider could not be reached or returned an error.

#Callbacks

If a transaction was created with a callback_url, the switch delivers the final result to that URL once — the first time verification finds the transaction in a settled state (success or failed). Pending checks never fire a callback.

The callback is an HTTP POST with this JSON body:

 1{
 2  "transaction_id": "9b6c2f1e-2a4d-4c7e-9f3a-1b2c3d4e5f6a",
 3  "reference": "lenco_ref_abc123",
 4  "status": "success",
 5  "amount": 50.0,
 6  "currency": "ZMW",
 7  "provider": "Lenco"
 8}

Notes:

  • Delivery is queued and retried (up to 3 attempts with backoff), so make your endpoint idempotent — key off transaction_id.
  • A transaction is notified at most once; repeated verification of an already-settled, already-notified transaction will not re-send the callback.
  • Respond with a 2xx status to acknowledge receipt.