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+
requestsbeautifulsoup4
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():
- Fetches the receipt from Telebirr
- Parses the HTML
- Extracts the transaction information
- Populates the
TelebirrReceiptobject - 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)
| 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)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| 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.