定制 matt-di/laravel-telebirr 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

matt-di/laravel-telebirr

最新稳定版本:v1.0.0

Composer 安装命令:

composer require matt-di/laravel-telebirr

包简介

Telebirr payment gateway integration for Laravel applications

README 文档

README

Latest Version on Packagist Total Downloads License

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...&timestamp=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

// Simple payment initiation
Telebirr::initiatePayment([
    'txn_ref' => 'TXN_123',
    'amount' => 100.00,
    'subject' => 'Product Purchase'
]);

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 order
  • POST /api/telebirr/verify - Verify payment status
  • POST /api/telebirr/query - Query order details
  • POST /api/telebirr/auth - Get auth token
  • POST /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

  1. Change mode: TELEBIRR_MODE=multi
  2. Run: php artisan telebirr:install --mode=multi --run-migrations
  3. Add merchant records to telebirr_merchants table
  4. 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

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 1
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-11-14