Skip to main content

Telebirr Receipt Parser

A Python library for fetching, parsing, and verifying Ethiopian Telebirr transaction receipts from the official Ethio Telecom transaction information service.

The library is designed to make it easy to retrieve a Telebirr receipt using its receipt number, extract transaction information, check payment status, verify payer and recipient details, verify payment amounts, and serialize receipt data to dictionaries or JSON.


Features

  • Fetch Telebirr receipts directly using a receipt number
  • Parse Telebirr receipt HTML
  • Support Amharic/English mixed receipt labels
  • Extract payer information
  • Extract recipient information
  • Extract transaction status
  • Extract payment date
  • Extract settled amount
  • Extract total paid amount
  • Extract service fees
  • Extract service fee VAT
  • Extract stamp duty
  • Extract discount amount
  • Extract payment mode
  • Extract payment reason
  • Extract payment channel
  • Extract customer notes
  • Check whether a receipt exists
  • Check whether a transaction is completed
  • Verify payer name and Telebirr number
  • Verify recipient name and Telebirr number
  • Support masked Telebirr numbers
  • Verify payment amounts
  • Verify transaction status
  • Perform complete payment verification
  • Return receipt data as a Python dictionary
  • Return receipt data as JSON
  • Automatic HTTP retries for temporary server errors
  • Custom exceptions for fetching, parsing, and receipt errors

Installation

Install the package from PyPI:

pip install telebirr-receipt

You can also install it using:

python -m pip install telebirr-receipt

After installation, import the package:

from telebirr_receipt import TelebirrReceipt

Requirements

The package requires:

  • Python 3.9+
  • requests
  • beautifulsoup4

These dependencies are installed automatically when you install the package with pip.


Quick Start

The simplest way to use the library is to create a TelebirrReceipt instance with a receipt number and call load().

from telebirr_receipt import TelebirrReceipt

receipt = TelebirrReceipt("YOUR_RECEIPT_NUMBER")

receipt.load()

print(receipt.receipt_no)
print(receipt.payer_name)
print(receipt.credited_party_name)
print(receipt.total_paid_amount)
print(receipt.transaction_status)

Example output:

FT123456789
John Doe
Jane Doe
100.0
Completed

Replace YOUR_RECEIPT_NUMBER with the actual Telebirr receipt number.


How It Works

The library performs the following process:

Receipt Number
      │
      ▼
Telebirr Transaction Service
      │
      ▼
Receipt HTML
      │
      ▼
HTML Parser
      │
      ▼
TelebirrReceipt object
      │
      ├── Payer information
      ├── Recipient information
      ├── Transaction information
      ├── Amount information
      └── Payment information

The library requests the receipt page from the Telebirr transaction information service and parses the returned HTML using BeautifulSoup.

The receipt URL is generated from the receipt number.


Basic Usage

Create a Receipt Object

from telebirr_receipt import TelebirrReceipt

receipt = TelebirrReceipt("YOUR_RECEIPT_NUMBER")

At this point, the receipt has not necessarily been fetched yet.

The receipt is fetched when you call methods such as:

receipt.load()

or methods that require receipt data.


Load a Receipt

Use load() to fetch and parse the receipt.

from telebirr_receipt import TelebirrReceipt

receipt = TelebirrReceipt("YOUR_RECEIPT_NUMBER")

receipt.load()

print(receipt.receipt_no)

load():

  1. Fetches the receipt from Telebirr
  2. Parses the HTML
  3. Extracts the transaction information
  4. Populates the TelebirrReceipt object
  5. Returns the same receipt object

You can therefore also write:

receipt = TelebirrReceipt("YOUR_RECEIPT_NUMBER").load()

Check Whether a Receipt Exists

Use exists() when you only need to know whether a receipt can be successfully retrieved.

from telebirr_receipt import TelebirrReceipt

receipt = TelebirrReceipt("YOUR_RECEIPT_NUMBER")

if receipt.exists():
    print("Receipt exists")
else:
    print("Receipt does not exist")

exists() returns:

True

or:

False

The method catches Telebirr-related errors and returns False when the receipt cannot be successfully loaded.


Check Transaction Status

Use is_completed() to determine whether the transaction status is Completed.

from telebirr_receipt import TelebirrReceipt

receipt = TelebirrReceipt("YOUR_RECEIPT_NUMBER")

