matt-di/laravel-telebirr
Composer 安装命令:
composer require matt-di/laravel-telebirr
包简介
Telebirr payment gateway integration for Laravel applications
README 文档
README
Telebirr payment gateway integration for Laravel applications with support for single and multi-merchant setups.
🎯 Integration Type
This package is designed for Telebirr Super App integration where the frontend handles payment requests through the Telebirr mobile application.
- Backend Role: Generates signed payment requests and handles webhooks
- Frontend Role: Uses Telebirr mobile SDK to process payments
- 📖 Frontend Integration: Refer to Telebirr Developer Documentation for mobile app integration details
- 🔗 Official Resources: Check Telebirr's official documentation for SDK implementation and best practices
Features
- 🚀 Simple Setup - Get started in minutes with zero configuration
- 🏪 Multi-Merchant Support - Perfect for multi-branch or multi-store applications
- 🔐 Enterprise Security - RSA PSS signatures, webhook verification, SSL controls
- ⚡ High Performance - Token caching, queue-based processing, retry logic
- 🛠 Developer Friendly - Artisan commands, comprehensive logging, extensive configuration
- 🔧 Highly Configurable - Extensive customization options for any use case
- 📱 Mobile SDK Ready - Raw request generation for Telebirr mobile applications
- 🎯 Event Driven - Laravel events for payment lifecycle hooks
Installation
Basic Setup (Single Merchant)
composer require matt-di/laravel-telebirr php artisan telebirr:install
Multi-Merchant Setup
composer require Matt-di/laravel-telebirr php artisan telebirr:install --mode=multi --run-migrations
Quick Start
1. Configure Environment
Add your Telebirr credentials to .env:
# Single merchant mode TELEBIRR_MODE=single TELEBIRR_FABRIC_APP_ID=your_fabric_app_id TELEBIRR_MERCHANT_APP_ID=your_merchant_app_id TELEBIRR_MERCHANT_CODE=123456 TELEBIRR_APP_SECRET=your_app_secret TELEBIRR_RSA_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
2. Create Payment Request
use Telebirr\LaravelTelebirr\Facades\Telebirr; $rawRequest = Telebirr::initiatePayment([ 'txn_ref' => 'TXN_' . time(), 'amount' => 150.00, 'subject' => 'Order Payment' ]); // Returns: "appid=MERCHANT123&merch_code=MC456&nonce_str=abc...&prepay_id=PRE123...×tamp=202512021200&sign_type=SHA256WithRSA&sign=signed_data..."
3. Handle Webhook (Automatically Done)
The package handles webhook verification, signature checking, and payment verification automatically.
Usage Examples
Single Merchant
Step 1: Configure Environment
Add your Telebirr credentials to .env:
TELEBIRR_MODE=single TELEBIRR_FABRIC_APP_ID=your_fabric_app_id TELEBIRR_MERCHANT_APP_ID=your_merchant_app_id TELEBIRR_MERCHANT_CODE=your_merchant_code TELEBIRR_APP_SECRET=your_app_secret TELEBIRR_RSA_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nYOUR_PRIVATE_KEY_HERE\n-----END PRIVATE KEY-----"
Step 2: Install the Package
php artisan telebirr:install
Step 3: Initiate a Payment
use Telebirr\LaravelTelebirr\Facades\Telebirr; $rawRequest = Telebirr::initiatePayment([ 'txn_ref' => 'TXN_' . time(), 'amount' => 150.00, 'subject' => 'Order Payment' ]); // Returns a signed query string for the mobile SDK: // "appid=MERCHANT123&merch_code=MC456&nonce_str=abc...&prepay_id=PRE123...×tamp=202512021200&sign_type=SHA256WithRSA&sign=signed_data..."
Step 4: Web Checkout (Browser-based Payment)
For web-based checkout, the package provides a dedicated API endpoint that handles the entire flow:
Using the API endpoint (recommended):
// POST /api/telebirr/web-checkout // Request: { "invoice_id": "INV_12345", "amount": 150.00, "subject": "Order Payment" } // Response: { "success": true, "data": { "invoice_id": "INV_12345", "prepay_id": "PRE123456789", "checkout_url": "https://developerportal.ethiotelebirr.et:38443/payment/web/paygate?appid=...&prepay_id=...&sign=...", "amount": 150.00, "subject": "Order Payment" } }
Then redirect the user to the checkout URL:
// Frontend example fetch("/api/telebirr/web-checkout", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ invoice_id: "INV_12345", amount: 150.0, subject: "Order Payment", }), }) .then((res) => res.json()) .then((data) => { if (data.success) { window.location.href = data.data.checkout_url; } });
Using the Facade directly:
use Telebirr\LaravelTelebirr\Facades\Telebirr; // First, initiate payment to get a prepay_id $rawRequest = Telebirr::initiatePayment([ 'txn_ref' => 'TXN_' . time(), 'amount' => 150.00, 'subject' => 'Order Payment' ]); // Parse the prepay_id from the raw request parse_str($rawRequest, $params); $prepayId = $params['prepay_id']; // Generate the checkout URL $checkoutUrl = Telebirr::generateCheckoutUrl($prepayId); // Redirect user to the checkout URL return redirect($checkoutUrl);
#### USSD Push Payment (C2B)
```php
use Telebirr\LaravelTelebirr\Facades\Telebirr;
// Initiate USSD push payment
$rawRequest = Telebirr::ussdPush([
'phone' => '0912345678', // or international format +2519...
'txn_ref' => 'TXN_' . time(),
'amount' => 150.00,
'subject' => 'Order Payment',
// Optional overrides
// 'trade_type' => 'Checkout',
// 'timeout_express' => '30m',
]);
// $rawRequest is a signed query string that can be sent via USSD or SMS gateway
Custom Parameter Overrides
You can override any request parameter by passing additional keys in the order data. For example:
$rawRequest = Telebirr::initiatePayment([ 'txn_ref' => 'TXN_' . time(), 'amount' => 200.00, 'subject' => 'Custom Order', // Override trade type and timeout 'trade_type' => 'Purchase', 'timeout_express' => '45m', ]);
All other default parameters (like appid, merch_code, nonce_str) will be generated automatically.
The checkout URL is configured via environment variables:
```env
TELEBIRR_WEB_BASE_URL=https://developerportal.ethiotelebirr.et:38443/payment/web/paygate?
TELEBIRR_WEB_VERSION=1.0
TELEBIRR_WEB_TRADE_TYPE=Checkout
Step 5: Handle Webhook
The package automatically handles incoming webhooks. Configure your webhook URL:
TELEBIRR_WEBHOOK_URL=https://your-domain.com/api/telebirr/webhook
Test your webhook:
php artisan telebirr:setup-webhook --test
Multi-Merchant (Branch-Based)
// Payment for specific branch Telebirr::initiatePayment([ 'txn_ref' => 'TXN_123', 'amount' => 100.00, 'subject' => 'Branch Order' ], ['branch_id' => 1]);
Custom Context
// Organized by stores Telebirr::initiatePayment($data, ['store_id' => 5]); // Or even custom types Telebirr::initiatePayment($data, ['owner_type' => 'restaurant', 'owner_id' => 10]);
Payment Verification
$result = Telebirr::verifyPayment('TXN_123'); if ($result && $result['order_status'] === 'PAY_SUCCESS') { // Payment successful }
Auth Token Retrieval
$userInfo = Telebirr::getAuthToken($accessToken);
Error Handling
try { $paymentRequest = Telebirr::initiatePayment([ 'txn_ref' => 'TXN_' . time(), 'amount' => 150.00, 'subject' => 'Order Payment', ]); // Process successful payment initiation } catch (\Telebirr\LaravelTelebirr\Exceptions\TelebirrException $e) { // Handle payment initiation errors Log::error('Telebirr payment failed: ' . $e->getMessage()); // Show user-friendly error message return back()->withErrors(['payment' => 'Payment initiation failed. Please try again.']); }
Event Listeners
Listen to payment lifecycle events:
Event::listen(Telebirr\LaravelTelebirr\Events\PaymentInitiated::class, function ($event) { // Payment initiated }); Event::listen(Telebirr\LaravelTelebirr\Events\PaymentVerified::class, function ($event) { // Payment verified and successful // Update your order/invoice status here }); Event::listen(Telebirr\LaravelTelebirr\Events\WebhookReceived::class, function ($event) { // Raw webhook received });
Testing
Test your integration:
# Test API connectivity php artisan telebirr:test-connection # Setup and test webhooks php artisan telebirr:setup-webhook --test
Configuration
Single Merchant Mode
- Uses global ENV configuration
- No database required
- Perfect for simple applications
Multi-Merchant Mode
- Database-driven merchant management
- Configurable relationship mappings
- Enterprise-ready for complex applications
API Reference
Facade Methods
Telebirr::initiatePayment(array $data, array $context = []) Telebirr::verifyPayment(string $transactionId, array $context = []) Telebirr::queryOrder(string $orderId, array $context = []) Telebirr::getAuthToken(string $accessToken, array $context = []) Telebirr::handleWebhook(Request $request)
HTTP Endpoints
POST /api/telebirr/order- Create payment orderPOST /api/telebirr/verify- Verify payment statusPOST /api/telebirr/query- Query order detailsPOST /api/telebirr/auth- Get auth tokenPOST /api/telebirr/webhook- Webhook handler
Advanced Configuration
Publish config for full customization:
php artisan vendor:publish --tag=telebirr-config
Custom Merchant Resolver
// config/telebirr.php 'merchant' => [ 'resolver' => App\Services\CustomMerchantResolver::class, ],
Custom Webhook Handler
'webhook' => [ 'handler' => App\Services\CustomWebhookHandler::class, ],
Migration Guide
From Single to Multi-Merchant
- Change mode:
TELEBIRR_MODE=multi - Run:
php artisan telebirr:install --mode=multi --run-migrations - Add merchant records to
telebirr_merchantstable - Update code to pass merchant context where needed
Complete Integration Example
Here's a complete real-world integration example:
<?php namespace App\Http\Controllers; use App\Models\Order; use Illuminate\Http\Request; use Illuminate\Support\Facades\Log; use Telebirr\LaravelTelebirr\Facades\Telebirr; use Telebirr\LaravelTelebirr\Exceptions\TelebirrException; class PaymentController extends Controller { /** * Create payment order and initiate Telebirr payment */ public function checkout(Request $request) { $request->validate([ 'amount' => 'required|numeric|min:1|max:10000', 'description' => 'required|string|max:255', ]); // 1. Create order in your system first $order = Order::create([ 'user_id' => auth()->id(), 'amount' => $request->amount, 'currency' => 'ETB', 'description' => $request->description, 'status' => 'pending', 'reference' => 'ORD_' . time() . '_' . auth()->id(), ]); try { // 2. Initiate Telebirr payment $paymentRequest = Telebirr::initiatePayment([ 'txn_ref' => $order->reference, 'amount' => $order->amount, 'subject' => 'Order #' . $order->id, 'description' => $order->description, 'notify_url' => route('webhook.telebirr'), 'return_url' => route('payment.success', $order->id), 'timeout_express' => '30m', ]); // 3. Update order with payment request details $order->update([ 'payment_raw_request' => $paymentRequest, 'raw_request_parsed' => $this->parseRawRequest($paymentRequest), ]); Log::info('Telebirr payment initiated', [ 'order_id' => $order->id, 'amount' => $order->amount, 'payment_ref' => $order->reference ]); return response()->json([ 'success' => true, 'payment_raw_request' => $paymentRequest, 'order_id' => $order->id, 'reference' => $order->reference ]); } catch (TelebirrException $e) { // 4. Handle payment initiation failure $order->update(['status' => 'failed']); Log::error('Telebirr payment initiation failed', [ 'order_id' => $order->id, 'error' => $e->getMessage() ]); return response()->json([ 'success' => false, 'message' => 'Payment initiation failed. Please try again.', 'error' => $e->getMessage() ], 422); } } /** * Handle Telebirr webhooks */ public function webhook(Request $request) { try { $payload = $request->all(); // Verify webhook and process payment $result = Telebirr::handleWebhook($request); if ($result && isset($payload['merch_order_id'])) { // Update order status based on payment result $order = Order::where('reference', $payload['merch_order_id'])->first(); if ($order) { if ($payload['trade_status'] === 'Completed') { $order->update([ 'status' => 'paid', 'paid_at' => now(), 'payment_details' => $payload ]); Log::info('Order marked as paid', [ 'order_id' => $order->id, 'payment_ref' => $payload['merch_order_id'] ]); } elseif ($payload['trade_status'] === 'Failed') { $order->update([ 'status' => 'failed', 'payment_details' => $payload ]); Log::warning('Payment failed', [ 'order_id' => $order->id, 'payment_ref' => $payload['merch_order_id'] ]); } } } return response()->json(['code' => 0, 'message' => 'Success']); } catch (\Exception $e) { Log::error('Webhook processing failed', [ 'error' => $e->getMessage(), 'payload' => $request->all() ]); return response()->json(['code' => 1, 'message' => 'Processing failed'], 500); } } /** * Payment success page */ public function success(Order $order) { // Verify final payment status try { $result = Telebirr::verifyPayment($order->reference); if ($result && $result['order_status'] === 'PAY_SUCCESS') { $order->update([ 'status' => 'paid', 'verified_at' => now() ]); return view('payment.success', compact('order')); } else { return view('payment.pending', compact('order')); } } catch (TelebirrException $e) { Log::error('Payment verification failed', [ 'order_id' => $order->id, 'error' => $e->getMessage() ]); return view('payment.error', [ 'order' => $order, 'error' => 'Unable to verify payment status' ]); } } }
Troubleshooting
Common Issues
RSA Key Format Error
# Ensure your private key includes proper PEM headers
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC7VITN...
-----END PRIVATE KEY-----
Network Timeouts
# Increase timeout in config or .env TELEBIRR_API_TIMEOUT=30
Webhook Signature Verification Failures
# Test webhook locally first php artisan telebirr:setup-webhook --url=https://your-domain.com/api/telebirr/webhook --test # Check your public/private key pair php artisan telebirr:test-connection
Multi-Merchant Configuration Issues
# Ensure merchant records exist php artisan tinker >>> App\Models\TelebirrMerchant::count() >>> App\Models\TelebirrMerchant::first() # Test with merchant context Telebirr::initiatePayment($data, ['store_id' => 1])
Database Connection Issues
# Run migrations for multi-merchant mode
php artisan migrate
php artisan telebirr:install --run-migrations
Queue Configuration for Background Processing
# Ensure queue is configured for payment verification QUEUE_CONNECTION=database TELEBIRR_QUEUE_VERIFY_PAYMENT_ENABLED=true
Debug Mode
Enable detailed logging for troubleshooting:
LOG_LEVEL=debug TELEBIRR_LOGGING_ENABLED=true
Getting Help
- Check logs:
storage/logs/laravel.log - Review network requests in browser dev tools
- Test API credentials manually with Postman
- Verify webhook endpoint is publicly accessible
Security
- RSA PSS signature validation
- Webhook signature verification with timestamp tolerance
- SSL certificate validation (configurable)
- Comprehensive audit logging
- Configurable sensitive data masking
Performance
- Fabric token caching (55-minute TTL)
- Queue-based payment verification
- Retry logic with exponential backoff
- Database connection pooling aware
- Optimized queries with proper indexing
Requirements
- PHP 8.1+
- Laravel 9.0+
- phpseclib 3.0+
Contributing
Please see CONTRIBUTING for details.
License
This package is open-sourced software licensed under the MIT license.
Support
- 📖 Documentation: https://laravel-telebirr.com
- 🐛 Issues: GitHub Issues
- 💬 Discussions: GitHub Discussions
matt-di/laravel-telebirr 适用场景与选型建议
matt-di/laravel-telebirr 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 0 次下载、GitHub Stars 达 0, 最近一次更新时间为 2025 年 11 月 14 日, 在 PHP 生态内属于活跃度较高的组件。
我们在过去多个企业项目中使用过 matt-di/laravel-telebirr 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 matt-di/laravel-telebirr 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 18
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-11-14