bekambeyene / telebirr
Telebirr payment gateway integration for PHP and Laravel 10, 11, 12, and 13.
Requires
- php: ^8.2
- guzzlehttp/guzzle: ^7.8
- illuminate/http: ^10.0 || ^11.0 || ^12.0 || ^13.0
- illuminate/support: ^10.0 || ^11.0 || ^12.0 || ^13.0
- phpseclib/phpseclib: ^3.0
Requires (Dev)
- larastan/larastan: ^2.9 || ^3.0
- laravel/pint: ^1.14
- orchestra/testbench: ^8.0 || ^9.0 || ^10.0 || ^11.0
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^10.0 || ^11.0
README
A fully-featured, secure, and modern PHP SDK for integrating Ethio Telecom's Telebirr SuperApp Payment Gateway.
This package has been thoroughly redesigned to prioritize security, providing first-class integrations, facades, and configuration builders for Laravel 10, 11, 12, and 13, alongside robust support for Vanilla PHP environments.
⚡ Key Features
- Decentralized Architecture: Built with single-responsibility services (
SignatureService,TokenManager,TelebirrHttpClient) for clean integration and easy testing. - Strict Security & SSL Enforcement: Ensures enterprise-grade security by enforcing transport-layer SSL verification.
- Advanced Cryptography:
- Request Signing: Handles RSA signature generation using SHA256 with RSA-PSS padding (with SHA256 MGF1 hash configuration) as strictly required by Telebirr.
- Webhook Verification: Cryptographically validates incoming Telebirr webhooks to prevent spoofing and Man-in-the-Middle (MitM) attacks.
- H5 Redirect URL: Generates secure
PKCS#1signatures for the web gateway payload.
- Flexible Flow Support:
- H5 / Web Checkout Flow: Generate payment URLs seamlessly to redirect web clients.
- In-App Payment Flow: Obtain raw request strings directly for integration inside mobile apps or WebViews.
- Zero-Dependency Laravel Bridge: Includes a built-in Service Provider and Facade that auto-discovers on installation.
📦 Compatibility & Requirements
- PHP:
^8.2(Fully supports PHP 8.2, 8.3, and 8.4) - Laravel Framework:
^10.0 || ^11.0 || ^12.0 || ^13.0 - Extensions Needed:
openssl,curl,json
🚀 Installation
Install the package into your project using Composer:
composer require bekambeyene/telebirr
🔑 Generating RSA Keys
Telebirr requires asymmetric RSA keys to securely sign requests and verify payloads. If you don't have your keys yet, follow these steps to generate them using Ethio Telecom's official tools:
- Download the Sign Tool: Download the official Telebirr Key Generation tool here: https://developer.ethiotelecom.et/developer_tools/static/download/SignTool.zip
- Generate the Key Pair:
Extract the
.zipfile, open the tool, and generate your RSA key pair. - Save your Keys: You will receive a Public Key and a Private Key. You must provide your Public Key to Telebirr via the Developer Portal, and keep the Private Key secure within your application environment.
🛠️ Laravel Integration
Thanks to Laravel's Package Auto-Discovery, the Service Provider and Telebirr Facade are registered automatically.
1. Publish Configuration
Publish the configuration file using Artisan:
php artisan vendor:publish --tag="telebirr-config"
This creates a default config file at config/telebirr.php.
2. Environment Configuration
Add the following credentials provided by Ethio Telecom to your .env file:
TELEBIRR_BASE_URL=https://developerportal.ethiotelebirr.et:38443/apiaccess/payment/gateway TELEBIRR_WEB_URL=https://developerportal.ethiotelebirr.et:38443/payment/web/paygate 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 TELEBIRR_PUBLIC_KEY="-----BEGIN PUBLIC KEY----- YOUR_TELEBIRR_PUBLIC_KEY_HERE -----END PUBLIC KEY-----" TELEBIRR_PRIVATE_KEY="-----BEGIN PRIVATE KEY----- YOUR_MERCHANT_PRIVATE_KEY_HERE -----END PRIVATE KEY-----"
3. Usage inside Laravel Controllers
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Bekambeyene\Telebirr\Facades\Telebirr; use Bekambeyene\Telebirr\Exceptions\TelebirrException; use Illuminate\Support\Facades\Log; class TelebirrPaymentController extends Controller { /** * Start payment checkout flow */ public function initiateCheckout(Request $request) { $request->validate([ 'amount' => 'required|numeric|min:1', 'title' => 'required|string|max:100', ]); try { // 1. Generate the payment redirect URL for H5 Checkout $paymentUrl = Telebirr::createOrder( $request->input('title'), $request->input('amount') ); // 2. Redirect the customer to Telebirr Gateway return redirect()->away($paymentUrl); } catch (TelebirrException $e) { Log::error('Telebirr Payment Error: ' . $e->getMessage()); return back()->with('error', 'Unable to initiate payment. Please try again.'); } } /** * Handle payment notification callback (Webhook) from Telebirr */ public function handleNotification(Request $request) { Log::info('Telebirr Webhook Payload Received: ', $request->all()); try { $payload = $request->except('sign'); $signature = $request->input('sign'); // Securely verify the RSA-PSS webhook signature $isValid = Telebirr::verifyCallbackSignature($payload, $signature); if (!$isValid) { Log::warning('Telebirr Webhook Signature Verification Failed!'); return response('invalid signature', 403); } $tradeStatus = $request->input('trade_status'); $merchantOrderId = $request->input('merch_order_id'); if ($tradeStatus === 'PAY_SUCCESS') { // Update order status in your database securely // e.g. Order::where('order_id', $merchantOrderId)->update(['status' => 'paid']); } return response('success'); // Telebirr expects 'success' response } catch (\Exception $e) { Log::error('Telebirr Webhook Parsing Error: ' . $e->getMessage()); return response('error', 500); } } /** * Verify payment status manually (e.g. on return/success page redirect) */ public function verifyStatus(Request $request) { $merchantOrderId = $request->query('track_number'); if (!$merchantOrderId) { return redirect('/')->with('error', 'Missing order reference.'); } $result = Telebirr::verifyPayment($merchantOrderId); if ($result['success']) { $status = $result['status']; // e.g. "pay_success", "fail", etc. return view('payment.success', ['status' => $status, 'details' => $result['raw_response']]); } return redirect('/')->with('error', 'Verification failed: ' . $result['message']); } }
🐘 Vanilla PHP Integration (Framework-Agnostic)
You can easily use the SDK in native PHP applications. Because the new architecture relies on specialized services, you simply instantiate and inject the dependencies into the main TelebirrClient.
1. Initialize the Client
<?php require 'vendor/autoload.php'; use Bekambeyene\Telebirr\TelebirrClient; use Bekambeyene\Telebirr\Services\TokenManager; use Bekambeyene\Telebirr\Services\SignatureService; use Bekambeyene\Telebirr\Services\TelebirrHttpClient; $config = [ 'base_url' => 'https://developerportal.ethiotelebirr.et:38443/apiaccess/payment/gateway', 'web_url' => 'https://developerportal.ethiotelebirr.et:38443/payment/web/paygate', 'fabric_app_id' => 'your_fabric_app_id', 'app_secret' => 'your_app_secret', 'merchant_app_id' => 'your_merchant_app_id', 'merchant_code' => 'your_merchant_code', 'notify_url' => 'https://yourdomain.com/payment/notify', 'return_url' => 'https://yourdomain.com/payment/success', 'public_key' => '-----BEGIN PUBLIC KEY----- YOUR_TELEBIRR_PUBLIC_KEY -----END PUBLIC KEY-----', 'private_key' => '-----BEGIN PRIVATE KEY----- YOUR_PRIVATE_KEY -----END PRIVATE KEY-----' ]; // Optional: Provide custom logging callback $logger = function (string $message, string $level = 'info', array $context = []) { error_log("[Telebirr SDK][$level] $message " . json_encode($context)); }; // 1. Initialize the HTTP Client (Base URL, Verify SSL = true) $httpClient = new TelebirrHttpClient($config['base_url'], true); // 2. Initialize the Token Manager $tokenManager = new TokenManager($httpClient, $config['fabric_app_id'], $config['app_secret']); // 3. Initialize the Signature Service $signatureService = new SignatureService(); // 4. Boot the Telebirr Orchestrator Client $telebirr = new TelebirrClient($config, $tokenManager, $signatureService, $httpClient, $logger);
2. Standard H5 / Web Checkout Flow
try { $paymentUrl = $telebirr->createOrder('Standard Plan Subscription', 250.00); // Redirect customer to the secure Telebirr gateway header('Location: ' . $paymentUrl); exit; } catch (Exception $e) { echo "Payment failed to initialize: " . $e->getMessage(); }
3. Mobile App InApp / WebView Flow
If you are requesting the payload for a Mobile App SDK (InApp) and want the raw query string instead of the Web Checkout redirect URL:
try { // Generate raw request string for Mobile Client SDK evaluation $rawRequestString = $telebirr->createOrder('InApp Purchase', 120.00, null, [ 'trade_type' => 'InApp', 'raw_request' => true ]); header('Content-Type: application/json'); echo json_encode(['raw_request_string' => $rawRequestString]); } catch (Exception $e) { echo json_encode(['error' => $e->getMessage()]); }
4. Direct Status Verification
$merchantOrderId = '1780080424282'; $result = $telebirr->verifyPayment($merchantOrderId); if ($result['success']) { echo "Status: " . $result['status']; // e.g. "pay_success" print_r($result['raw_response']); } else { echo "Verification failure: " . $result['message']; }
🔒 Security, Signing and Padding Details
The Telebirr Gateway utilizes a complex dual signing architecture. Our SignatureService handles this securely under the hood:
- Pre-order API Request Signature: Signed with RSA-PSS Padding with SHA256 hash & SHA256 Mask Generation Function (
withMGFHash('sha256')). - Webhook Verification: Incoming callbacks are cryptographically verified using RSA-PSS Padding against the provided Public Key.
- Web Paygate Redirect URL Signature: Uses RSA-PKCS1 Padding on the web payload variables (
appid,merch_code,nonce_str,prepay_id,timestamp,sign_type), while leaving structural parameters likeversionandtrade_typeappended to the URL securely.
This SDK dynamically abstracts all these complexities via phpseclib3.
Default endpoints used by the library:
- Test API: https://developerportal.ethiotelebirr.et:38443/apiaccess/payment/gateway
- Production API: https://superapp.ethiomobilemoney.et:38443/apiaccess/payment/gateway
- Test Web Checkout Redirect: https://developerportal.ethiotelebirr.et:38443/payment/web/paygate?
- Production Web Checkout Redirect: https://superapp.ethiomobilemoney.et:38443/payment/web/paygate?
🔗 Links
📞 Support & Contacts
- 📧 General Info / Security Vulnerabilities: bbekam60@gmail.com
- 💬 Developer Support (Telegram): @eth_dev_support
📄 License
This SDK is open-sourced software licensed under the MIT License.