if receipt.is_completed():
    print("Payment completed")
else:
    print("Payment is not completed")

The comparison is case-insensitive.

For example:

Completed
completed
COMPLETED

are treated as the same status.


Get Payment Amount

Use get_amount() to get the total paid amount as a numeric value.

receipt = TelebirrReceipt("YOUR_RECEIPT_NUMBER")

amount = receipt.get_amount()

print(amount)

Example:

100.0

The parser converts amount strings such as:

50 Birr
0.87 Birr
1,234.56

into numeric floating-point values.


Get Settled Amount

Use:

settled_amount = receipt.get_settled_amount()

print(settled_amount)

Example:

100.0

The settled amount is separate from the total paid amount.


Get Payer Information

Payer Name

name = receipt.get_payer_name()

print(name)

You can also access:

receipt.payer_name

Payer Telebirr Number

number = receipt.get_payer_number()

print(number)

You can also access:

receipt.payer_telebirr_no

Get Recipient Information

Recipient Name

name = receipt.get_recipient_name()

print(name)

You can also access:

receipt.credited_party_name

Recipient Telebirr Number

number = receipt.get_recipient_number()

print(number)

You can also access:

receipt.credited_party_account_no

Receipt Data

The TelebirrReceipt object contains the following fields.

Receipt Information

receipt.receipt_no
receipt.fetched_at

Payer Information

receipt.payer_name
receipt.payer_telebirr_no
receipt.payer_account_type
receipt.payer_tin_no
receipt.payer_vat_reg_no
receipt.payer_vat_reg_date

Recipient Information

receipt.credited_party_name
receipt.credited_party_account_no

Transaction Information

receipt.transaction_status
receipt.payment_date

Amount Information

Raw amount values:

receipt.settled_amount_raw
receipt.stamp_duty_raw
receipt.discount_amount_raw
receipt.service_fee_raw
receipt.service_fee_vat_raw
receipt.total_paid_amount_raw

Parsed numeric values:

receipt.settled_amount
receipt.stamp_duty
receipt.discount_amount
receipt.service_fee
receipt.service_fee_vat
receipt.total_paid_amount

Payment Information

receipt.total_amount_in_words
receipt.payment_mode
receipt.payment_reason
receipt.payment_channel
receipt.customer_note

Convert Receipt to Dictionary

Use to_dict() to convert the receipt into a Python dictionary.

receipt = TelebirrReceipt("YOUR_RECEIPT_NUMBER")

receipt.load()

data = receipt.to_dict()

print(data)

Example structure:

{
    "receipt_no": "...",
    "payer_name": "...",
    "payer_telebirr_no": "...",
    "payer_account_type": "...",
    "credited_party_name": "...",
    "credited_party_account_no": "...",
    "transaction_status": "Completed",
    "payment_date": "...",
    "settled_amount": 100.0,
    "total_paid_amount": 100.0,
    "payment_mode": "...",
    "payment_reason": "...",
    "payment_channel": "...",
    "customer_note": "...",
    "raw_pairs": {...},
    "fetched_at": "..."
}

The exact values depend on the receipt.


Convert Receipt to JSON

Use to_json() when you need a JSON string.

receipt = TelebirrReceipt("YOUR_RECEIPT_NUMBER")

receipt.load()

json_data = receipt.to_json()

print(json_data)

You can also specify the indentation:

json_data = receipt.to_json(indent=4)

Verify Recipient

You can verify that the receipt belongs to a specific recipient.

receipt = TelebirrReceipt("YOUR_RECEIPT_NUMBER")

result = receipt.check_recipient(
    name="Jane Doe",
    number="251912345678"
)

print(result)

The method returns:

True

if both the recipient name and number match.

Otherwise it returns:

False

Case-Insensitive Recipient Verification

By default, recipient name comparison ignores case.

receipt.check_recipient(
    name="jane doe",
    number="251912345678"
)

is equivalent to:

receipt.check_recipient(
    name="Jane Doe",
    number="251912345678"
)

You can disable case-insensitive matching:

receipt.check_recipient(
    name="Jane Doe",
    number="251912345678",
    ignore_case=False
)

Verify Payer

You can also verify the payer.

receipt = TelebirrReceipt("YOUR_RECEIPT_NUMBER")

result = receipt.check_payer(
    name="John Doe",
    number="251912345678"
)

print(result)

