LubaakPay / API Docs
Home Verify v1

Transaction Verify API

A single endpoint that accepts a receipt URL or transaction reference, fetches and parses the receipt from the originating bank, and returns structured transaction data. Verified transactions are cached — repeat lookups are served instantly from the database.

Base URL

/api/v1

Auth

None required

Format

JSON

Endpoint

POST /api/v1/verify
GET /api/v1/verify?reference=…&bank=…

POST accepts a JSON body. GET accepts the same fields as query parameters. POST is preferred to avoid URL-encoding issues with receipt URLs.


Parameters

Field Type Required Description
url string Either/or Full receipt URL. Bank is auto-detected from the hostname. Pass this or reference.
reference string Either/or Transaction reference / receipt ID. Bank is inferred from the pattern, or pass bank explicitly.
bank string Optional Bank slug. Required when the reference pattern is ambiguous (e.g. BOA, Awash, Dashen, M-Pesa). See Supported Banks.
phone string Conditional Required when bank=cbebirr and reference is used (not needed when a full URL is provided).
suffix string Conditional Account destination suffix appended to the reference when building the receipt URL. Required for bank=cbe (last 8 digits) and bank=boa (last 5 digits) when using reference.
settlement_account string Optional Account number or phone the payment is expected to have landed in. When provided, the response includes a settlement_match object with match type and confidence.

Supported Banks

Bank Slug Auto-detect / Notes
Commercial Bank of Ethiopia cbe apps.cbe.com.et
FT-prefixed references auto-detected. PDF receipt.
CBE Mobile Receipt cbemobile mbreciept.cbe.com.et
Token slug. Auto-detected from URL. JSON API.
CBE Birr cbebirr cbepay1.cbe.com.et
Requires phone when using reference. PDF receipt.
Bank of Abyssinia boa cs.bankofabyssinia.com
Requires bank param with reference. JSON API.
Telebirr telebirr transactioninfo.ethiotelecom.et
8–12 char references auto-detected. HTML receipt.
Zemen Bank zemen share.zemenbank.com
16+ char references auto-detected. PDF receipt.
Awash Bank awash awashpay.awashbank.com
Full URL required (no reference template). HTML receipt.
Dashen Super App dashen api.dashensuperapp.com
Full URL required (no reference template). PDF receipt.
M-Pesa Ethiopia mpesa m-pesabusiness.safaricom.et
Requires bank param with reference. PDF via base64.
Wegagen Bank wegagen wegagenbanksc.com.et
Requires bank param with reference. JSON API.
NIB International Bank nib nibinvoice.nibbank.com.et
Requires bank param with reference. JSON API.
Siinqee Bank siinqee receipts.siinqeebank.com
Requires bank param with reference. JSON API.
Abay Bank abay abaymobile.com.et
Requires bank param with reference. JSON API.
Kaafi Ebirr kaafiebirr receipt.ebirr.com
Requires bank param with reference. JSON API.

Rate Limits

Tier Limit Scope
Anonymous 10 requests / hour Per IP address

Cached lookups count against the limit. When exceeded, the API returns 429 Too Many Requests with Retry-After and X-RateLimit-Reset headers indicating when the window resets.


Request Examples

cbe Commercial Bank of Ethiopia
Full URL
POST /api/v1/verify
Content-Type: application/json

{"url": "https://apps.cbe.com.et:100/?id=FT25211G11JQ21827223"}
Reference (auto-detected)
POST /api/v1/verify
Content-Type: application/json

{"reference": "FT25211G11JQ21827223"}
cbemobile CBE Mobile Receipt
Full URL
POST /api/v1/verify
Content-Type: application/json

{"url": "https://mbreciept.cbe.com.et/fHCxyUdnBt2PA0H8ge"}
Slug as reference
POST /api/v1/verify
Content-Type: application/json

{"reference": "fHCxyUdnBt2PA0H8ge", "bank": "cbemobile"}
cbebirr CBE Birr
Full URL
POST /api/v1/verify
Content-Type: application/json

{"url": "https://cbepay1.cbe.com.et/aureceipt?TID=ABC1234567&PH=0911234567"}
Reference + phone
POST /api/v1/verify
Content-Type: application/json

{"reference": "ABC1234567", "bank": "cbebirr", "phone": "0911234567"}
boa Bank of Abyssinia
Full URL
POST /api/v1/verify
Content-Type: application/json

{"url": "https://cs.bankofabyssinia.com/api/onlineSlip/getDetails/?id=FT26166XLKCN05677"}
Reference + bank
POST /api/v1/verify
Content-Type: application/json

{"reference": "FT26166XLKCN05677", "bank": "boa"}
telebirr Telebirr
Full URL
POST /api/v1/verify
Content-Type: application/json

{"url": "https://transactioninfo.ethiotelecom.et/receipt/DF98Q6QQRM"}
Reference (auto-detected)
POST /api/v1/verify
Content-Type: application/json

{"reference": "DF98Q6QQRM"}
zemen Zemen Bank
Full URL
POST /api/v1/verify
Content-Type: application/json

{"url": "https://share.zemenbank.com/rt/94497018108ATWR2520600HM/pdf"}
Reference (auto-detected)
POST /api/v1/verify
Content-Type: application/json

{"reference": "94497018108ATWR2520600HM"}
awash Awash Bank
Full URL (required)
POST /api/v1/verify
Content-Type: application/json

{"url": "https://awashpay.awashbank.com:8225/-E41AE0D86FFA-21XYYW"}
dashen Dashen Super App
Full URL (required)
POST /api/v1/verify
Content-Type: application/json

