Skip to content
PayCheck

API guide

PayCheck API

End-to-end steps to verify Ethiopian bank and wallet receipts. Base URL for local development: https://paycheck-api-server.praxisnest.com. Update this host when you deploy.

Overview

PayCheck fetches the official receipt from Telebirr, CBE mobile banking, CBE Birr, Bank of Abyssinia, Zemen Bank, or Awash Bank, parses payment fields, and optionally checks that amount and destination account match what you expect.

  • Companies and individuals register on the website.
  • Each workspace creates one or more Apps.
  • Each App gets an API key and per-bank expectation settings.
  • Your backend calls /api/v1/verify/* with that key.

1. Create an account

  1. Open /signup.
  2. Register with email, or continue with Google, Telegram, or GitHub.
  3. You are redirected to the company console at https://paycheck-console.praxisnest.com.

2. Create an App (required for API access)

  1. In the console go to Apps.
  2. Click Create app and give it a name (e.g. Checkout production).
  3. For each bank tab (Telebirr, CBE, CBE Birr, Abyssinia, Zemen, Awash), set:
    • Default expected amount (optional)
    • Default expected account (optional)
    • Require expected amount / account checkboxes
  4. If a require checkbox is on, you must fill that default field (or send it on every request).
  5. Copy the API key immediately - it is shown only once.

You can rotate keys later from the same Apps page. Disabled apps reject verification.

3. Authenticate every verify call

Send the App key on every request:

X-API-Key: pk_live_your_key_here

# or
Authorization: Bearer pk_live_your_key_here

Content-Type for JSON bodies: application/json

4. Expected amount & account

Resolution order for each provider:

  1. Values in the request body (if provided)
  2. Otherwise App defaults for that bank
  3. If the App marks a field as required and neither source has it → 400 REQUIRED_EXPECTATIONS_MISSING

Optional body fields (all providers):

{
  "expectedAmount": 30,
  "expectedAccount": "0964314791",
  "expectedCreditedParty": "Optional receiver name"
}

Account matching supports masked numbers (similarity check), so receipts that show ****4791 can still match your full account when digits align.

5. Verify Telebirr

POST https://paycheck-api-server.praxisnest.com/api/v1/verify/telebirr

curl -X POST https://paycheck-api-server.praxisnest.com/api/v1/verify/telebirr \
  -H "Content-Type: application/json" \
  -H "X-API-Key: pk_live_..." \
  -d '{
    "receipt": "https://transactioninfo.ethiotelecom.et/receipt/DH51J8WQQ5",
    "expectedAmount": 30,
    "expectedAccount": "0964314791"
  }'

receipt may be a full URL or receipt ID. Duplicate already-verified receipts return an error with the existing payment payload.

6. Verify CBE Bank (mobile banking)

POST https://paycheck-api-server.praxisnest.com/api/v1/verify/cbe

curl -X POST https://paycheck-api-server.praxisnest.com/api/v1/verify/cbe \
  -H "Content-Type: application/json" \
  -H "X-API-Key: pk_live_..." \
  -d '{
    "receipt": "https://mbreciept.cbe.com.et/v2-hfHCxG4KatYPWGweBSlG",
    "expectedAmount": 2000,
    "expectedAccount": "1000123456789"
  }'

You can also paste the SMS text that contains the mbreciept link.

7. Verify CBE Birr

POST https://paycheck-api-server.praxisnest.com/api/v1/verify/cbebirr

Option A - invoice URL or SMS:

{
  "receipt": "https://cbepay1.cbe.com.et/aureceipt?TID=DGL91J1KN0P&PH=0964314791",
  "expectedAmount": 510,
  "expectedAccount": "0964314791"
}

Option B - explicit TID + phone:

{
  "tid": "DGL91J1KN0P",
  "phone": "0964314791",
  "expectedAmount": 510
}

Provide either receipt, or both tid and phone.

8. Verify Bank of Abyssinia

POST https://paycheck-api-server.praxisnest.com/api/v1/verify/abyssinia

curl -X POST https://paycheck-api-server.praxisnest.com/api/v1/verify/abyssinia \
  -H "Content-Type: application/json" \
  -H "X-API-Key: pk_live_..." \
  -d '{
    "receipt": "https://cs.bankofabyssinia.com/slip/?trx=FT26106TLDBY65048",
    "expectedAmount": 30,
    "expectedAccount": "567031"
  }'

SMS text containing the slip URL is also accepted.

9. Verify Zemen Bank

POST https://paycheck-api-server.praxisnest.com/api/v1/verify/zemen

curl -X POST https://paycheck-api-server.praxisnest.com/api/v1/verify/zemen \
  -H "Content-Type: application/json" \
  -H "X-API-Key: pk_live_..." \
  -d '{
    "receipt": "Dear Customer,\nBirr 30000 Miscellaneous- deposit has been made to A/c No 149xxxxxxxx3014 on 5-Aug-2026 . ... https://feedback.zemenbank.com?ref=1642028262170001",
    "expectedAmount": 30000,
    "expectedAccount": "1493014"
  }'

Paste the full SMS when possible. We call the same endpoint the feedback page uses (GET /realtimeFeedback/api/check-reference/?ref=…) and require status: "success" + valid: true with a matching transaction_reference. Amount and masked account are parsed from the SMS - the feedback URL alone confirms the ref but does not include them.

10. Verify Awash Bank

POST https://paycheck-api-server.praxisnest.com/api/v1/verify/awash

curl -X POST https://paycheck-api-server.praxisnest.com/api/v1/verify/awash \
  -H "Content-Type: application/json" \
  -H "X-API-Key: pk_live_..." \
  -d '{
    "receipt": "Dear Customer; Telebirr Transfer of 50.00 ETB to ... 251911190282 from 01320217258600/BANK, ... Receipt Link: https://awashpay.awashbank.com:8225/-2KG48CK0X5-5GRA1F. Contact Center 8980.",
    "expectedAmount": 50,
    "expectedAccount": "251911190282"
  }'

Paste the full Awash Pay SMS (preferred) or the receipt URL. We fetch awashpay.awashbank.com HTML and match amount plus destination phone or source account (251911190282 or 01320217258600).

11. Responses & errors

Success envelope:

{
  "success": true,
  "data": {
    "verified": true,
    "provider": "TELEBIRR",
    "payment": {
      "receiptNumber": "...",
      "totalPaidAmount": 30,
      "creditedPartyAccount": "...",
      "status": "VERIFIED",
      "...": "full parsed fields"
    }
  },
  "meta": { "requestId": "uuid" }
}

Error envelope:

{
  "success": false,
  "error": {
    "code": "REQUIRED_EXPECTATIONS_MISSING",
    "message": "Human readable explanation",
    "details": {}
  },
  "meta": { "requestId": "uuid" }
}

Common codes:

  • MISSING_API_KEY / INVALID_API_KEY / REVOKED_API_KEY
  • APP_DISABLED / API_KEY_NOT_LINKED_TO_APP
  • REQUIRED_EXPECTATIONS_MISSING
  • ALREADY_VERIFIED - receipt already used
  • VALIDATION_ERROR - bad payload
  • RATE_LIMIT_EXCEEDED - too many requests

12. Ping & rate limits

GET https://paycheck-api-server.praxisnest.com/api/v1/verify/ping with your API key returns company/app info and providerConfigs.

Each App has a requests-per-minute limit. Responses include RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset. Over limit → HTTP 429.

13. Console Attester

Without writing code, open Attester, select an App, choose a bank, paste a receipt, and verify. The same per-bank rules apply as the API.

Usage history: Usage.

Deploy note

Examples above use https://paycheck-api-server.praxisnest.com. After you deploy the API, replace the base URL in your clients and we will update this page with the production host.