The method verifies both:

  • Payer name
  • Payer Telebirr number

Masked Telebirr Numbers

Telebirr receipts may contain masked numbers.

For example:

2519****6652

The library supports comparison between masked and full numbers.

For example:

receipt.check_recipient(
    name="Jane Doe",
    number="251912346652"
)

can match a receipt containing:

2519****6652

The comparison checks the visible prefix and suffix of the masked number.


Complete Payment Verification

For payment-processing applications, you can perform multiple verification checks at once using verify_payment().

receipt = TelebirrReceipt("YOUR_RECEIPT_NUMBER")

result = receipt.verify_payment(
    expected_recipient_name="Jane Doe",
    expected_recipient_number="251912345678",
    expected_amount=100.00,
)

print(result)

The method can verify:

  • Transaction status
  • Payment amount
  • Payer name
  • Payer number
  • Recipient name
  • Recipient number

All checks are optional.


Verify Amount

You can verify that the payment amount matches an expected amount.

result = receipt.verify_payment(
    expected_amount=100.00
)

print(result)

The result contains:

result["valid"]

and:

result["checks"]["amount"]

Amount Tolerance

You can specify an amount tolerance.

result = receipt.verify_payment(
    expected_amount=100.00,
    amount_tolerance=0.01
)

This allows a small difference between the expected and actual amount.

For example, with:

amount_tolerance=0.01

an actual amount of:

100.005

can be accepted depending on the comparison result.


Verify Transaction Status

By default, verify_payment() expects the transaction status to be:

Completed

Example:

result = receipt.verify_payment(
    expected_status="Completed"
)

You can specify another expected status:

result = receipt.verify_payment(
    expected_status="Pending"
)

Status comparison is case-insensitive.


Verify Payer

result = receipt.verify_payment(
    expected_payer_name="John Doe",
    expected_payer_number="251912345678"
)

Verify Recipient

result = receipt.verify_payment(
    expected_recipient_name="Jane Doe",
    expected_recipient_number="251987654321"
)

Verify Everything

You can combine all available checks:

from telebirr_receipt import TelebirrReceipt

receipt = TelebirrReceipt("YOUR_RECEIPT_NUMBER")

result = receipt.verify_payment(
    expected_recipient_name="Jane Doe",
    expected_recipient_number="251987654321",
    expected_payer_name="John Doe",
    expected_payer_number="251912345678",
    expected_amount=100.00,
    expected_status="Completed",
    amount_tolerance=0.0,
)

print(result)

The returned dictionary contains:

{
    "valid": True,
    "receipt_no": "...",
    "status": "Completed",
    "amount": 100.0,
    "recipient": {
        "name": "...",
        "number": "..."
    },
    "payer": {
        "name": "...",
        "number": "..."
    },
    "checks": {
        "status": True,
        "amount": True,
        "payer_name": True,
        "payer_number": True,
        "recipient_name": True,
        "recipient_number": True
    },
    "errors": {}
}

If one or more checks fail, valid becomes:

False

and the errors dictionary contains information about the failed checks.


Example: Payment Verification in an Application

A common use case is verifying a payment before giving a user access to a product or service.

from telebirr_receipt import TelebirrReceipt

receipt = TelebirrReceipt("YOUR_RECEIPT_NUMBER")

result = receipt.verify_payment(
    expected_recipient_name="My Business",
    expected_recipient_number="2519XXXXXXXX",
    expected_amount=500.00,
)

if result["valid"]:
    print("Payment verified")
else:
    print("Payment verification failed")
    print(result["errors"])

This allows your application to check the receipt information before processing the transaction.


Error Handling

The package provides custom exceptions for different failure cases.

Import them with:

from telebirr_receipt import (
    TelebirrReceipt,
    TelebirrError,
    TelebirrFetchError,
    TelebirrParseError,
    ReceiptNotFoundError,
    PaymentVerificationError,
)

TelebirrError

TelebirrError is the base exception for errors raised by the package.

You can catch all package-specific errors with:

try:
    receipt.load()
except TelebirrError as error:
    print(error)

TelebirrFetchError

Raised when the receipt cannot be fetched successfully.

try:
    receipt.load()
except TelebirrFetchError as error:
    print("Failed to fetch receipt:", error)

This can happen because of network problems or unexpected HTTP responses.


ReceiptNotFoundError