{"url": "https://api.dashensuperapp.com/receipts/TopUp--Ethio-telecom-air-time-TopUp-387ETAP2522000WK.pdf"}
mpesa M-Pesa Ethiopia
Full URL
POST /api/v1/verify
Content-Type: application/json

{"url": "https://m-pesabusiness.safaricom.et/api/receipt/getReceipt?trxNo=MP12345ABC"}
Reference + bank
POST /api/v1/verify
Content-Type: application/json

{"reference": "MP12345ABC", "bank": "mpesa"}

Response Format

Valid transaction

200 OK · status: verified
{
  "valid":  true,
  "status": "verified",
  "bank":   "boa",
  "cached": false,
  "data": {
    "sender_name":      "MUBAREK SEID JUHAR",
    "sender_account":   "1******77",
    "receiver_name":    "ELIAS WELDU REZAKUM",
    "receiver_account": "1**********08",
    "receiver_bank":    "Commercial Bank of Ethiopia",
    "sent_amount":      "10.00 ETB",
    "service_charge":   "0.06 ETB",
    "tax_vat":          "0.01 ETB",
    "total_paid":       "10.07 ETB",
    "transfer_date":    "14/06/26 12:46",
    "transaction_id":   "FT26166XLKCN",
    "transaction_type": "Other Bank Transfer",
    "reason":           "P2P Transaction"
  }
}

Pending (bank unreachable)

When the bank API is temporarily unreachable (connection timeout), a soft pending state is returned instead of a hard 502 error. Clients should retry.

200 OK · status: pending
{
  "valid":  false,
  "status": "pending",
  "bank":   "cbe",
  "cached": false,
  "data": {
    "error": "Bank service is temporarily unreachable. Please try again in a moment."
  }
}

Invalid / not found

200 OK
{
  "valid":  false,
  "bank":   "boa",
  "cached": false,
  "data": {
    "transaction_id": "",
    "error":          "Invalid reference number"
  }
}

Cached response

When a transaction was previously verified and stored, the response is returned from the database. Only the top-level fields differ — data is identical.

200 OK
{
  "valid":  true,
  "bank":   "boa",
  "cached": true,
  "data":   { ... },
  "confirmation": {
    "confirmed_count":    4,      // how many times this txn has been verified
    "first_confirmed_at": "2026-06-01T09:12:00+03:00",
    "last_confirmed_at":  "2026-06-15T14:33:00+03:00"
  }
}

Settlement match

When settlement_account is provided, the response includes a settlement_match object.

200 OK · match types: exact, suffix, masked_pattern, phone_normalised, unmatched
{
  "valid": true,
  "data": { ... },
  "settlement_match": {
    "matched":          true,
    "match_type":       "phone_normalised",
    "match_confidence": "high"
  }
}

X-Verify-Cache header

Every response carries an X-Verify-Cache header indicating whether the result came from the live upstream or the local DB cache.

Response headers
X-Verify-Cache: HIT   // served from database cache
X-Verify-Cache: MISS  // fetched live from the bank

Response Fields

All fields live inside data. Not every field is present for every bank — omitted fields are simply absent from the object.

Field Description Banks
status verified · pending · invalid — always present at the top level All
sender_name Full name of the payer / debit account holder All
sender_account Masked or partial account number of the sender All
receiver_name Full name of the beneficiary / credit account holder All
receiver_account Masked or partial account / phone of the receiver All
receiver_bank Destination bank name (inter-bank transfers) awash, boa, cbe
sent_amount Amount credited to the receiver (with currency) All
service_charge Bank service / commission fee All
tax_vat 15% VAT on the service charge All
total_paid Total debited from sender including fees All
transfer_date Transaction timestamp (format varies by bank) All
transaction_id Unique transaction reference used for caching All
invoice_no Invoice number (Zemen Bank) zemen
receipt_number Receipt number (CBE Birr) cbebirr
order_id Order ID (CBE Birr) cbebirr
receipt_no Receipt number (M-Pesa) mpesa
status Transaction status string telebirr, zemen
transaction_type Type of transaction (transfer, topup, etc.) boa, cbemobile, dashen, awash
reason Payment reason or narrative cbe, awash, boa, telebirr, mpesa
channel Payment channel used telebirr, cbebirr
service_type Service type label (Dashen) dashen
narrative Free-text narrative (Dashen) dashen
transfer_ref Secondary transfer reference (Dashen) dashen
error Human-readable reason when valid is false All (when invalid)
confirmation.confirmed_count Number of times this transaction has been verified All (cached txns)
confirmation.first_confirmed_at ISO 8601 timestamp of the first verification All (cached txns)
confirmation.last_confirmed_at ISO 8601 timestamp of the most recent verification All (cached txns)
settlement_match.matched true if the receiver account matches settlement_account When settlement_account provided
settlement_match.match_type exact · suffix · masked_pattern · phone_normalised · unmatched When settlement_account provided
settlement_match.match_confidence high or none When settlement_account provided

Error Codes

Status Cause
422 Neither url nor reference provided; unsupported bank value; bank cannot be auto-detected from reference; CBE Birr missing phone; Awash/Dashen missing URL.
200 status=pending Bank API connection timeout or DNS failure. Not a hard error — the client should retry. No credits are deducted.
502 The bank API returned an unexpected error or the PDF/HTML parser failed. Unlike timeouts, these are non-retriable parsing failures.
200 status=invalid Receipt was fetched but the transaction does not exist or was rejected by the bank. Check data.error for the reason.

PDF receipts (CBE, CBE Birr, Dashen, Zemen, M-Pesa) are parsed with smalot/pdfparser — a pure-PHP library with no system dependencies. No additional packages need to be installed on the server.


Playground

Send a live request to /api/v1/verify and inspect the response — no external tools needed.

POST /api/v1/verify
// fill in the form above
Response
// response will appear here