Skip to main content

Transaction Verification API — Python library for verifying Ethiopian payment transactions (CBE, Telebirr, Dashen, Abyssinia, CBE Birr, M-Pesa).

Project description

tx-verify

PyPI Python License: ISC

Python library for verifying Ethiopian payment transactions across multiple providers: CBE, Telebirr, Dashen Bank, Bank of Abyssinia, CBE Birr, and M-Pesa.

Each verifier fetches the official receipt from the provider (PDF or HTML), parses it, and returns typed result objects. No headless browser is bundled — PDFs are parsed with pypdf and HTML with BeautifulSoup — so it runs anywhere Python does.


Supported Providers

Provider Function Input (example)
CBE verify_cbe() reference="FT…", account_suffix="…"
Telebirr verify_telebirr() reference="CE12345678"
Dashen Bank verify_dashen() transaction_reference="123…" (16 dig)
Bank of Abyssinia verify_abyssinia() reference="FT…", suffix="…" (5 dig)
CBE Birr verify_cbe_birr() receipt="…", phone="09…" (local)
M-Pesa verify_mpesa() transaction_id="UE20VG1GS8"
Image (Mistral AI) verify_image() image_bytes, auto-detects provider
Universal verify_universal() reference — auto-routes by format

Installation

pip install tx-verify

Or with uv:

uv pip install tx-verify

Quick Start

import asyncio
from tx_verify import verify_telebirr, verify_cbe

async def main():
    # --- Telebirr ---
    receipt = await verify_telebirr("CE12345678")
    if receipt:
        print(receipt.payer_name, receipt.settled_amount)

    # --- CBE ---
    result = await verify_cbe("FT23062669JJ", account_suffix="12345678")
    if result.success:
        print(f"Paid {result.amount} ETB to {result.receiver}")

asyncio.run(main())

Examples

See the examples/ directory for a runnable example per provider:

File What it shows
telebirr.py Verify a Telebirr receipt by reference number
cbe.py Fetch and parse a CBE PDF receipt
cbe_birr.py Verify a CBE Birr wallet transaction
dashen.py Verify a Dashen Bank receipt with retry logic
abyssinia.py Verify a Bank of Abyssinia transaction
mpesa.py Verify an Ethiopian M-Pesa transaction
image.py Analyse a receipt image with Mistral Vision AI
universal.py Let the library auto-route to the right provider
error_handling.py Catch provider-specific errors gracefully

Provider Reference

CBE — Commercial Bank of Ethiopia

CBE references are 12 characters starting with FT. You must supply the last 8 digits of the account number as a suffix. The bank returns a PDF that is fetched and parsed automatically.

from tx_verify import verify_cbe

result = await verify_cbe("FT23062669JJ", "12345678")
# result.success      → bool
# result.payer        → str | None
# result.receiver     → str | None
# result.amount       → float | None
# result.date         → datetime | None
# result.reference    → str | None
# result.reason       → str | None
# result.error        → str | None

Telebirr

Telebirr references are 10-character alphanumeric codes. The library scrapes the public Ethio Telecom receipt page.

from tx_verify import verify_telebirr

receipt = await verify_telebirr("CE12345678")
# receipt.payer_name, receipt.settled_amount, receipt.total_paid_amount, …

Dashen Bank

Dashen references are 16-digit numbers starting with 3 digits (e.g. 1234567890123456). The verifier fetches a PDF with built-in retry logic (up to 5 attempts).

from tx_verify import verify_dashen

result = await verify_dashen("1234567890123456")
# result.sender_name, result.transaction_amount, result.total, …

Bank of Abyssinia

Abyssinia references are also 12 characters starting with FT, but the suffix is the last 5 digits of the account number. The bank returns JSON rather than a PDF.

from tx_verify import verify_abyssinia

result = await verify_abyssinia("FT23062669JJ", "90172")
# result.payer, result.amount, result.date, …

CBE Birr

CBE Birr receipts are 10-character alphanumeric codes. You also need the wallet phone number in local Ethiopian format (e.g. 0911234567).

from tx_verify import verify_cbe_birr

result = await verify_cbe_birr("AB1234CD56", "0911234567")
# result.customer_name, result.amount, result.paid_amount, …

M-Pesa

M-Pesa references are 10-character alphanumeric codes. The verifier hits the Safaricom primary API.

from tx_verify import verify_mpesa

result = await verify_mpesa("UE20VG1GS8")
# result.payer_name, result.amount, result.service_fee, result.vat, …

Image verification (Mistral Vision)

Upload a receipt image (JPEG/PNG) and Mistral Vision AI will detect whether it is a CBE or Telebirr receipt, extract the reference, and optionally verify it automatically.

from tx_verify import verify_image

with open("receipt.jpg", "rb") as f:
    image_bytes = f.read()

# Detect only
info = await verify_image(image_bytes, auto_verify=False)
print(info.type, info.reference, info.forward_to)