Raised when the receipt does not exist or the receipt page does not contain the required transaction information.

try:
    receipt.load()
except ReceiptNotFoundError:
    print("Receipt not found")

TelebirrParseError

Raised when the returned HTML cannot be parsed correctly.

try:
    receipt.load()
except TelebirrParseError as error:
    print("Unable to parse receipt:", error)

PaymentVerificationError

The package exposes PaymentVerificationError as a custom payment-verification exception type.

from telebirr_receipt import PaymentVerificationError

Recommended Error Handling

For a production application:

from telebirr_receipt import (
    TelebirrReceipt,
    TelebirrError,
    ReceiptNotFoundError,
)

receipt = TelebirrReceipt("YOUR_RECEIPT_NUMBER")

try:
    receipt.load()

    result = receipt.verify_payment(
        expected_amount=100.00,
        expected_status="Completed",
    )

    if result["valid"]:
        print("Payment verified")
    else:
        print("Payment verification failed")
        print(result["errors"])

except ReceiptNotFoundError:
    print("Receipt does not exist")

except TelebirrError as error:
    print("Telebirr error:", error)

HTTP Requests and Retries

The library uses requests to communicate with the Telebirr transaction information service.

Temporary HTTP errors are automatically retried.

The retry configuration includes:

429
500
502
503
504

The library uses multiple retry attempts with exponential-style backoff.

TLS certificate verification is enabled for requests.


Raw Receipt Data

The parser keeps the extracted label/value pairs in:

receipt.raw_pairs

Example:

receipt.load()

print(receipt.raw_pairs)

This can be useful when you want to inspect the values extracted directly from the receipt.


Full Example

from telebirr_receipt import (
    TelebirrReceipt,
    TelebirrError,
    ReceiptNotFoundError,
)

receipt_number = "YOUR_RECEIPT_NUMBER"

receipt = TelebirrReceipt(receipt_number)

try:
    receipt.load()

    print("Receipt:", receipt.receipt_no)
    print("Payer:", receipt.get_payer_name())
    print("Payer Number:", receipt.get_payer_number())

    print("Recipient:", receipt.get_recipient_name())
    print("Recipient Number:", receipt.get_recipient_number())

    print("Status:", receipt.transaction_status)
    print("Payment Date:", receipt.payment_date)

    print("Settled Amount:", receipt.get_settled_amount())
    print("Total Paid:", receipt.get_amount())

    if receipt.is_completed():
        print("Transaction completed")

    result = receipt.verify_payment(
        expected_recipient_name="Jane Doe",
        expected_recipient_number="251987654321",
        expected_amount=100.00,
        expected_status="Completed",
    )

    if result["valid"]:
        print("Payment verified successfully")
    else:
        print("Payment verification failed")
        print(result["errors"])

except ReceiptNotFoundError:
    print("Receipt was not found")

except TelebirrError as error:
    print("Telebirr error:", error)

API Reference

TelebirrReceipt

The main class provided by the package.

TelebirrReceipt(receipt_no=None)

Methods

Method Description
fetch() Fetch the raw receipt HTML
parse(html) Parse receipt HTML
load() Fetch and parse the receipt
exists() Check whether the receipt exists
is_completed() Check whether the transaction is completed
get_amount() Get the total paid amount
get_settled_amount() Get the settled amount
get_payer_name() Get payer name
get_payer_number() Get payer Telebirr number
get_recipient_name() Get recipient name
get_recipient_number() Get recipient account number
check_recipient() Verify recipient name and number
check_payer() Verify payer name and number
verify_payment() Perform complete payment verification
to_dict() Convert receipt to dictionary
to_json() Convert receipt to JSON

Data Model

The main receipt object contains information including:

Payer

payer_name
payer_telebirr_no
payer_account_type
payer_tin_no
payer_vat_reg_no
payer_vat_reg_date

Recipient

credited_party_name
credited_party_account_no

Transaction

receipt_no
transaction_status
payment_date

Amounts

settled_amount
stamp_duty
discount_amount
service_fee
service_fee_vat
total_paid_amount

Payment

total_amount_in_words
payment_mode
payment_reason
payment_channel
customer_note

Additional Data

raw_pairs
fetched_at

Important Note

This package depends on the HTML structure of the Telebirr transaction information service.

If the structure of the official receipt page changes, the parser may require an update.

