PHPackages                             bekambeyene/telebirr - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Payment Processing](/categories/payments)
4. /
5. bekambeyene/telebirr

ActiveLibrary[Payment Processing](/categories/payments)

bekambeyene/telebirr
====================

A Laravel and PHP SDK for Telebirr H5/SuperApp integration with webhook verification, RSA signing, and production-ready interoperability support.

v3.1.0(1mo ago)49↓88.9%MITPHPPHP ^8.2CI passing

Since May 29Pushed 1mo agoCompare

[ Source](https://github.com/OgBek/Telebirr-laravel-package-sdk)[ Packagist](https://packagist.org/packages/bekambeyene/telebirr)[ RSS](/packages/bekambeyene-telebirr/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (4)Dependencies (18)Versions (8)Used By (0)

 [![Telebirr PHP SDK](https://private-user-images.githubusercontent.com/175112831/600325230-187d06f5-9aaf-4edb-91aa-c31b1ebca7e6.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3ODQzNTI3MTksIm5iZiI6MTc4NDM1MjQxOSwicGF0aCI6Ii8xNzUxMTI4MzEvNjAwMzI1MjMwLTE4N2QwNmY1LTlhYWYtNGVkYi05MWFhLWMzMWIxZWJjYTdlNi5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjYwNzE4JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI2MDcxOFQwNTI2NTlaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT0wMzA3YTJkMmMxNmU2MzNkMjBkNGY5Mzg4NTlhZmRjZTE5MTc5ZjJiN2ZmMDRjZjhjZmU1ZWVmOTc1NmRlZTNkJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZyZXNwb25zZS1jb250ZW50LXR5cGU9aW1hZ2UlMkZwbmcifQ._I7Kfs4FDGLNg78yEocaAJrgNrbTPO8wUIXM3vt3teQ)](https://private-user-images.githubusercontent.com/175112831/600325230-187d06f5-9aaf-4edb-91aa-c31b1ebca7e6.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3ODQzNTI3MTksIm5iZiI6MTc4NDM1MjQxOSwicGF0aCI6Ii8xNzUxMTI4MzEvNjAwMzI1MjMwLTE4N2QwNmY1LTlhYWYtNGVkYi05MWFhLWMzMWIxZWJjYTdlNi5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjYwNzE4JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI2MDcxOFQwNTI2NTlaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT0wMzA3YTJkMmMxNmU2MzNkMjBkNGY5Mzg4NTlhZmRjZTE5MTc5ZjJiN2ZmMDRjZjhjZmU1ZWVmOTc1NmRlZTNkJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZyZXNwb25zZS1jb250ZW50LXR5cGU9aW1hZ2UlMkZwbmcifQ._I7Kfs4FDGLNg78yEocaAJrgNrbTPO8wUIXM3vt3teQ)Telebirr PHP &amp; Laravel SDK
==============================

[](#telebirr-php--laravel-sdk)

*A Laravel and PHP SDK for Telebirr H5/SuperApp integration with webhook verification, RSA signing, and production-ready interoperability support.*

[![Latest Stable Version](https://camo.githubusercontent.com/7c9d215adf48d5a8c01f8532d84c51f2858bb882bceb73e3856093759e8a0947/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f62656b616d626579656e652f74656c65626972723f7374796c653d666f722d7468652d626164676526636f6c6f723d626c7565)](https://packagist.org/packages/bekambeyene/telebirr)[![Total Downloads](https://camo.githubusercontent.com/4048e40c4e7e139d6abbbbaa24b9c5ef7cc4e9ea5b956d8ed8751ac1c3f575ac/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f62656b616d626579656e652f74656c65626972723f7374796c653d666f722d7468652d626164676526636f6c6f723d73756363657373)](https://packagist.org/packages/bekambeyene/telebirr)[![License](https://camo.githubusercontent.com/daa52099573be5a50c320c4387496400f2f722e49f86a42db8d5778130d3582d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e3f7374796c653d666f722d7468652d6261646765)](https://packagist.org/packages/bekambeyene/telebirr)[![PHP Version Compatibility](https://camo.githubusercontent.com/3f01c23181010008f63a3c631f88c424d7aac720c4d1ac41ade8b90491903beb/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f62656b616d626579656e652f74656c65626972723f7374796c653d666f722d7468652d6261646765)](https://packagist.org/packages/bekambeyene/telebirr)

This package solves the complex implementation details of Ethiopia's payment gateway. It prioritizes exact interoperability, determinism, and maintainability to guarantee seamless operation in both Telebirr sandbox and production environments. It supports Laravel 12 and 13, alongside Vanilla PHP environments.

---

🎨 Features
----------

[](#-features)

✨ **Production-Grade Webhook Handling**

- **Unified Webhook Verification:** Parse and verify incoming webhook requests automatically via `Telebirr::handleWebhook(Request $request)`.
- **Clock Drift &amp; Replay Protection:** Enforces strict validation of request age and tracks nonces via Laravel's cache.

🚀 **Configurable Cryptography &amp; Padding**

- **RSA-PSS Default Padding:** Preorder requests, H5 URLs, and webhook signatures default to modern RSA-PSS.
- **Legacy PKCS#1 v1.5 Support:** Optionally switch padding modes.

🛠 **Robust Canonicalization &amp; Smart Keys**

- **Stable Sorting:** Recursively and deterministically sorts parameter structures, preventing PHP hash-order discrepancies.
- **Smart Key Storage Flexibility:** Automatically processes raw strings, base64-encoded, or file path PEM keys (`file:///path/to/key.pem`) without crashing.

---

📦 Installation
--------------

[](#-installation)

Install the package into your project using Composer:

```
composer require bekambeyene/telebirr
```

Publish the configuration file (Laravel):

```
php artisan vendor:publish --tag="telebirr-config"
```

---

⚡ Quick Start
-------------

[](#-quick-start)

Add your credentials to your `.env` file:

```
TELEBIRR_ENV=sandbox

TELEBIRR_FABRIC_APP_ID=your_fabric_app_id
TELEBIRR_APP_SECRET=your_app_secret
TELEBIRR_MERCHANT_APP_ID=your_merchant_app_id
TELEBIRR_MERCHANT_CODE=your_merchant_code
TELEBIRR_NOTIFY_URL=https://yourdomain.com/payment/notify
TELEBIRR_RETURN_URL=https://yourdomain.com/payment/success

# Cryptography Settings (pss or pkcs1)
TELEBIRR_SIGNATURE_PADDING=pss
```

Tip

💡 **Smart Key Storage Flexibility**To avoid multiline `.env` string issues, the SDK supports three ways to load keys:

- **Raw Base64**: Paste just the raw string! The SDK automatically calculates chunking and injects `-----BEGIN PRIVATE KEY-----` boundaries for you.
- **File Path**: `TELEBIRR_PRIVATE_KEY="file:///var/www/keys/private_key.pem"`
- **Base64 Strict**: `TELEBIRR_PRIVATE_KEY="base64:LS0tLS1CRUdJ..."`

Tip

💡 **Sandbox SSL Issue**Adding `TELEBIRR_SSL_VERIFY=false` to your `.env` file resolves the "unable to get local issuer certificate" error when connecting to the Telebirr sandbox API.

---

📱 H5 Payment Controller Example
-------------------------------

[](#-h5-payment-controller-example)

Below is the recommended controller code you should use when integrating our package.

```
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Bekambeyene\Telebirr\Facades\Telebirr;
use Bekambeyene\Telebirr\Exceptions\TelebirrException;
use Bekambeyene\Telebirr\Exceptions\TelebirrServerException;
use Illuminate\Support\Facades\Log;

class PaymentController extends Controller
{
    /**
     * Initiate an H5 payment and redirect the user.
     */
    public function checkout(Request $request)
    {
        try {
            // Provide a clear subject, amount, and optionally a custom order ID
            $paymentUrl = Telebirr::createOrder('Premium Subscription', 250.00, 'ORDER-' . uniqid());

            // Redirect the user to the generated H5 Telebirr Checkout URL
            return redirect()->away($paymentUrl);

        } catch (TelebirrServerException $e) {
            // 60200087: The Telebirr gateway is busy or syncing
            Log::warning('Telebirr server status exception: ' . $e->getMessage());
            return back()->with('error', 'Telebirr payment services are currently busy. Please try again in a few moments.');

        } catch (TelebirrException $e) {
            // Configuration or generic SDK error
            Log::error('Telebirr config error: ' . $e->getMessage());
            return back()->with('error', 'Failed to initiate payment.');
        }
    }
}
```

---

🛡️ Webhook Verification
-----------------------

[](#️-webhook-verification)

Caution

🚨 **CSRF Middleware Exception Required!**Telebirr sends webhooks directly from its servers via a POST request. It does not carry a Laravel CSRF token. If you place your webhook route in `routes/web.php` without an exception, Laravel will instantly block it with a 419 Page Expired error.

**For Laravel 12+:** In `bootstrap/app.php`: `$middleware->validateCsrfTokens(except: ['payment/notification']);`

**For older projects (Laravel 11 and lower):** In `app/Http/Middleware/VerifyCsrfToken.php`: `protected $except = ['payment/notification'];`

```
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Bekambeyene\Telebirr\Facades\Telebirr;
use Bekambeyene\Telebirr\Exceptions\InvalidSignatureException;
use Bekambeyene\Telebirr\Exceptions\TimestampExpiredException;
use Bekambeyene\Telebirr\Exceptions\ReplayAttackException;
use Illuminate\Support\Facades\Log;

class WebhookController extends Controller
{
    public function handle(Request $request)
    {
        try {
            // Automatically validates signature, timestamp fresh window, and checks duplicate nonces
            $payload = Telebirr::handleWebhook($request);

            if ($payload['trade_status'] === 'PAY_SUCCESS') {
                // Process order securely...
            }

            return response('success');

        } catch (InvalidSignatureException $e) {
            Log::error('Webhook Invalid Signature: ' . $e->getMessage());
            return response('invalid signature', 403);
        } catch (TimestampExpiredException $e) {
            Log::error('Webhook Request Expired: ' . $e->getMessage());
            return response('request expired', 403);
        } catch (ReplayAttackException $e) {
            Log::error('Replay Attack detected: ' . $e->getMessage());
            return response('request already processed', 409);
        } catch (\Exception $e) {
            Log::error('Webhook handling failed: ' . $e->getMessage());
            return response('error', 500);
        }
    }
}
```

---

🔍 Signature Troubleshooting
---------------------------

[](#-signature-troubleshooting)

Different Telebirr endpoints use different signature generation rules:

### 1. Preorder Request Signing

[](#1-preorder-request-signing)

Preorder requests (`payment.preorder`) compile top-level properties and recursively sort all parameters. Signatures use the configured padding (`pss` by default).

### 2. H5 Web Checkout Checkout URL Signing

[](#2-h5-web-checkout-checkout-url-signing)

When launching H5 web checkout redirects, Telebirr expects the URL signature to be calculated on **EXACTLY** 5 fields:

- `appid`, `merch_code`, `nonce_str`, `prepay_id`, `timestamp`.

Warning

⚠️ **Do NOT sign `version`, `trade_type`, `sign_type`, or `redirect_url`.** These optional query parameters must be appended to the redirect URL *after* generating the signature. Adding them to the signed payload will cause intermittent signature failures (error `60200099`).

---

❌ Common Errors
---------------

[](#-common-errors)

### `60200099 Verify the sign field failed`

[](#60200099-verify-the-sign-field-failed)

This error means the public key on Telebirr's server cannot verify the signature generated by your private key.

- **Signed Field List:** Check that H5 signatures only include the 5 required fields.
- **Padding Mode mismatch:** Telebirr production requires `pss` (RSA-PSS) padding. Ensure `TELEBIRR_SIGNATURE_PADDING` matches your gateway settings.
- **Accidental double encoding:** Ensure you do not URL-encode the parameters twice.

### `60200087 Organization does not exist`

[](#60200087-organization-does-not-exist)

This status indicates the Telebirr gateway/merchant sync services are busy, down, or undergoing synchronization. Always catch `TelebirrServerException` and prompt users to retry.

---

✅ Production Best Practices
---------------------------

[](#-production-best-practices)

- **Clock Synchronization (NTP):** Ensure clock synchronization is enabled on your production servers.
- **Idempotency &amp; Database Locks:** Acquire database locks on transactions during callback handling.
- **Sandbox vs Production Differences:** Sandboxes are often more permissive than production systems.

---

🧪 Testing
---------

[](#-testing)

Run the tests with:

```
composer test
```

---

❓ FAQ
-----

[](#-faq)

### Does Telebirr use RSA-PSS or PKCS1?

[](#does-telebirr-use-rsa-pss-or-pkcs1)

By default, recent Telebirr implementations use RSA-PSS. You can switch to PKCS1 by setting `TELEBIRR_SIGNATURE_PADDING=pkcs1`.

### Why am I getting 60200099?

[](#why-am-i-getting-60200099)

This signature verification failure is commonly caused by including wrong fields in the signed payload, padding mode mismatch, or wrong keys. See # Common Errors.

### How do I verify webhooks?

[](#how-do-i-verify-webhooks)

Use the `Telebirr::handleWebhook($request)` method. It automatically performs deterministic canonicalization, RSA signature verification, nonce replay checking, and timestamp validation.

### How do I use Telebirr H5 in Laravel?

[](#how-do-i-use-telebirr-h5-in-laravel)

Generate the checkout URL using `Telebirr::createOrder('Title', $amount)` and simply redirect the user using `return redirect()->away($url)`.

### Can I use this package without Laravel?

[](#can-i-use-this-package-without-laravel)

Yes, the core SDK services (`SignatureService`, `TelebirrHttpClient`) are framework-agnostic and can be instantiated directly.

---

📄 License
---------

[](#-license)

This SDK is open-sourced software licensed under the [MIT License](LICENSE).

###  Health Score

42

—

FairBetter than 88% of packages

Maintenance91

Actively maintained with recent releases

Popularity10

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 98.3% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1 days

Total

5

Last Release

51d ago

Major Versions

v1.0.1 → v3.0.02026-06-01

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/8833356?v=4)[bekam](/maintainers/bekam)[@BeKam](https://github.com/BeKam)

---

Top Contributors

[![OgBek](https://avatars.githubusercontent.com/u/175112831?v=4)](https://github.com/OgBek "OgBek (58 commits)")[![aikido-autofix[bot]](https://avatars.githubusercontent.com/in/268977?v=4)](https://github.com/aikido-autofix[bot] "aikido-autofix[bot] (1 commits)")

---

Tags

ethiotelecomlaravelsdktelebirrtelebirr-api

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/bekambeyene-telebirr/health.svg)

```
[![Health](https://phpackages.com/badges/bekambeyene-telebirr/health.svg)](https://phpackages.com/packages/bekambeyene-telebirr)
```

###  Alternatives

[laravel/socialite

Laravel wrapper around OAuth 1 &amp; OAuth 2 libraries.

5.7k108.5M925](/packages/laravel-socialite)[psalm/plugin-laravel

Psalm plugin for Laravel

3345.3M347](/packages/psalm-plugin-laravel)[spatie/laravel-export

Create a static site bundle from a Laravel app

674146.0k6](/packages/spatie-laravel-export)[simplestats-io/laravel-client

Server-side analytics for Laravel that follows the full funnel from visit to registration to payment, attributed to the channel that drove it. Revenue, MRR, churn and ad-spend profit (ROAS/CAC) per channel. GDPR compliant, ad-blocker proof.

5022.6k](/packages/simplestats-io-laravel-client)[fleetbase/core-api

Core Framework and Resources for Fleetbase API

1235.9k21](/packages/fleetbase-core-api)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

255.2k](/packages/aedart-athenaeum)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