# Auto-verify (account_suffix required for CBE)
info = await verify_image(
    image_bytes,
    auto_verify=True,
    account_suffix="12345678",
)
print(info.verified, info.details)

Requires MISTRAL_API_KEY environment variable and the mistralai package (installed automatically).

Universal — auto-route by reference format

Hand any reference to verify_universal() and it routes to the correct provider based on length and prefix:

Reference format Routed to
16 digits starting with 3 Dashen Bank
12 chars starting with FT + 8-digit suffix CBE
12 chars starting with FT + 5-digit suffix Bank of Abyssinia
10 chars + phone_number CBE Birr
10 chars (no phone) Telebirr
from tx_verify import verify_universal

result = await verify_universal("CE12345678")
print(result.success, result.data, result.error)

Proxy Support

All receipt verifiers accept an explicit proxies argument. Environment variables are never read automatically — you must pass the proxy yourself.

Supported schemes:

Scheme Description
http Plain HTTP forward proxy
https HTTPS proxy (CONNECT tunnel)
socks4 SOCKS4 proxy
socks5 SOCKS5 proxy (client resolves DNS)
socks5h SOCKS5 proxy (proxy resolves DNS)

Authentication is embedded in the URL:

# Single global proxy
proxies = "http://user:pass@proxy.example.com:8080"

# Per-scheme mapping
proxies = {
    "http://":  "http://proxy.example.com:8080",
    "https://": "socks5://localhost:1080",
}

Pass it to any verifier:

from tx_verify import verify_telebirr, verify_cbe, verify_mpesa

# Telebirr through an HTTP proxy
receipt = await verify_telebirr("CE12345678", proxies="http://proxy:8080")

# CBE through SOCKS5
result = await verify_cbe("FT23062669JJ", "12345678", proxies="socks5://127.0.0.1:1080")

# M-Pesa with per-scheme mapping
result = await verify_mpesa("UE20VG1GS8", proxies={
    "http://": "http://proxy:8080",
    "https://": "socks5h://proxy:1080",
})

verify_universal and verify_image also forward proxies to the underlying provider automatically.

SOCKS tip: socks5h:// tells the proxy server to resolve hostnames, which is useful when the client cannot reach DNS directly.


Error Handling

All verifiers return result objects rather than raising for expected failures (network errors, missing receipts, parsing failures). Inspect result.success and result.error.

Telebirr may raise TelebirrVerificationError when a proxy returns an explicit error message. Catch it if you want to show the user a friendly message:

from tx_verify import TelebirrVerificationError, verify_telebirr

try:
    receipt = await verify_telebirr("INVALID_REF")
except TelebirrVerificationError as exc:
    print(f"Telebirr error: {exc}")
    if exc.details:
        print(f"Details: {exc.details}")

The library also provides a generic error handler for wrapping database or internal errors:

from tx_verify.utils.error_handler import AppError, ErrorType

Environment Variables

Variable Purpose
MISTRAL_API_KEY Required for verify_image()
LOG_LEVEL DEBUG or INFO (default INFO)

Development

# Clone
git clone https://github.com/YOUR_USERNAME/tx-verify.git
cd tx-verify

# Install with dev dependencies
pip install -e ".[dev]"

# Install pre-commit hooks
pre-commit install

# Lint & format
ruff check .
ruff format .

# Type-check
mypy tx_verify/

# Run tests
pytest

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tx_verify-0.1.1.tar.gz (134.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tx_verify-0.1.1-py3-none-any.whl (31.7 kB view details)

Uploaded Python 3

File details

Details for the file tx_verify-0.1.1.tar.gz.

File metadata

  • Download URL: tx_verify-0.1.1.tar.gz
  • Upload date:
  • Size: 134.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for tx_verify-0.1.1.tar.gz
Algorithm Hash digest
SHA256 76c334cd110ec63c9ce190da64fbdd04dbca5eb851e479e69fdc069a0b620f75
MD5 12e2c4614ba3b7c81aed8270c838abc9
BLAKE2b-256 20af9d5ebbbe1aeca0cbd89bd61cf017489f5c966361dfa76b0acca2f7f9dbb0

See more details on using hashes here.

Provenance

The following attestation bundles were made for tx_verify-0.1.1.tar.gz:

Publisher: publish.yml on nahom-network/tx-verify

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tx_verify-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: tx_verify-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 31.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for tx_verify-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 9f0d659615c7e75673b874f348a25f7bd920c0cdd5e52911442018f1c6d3f677
MD5 80929b9d5a936e34ec0932ea4754a369
BLAKE2b-256 94a54faf378c1bdf41dbef3a2ee003b641ee04161d0ff095f5df22f513f30e0f

See more details on using hashes here.

Provenance

The following attestation bundles were made for tx_verify-0.1.1-py3-none-any.whl:

Publisher: publish.yml on nahom-network/tx-verify

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page