The library does not control the Telebirr transaction service or its availability.


Responsible Use

This package is intended for legitimate software development and payment verification use cases.

Do not use it to:

  • Misrepresent payments
  • Fraudulently verify transactions
  • Access information you are not authorized to access
  • Abuse the Telebirr service
  • Circumvent security or access controls

Make sure your application's use of receipt information complies with applicable laws, regulations, and the policies of the relevant service providers.


Django / Django REST Framework

The package can also be used inside Django or Django REST Framework applications.

For example:

from telebirr_receipt import TelebirrReceipt

receipt = TelebirrReceipt(receipt_number)

result = receipt.verify_payment(
    expected_recipient_name="My Business",
    expected_recipient_number="2519XXXXXXXX",
    expected_amount=100.00,
)

if result["valid"]:
    # Process verified payment
    pass

This allows the receipt parser to remain a reusable Python library while your Django application handles:

  • Authentication
  • Database operations
  • API endpoints
  • Business logic
  • User accounts
  • Payment records

Example REST API Integration

A Django REST Framework view could use the package like this:

from rest_framework.response import Response
from rest_framework.views import APIView

from telebirr_receipt import TelebirrReceipt


class VerifyPaymentView(APIView):

    def post(self, request):

        receipt_number = request.data.get("receipt_number")

        receipt = TelebirrReceipt(receipt_number)

        result = receipt.verify_payment(
            expected_amount=100.00,
            expected_status="Completed",
        )

        return Response(result)

The package itself does not require Django or Django REST Framework.

It can be used in:

  • Django applications
  • Flask applications
  • FastAPI applications
  • CLI applications
  • Background workers
  • Standalone Python scripts
  • Other Python applications

License

This project is licensed under the MIT License.

See the LICENSE file for the complete license text.


Author

Amare Misgana


Disclaimer

Telebirr and Ethio Telecom are trademarks and services of their respective owners.

This project is an independent Python library and is not affiliated with, endorsed by, or officially supported by Ethio Telecom or Telebirr.

The package retrieves publicly accessible receipt information from the Telebirr transaction information service and provides tools for parsing and verification.


Contributing

Contributions, bug reports, and improvements are welcome.

When submitting an issue, please include:

  • Python version
  • Package version
  • Operating system
  • Error message
  • Relevant receipt structure information
  • Minimal reproducible example

Do not include sensitive personal or financial information in issues or pull requests.


Changelog

1.0.0

Initial release.

Features include:

  • Telebirr receipt fetching
  • Receipt HTML parsing
  • Payer information extraction
  • Recipient information extraction
  • Transaction status extraction
  • Payment amount extraction
  • Payment verification
  • Payer verification
  • Recipient verification
  • Masked Telebirr number comparison
  • Dictionary serialization
  • JSON serialization
  • Custom exception handling
  • HTTP retry support

Metadata

Release files for telebirr-receipt 1.0.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for telebirr-receipt 1.0.2
File Size Uploaded Provenance Actions
telebirr_receipt-1.0.2.tar.gz 20.0 kB Without provenance Details for telebirr_receipt-1.0.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for telebirr-receipt 1.0.2
File Interpreter ABI Platform Actions
telebirr_receipt-1.0.2-py3-none-any.whl Python 3 none any Details for telebirr_receipt-1.0.2-py3-none-any.whl

Total release size: 34.5 kB

Release files / telebirr_receipt-1.0.2.tar.gz

Download URL telebirr_receipt-1.0.2.tar.gz
Size 20.0 kB
Tags Source
SHA-256 checksum
How to use checksums
4d2daafacf3a61c2dc7b4ef73adce14f3ba21e503b877216ad2a474ba6bf316c
BLAKE2b-256 checksum
How to use checksums
c5fd194fbef9e0bc901b3ebd0a0fc15bab2c61ac7f8dafd08cb5f56dd2b20c2a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Release files / telebirr_receipt-1.0.2-py3-none-any.whl

Download URL telebirr_receipt-1.0.2-py3-none-any.whl
Size 14.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a584088ca858b551b51eba8f42f8405ac5f9b3ce5bde7bf1a7a4cfc5f005e0e9
BLAKE2b-256 checksum
How to use checksums
a190451b88ab83d0593a8df54ddf17e5c70c1b9060454f520c6861a07565574f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Security for telebirr-receipt 1.0.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.0.2 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page