unipay / unipay-bd
Unified Bangladesh Payment Gateway Package for Laravel (bKash, Nagad, Rocket, Upay, CellFin, SSLCommerz & Shurjopay)
Requires
- php: ^8.1
- ext-json: *
- ext-openssl: *
- guzzlehttp/guzzle: ^7.5
- illuminate/contracts: ^10.0 || ^11.0
- illuminate/support: ^10.0 || ^11.0
Requires (Dev)
- orchestra/testbench: ^8.0 || ^9.0
- phpunit/phpunit: ^10.0 || ^11.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-16 04:15:48 UTC
README
UniPay BD โ Unified Bangladesh Payment Gateway for Laravel
The ultimate unified Laravel payment gateway package for Bangladeshi Mobile Financial Services (MFS) & Payment Gateways.
๐ Table of Contents
- Overview
- Supported Payment Gateways
- Key Features
- Requirements
- Installation
- Configuration
- Quick Start & Usage
- Extending with Custom Drivers
- Exception & Error Handling
- Testing
- Security
- License
๐ Overview
UniPay BD (unipay/unipay-bd) provides a seamless, developer-friendly driver-based payment integration for Laravel applications operating in Bangladesh.
Inspired by Laravel's native driver pattern (FilesystemManager, CacheManager), UniPay allows developers to integrate bKash, Nagad, Rocket, Upay, CellFin, SSLCommerz, and Shurjopay using a single, normalized API syntax.
Instead of writing fragmented, gateway-specific API logic for each payment provider, UniPay BD normalizes all request payloads and response structures (PaymentResponse) across all Bangladeshi payment gateways.
๐ณ Supported Payment Gateways
UniPay BD natively supports 7 Bangladeshi payment providers:
| Gateway | Driver | MFS / Provider | Security & Protocol | Supported Operations |
|---|---|---|---|---|
| bKash | bkash |
bKash PGW | Tokenized REST API v1.2 with Bearer token caching | Create, Execute, Query, Refund |
| Nagad | nagad |
Nagad | RSA OpenSSL Public Key Encryption & Private Key Signing | Create, Complete, Verify, Refund |
| Rocket | rocket |
Dutch-Bangla Bank (DBBL) | Merchant API v1 with Terminal ID | Create, Verify, Refund |
| Upay | upay |
UCB Fintech | Bearer Token REST API | Create, Verify, Refund |
| CellFin | cellfin |
Islami Bank (IBBL) | Reference ID Checkout API | Create, Verify, Refund |
| SSLCommerz | sslcommerz |
SSL Wireless | GWProcess v4 API & Validation API | Create, Validate, Refund |
| Shurjopay | shurjopay |
ShurjoMukhi | Shurjopay API v2 Tokenized | Create, Verify, Refund |
โจ Key Features
- ๐ฏ Unified Manager Architecture: Easily switch payment drivers on the fly using
Payment::driver('bkash'),Payment::driver('nagad'), etc. - ๐ฆ Normalized DTO Responses: Unified
PaymentResponseobject guarantees identical property access (status,paymentId,transactionId,amount,redirectUrl,rawResponse). - ๐ Automated Callback & Webhook System: Built-in callback engine at
/unipay/callback/{gateway}handles payment redirects and webhooks automatically. - ๐ Native Laravel Events: Fires
PaymentSucceeded,PaymentFailed, andPaymentRefundedevents for decoupled application logic. - ๐ Enterprise RSA & Token Security: In-memory token caching for bKash and PKCS1 RSA encryption for Nagad merchant onboarding.
- ๐ Transaction Logging: Automatic logging of payment requests, status updates, and raw gateway JSON payloads to your database.
- ๐ ๏ธ Artisan Installation CLI: Publish configs and database migrations with
php artisan unipay:install.
โ๏ธ Requirements
- PHP:
^8.1 || ^8.2 || ^8.3 - Laravel:
^10.0 || ^11.0 - PHP Extensions:
ext-json,ext-openssl,ext-curl
๐ฆ Installation
Install the package via Composer:
composer require unipay/unipay-bd
Run the Artisan installer to publish the configuration file and database migrations:
php artisan unipay:install php artisan migrate
๐ง Configuration
Add your payment gateway credentials to your application's .env file:
# Default Driver & Logging UNIPAY_DEFAULT_DRIVER=bkash UNIPAY_LOGGING_ENABLED=true # bKash PGW Credentials BKASH_SANDBOX=true BKASH_APP_KEY=your_bkash_app_key BKASH_APP_SECRET=your_bkash_app_secret BKASH_USERNAME=your_bkash_username BKASH_PASSWORD=your_bkash_password # Nagad PGW Credentials NAGAD_SANDBOX=true NAGAD_MERCHANT_ID=68625001 NAGAD_MERCHANT_NUMBER=01700000000 NAGAD_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----" NAGAD_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----" # DBBL Rocket Credentials ROCKET_SANDBOX=true ROCKET_MERCHANT_ID=your_rocket_merchant_id ROCKET_TERMINAL_ID=your_rocket_terminal_id ROCKET_PASSWORD=your_rocket_password # Upay Credentials UPAY_SANDBOX=true UPAY_MERCHANT_ID=your_upay_merchant_id UPAY_MERCHANT_KEY=your_upay_merchant_key UPAY_MERCHANT_CODE=your_upay_merchant_code UPAY_PASSWORD=your_upay_password # IBBL CellFin Credentials CELLFIN_SANDBOX=true CELLFIN_MERCHANT_ID=your_cellfin_merchant_id CELLFIN_STORE_ID=your_cellfin_store_id CELLFIN_SECRET_KEY=your_cellfin_secret_key # SSLCommerz Credentials SSLCOMMERZ_SANDBOX=true SSLCOMMERZ_STORE_ID=your_sslcommerz_store_id SSLCOMMERZ_STORE_PASSWORD=your_sslcommerz_store_password # Shurjopay Credentials SHURJOPAY_SANDBOX=true SHURJOPAY_USERNAME=sp_sandbox SHURJOPAY_PASSWORD=pyRcsawValidated SHURJOPAY_PREFIX=NOK
๐ป Quick Start & Usage
1. Initiate Payment
To start a checkout process, build a PaymentRequest and call Payment::createPayment():
namespace App\Http\Controllers; use Illuminate\Http\Request; use Unipay\BD\Facades\Payment; use Unipay\BD\DTOs\PaymentRequest; class CheckoutController extends Controller { public function processCheckout(Request $request) { // Choose gateway driver dynamically ('bkash', 'nagad', 'rocket', 'upay', 'cellfin', 'sslcommerz', 'shurjopay') $gateway = $request->input('gateway', 'bkash'); $paymentRequest = new PaymentRequest( amount: 1250.00, invoiceId: 'INV-' . time(), customerMobile: '01700000000', callbackUrl: route('checkout.callback') ); $response = Payment::driver($gateway)->createPayment($paymentRequest); if ($response->isSuccessful() || $response->isPending()) { // Redirect customer to MFS / Gateway checkout page return redirect()->away($response->redirectUrl); } return back()->with('error', $response->message); } }
2. Handle Payment Callbacks & Webhooks
UniPay automatically registers a unified callback route at /unipay/callback/{gateway}.
When a customer completes payment, the MFS provider redirects back to this endpoint. UniPay automatically executes status verification and dispatches Laravel events.
3. Listen to Payment Events
Decouple your order processing logic by listening to UniPay events in App\Providers\EventServiceProvider.php:
use Unipay\BD\Events\PaymentSucceeded; use Unipay\BD\Events\PaymentFailed; use Unipay\BD\Events\PaymentRefunded; protected $listen = [ PaymentSucceeded::class => [ \App\Listeners\MarkOrderAsPaid::class, ], PaymentFailed::class => [ \App\Listeners\HandleFailedPayment::class, ], ];
Inside your event listener class:
namespace App\Listeners; use Unipay\BD\Events\PaymentSucceeded; use App\Models\Order; class MarkOrderAsPaid { public function handle(PaymentSucceeded $event) { $response = $event->response; // PaymentResponse DTO $order = Order::where('invoice_id', $response->invoiceId)->first(); if ($order) { $order->update([ 'status' => 'paid', 'transaction_id' => $response->transactionId, 'gateway' => $response->gatewayName, ]); } } }
4. Process Refunds
To issue a full or partial refund to a customer:
use Unipay\BD\Facades\Payment; use Unipay\BD\DTOs\RefundRequest; $refundRequest = new RefundRequest( paymentId: 'PAY_12345678', transactionId: 'TRX_98765432', amount: 500.00, reason: 'Customer return request' ); $response = Payment::driver('bkash')->refund($refundRequest); if ($response->isSuccessful()) { // Refund complete $refundTrxId = $response->refundTransactionId; }
5. Query Payment Status
Query any transaction status explicitly at any time:
use Unipay\BD\Facades\Payment; $response = Payment::driver('nagad')->queryPayment('NAGAD_REF_1001'); if ($response->isSuccessful()) { $trxId = $response->transactionId; $amount = $response->amount; }
๐ ๏ธ Extending with Custom Drivers
You can easily register custom gateway drivers using Payment::extend():
use Unipay\BD\Facades\Payment; Payment::extend('custom_mfs', function ($app) { return new CustomMfsGateway(config('unipay.gateways.custom_mfs')); });
โ ๏ธ Exception & Error Handling
UniPay provides a clean exception hierarchy:
Unipay\BD\Exceptions\UnipayException: Base exception class.Unipay\BD\Exceptions\InvalidGatewayException: Thrown when requesting an unsupported gateway.Unipay\BD\Exceptions\BkashApiException: Thrown when bKash API returns invalid credentials or auth errors.Unipay\BD\Exceptions\NagadEncryptionException: Thrown when OpenSSL RSA keys or signatures fail.Unipay\BD\Exceptions\PaymentVerificationFailedException: Thrown on failed payment checksums.
use Unipay\BD\Exceptions\UnipayException; try { $response = Payment::driver('bkash')->createPayment($paymentRequest); } catch (UnipayException $e) { logger()->error('UniPay Error: ' . $e->getMessage()); }
๐งช Testing
UniPay BD includes a full Pest & PHPUnit test suite with 100% mocked HTTP responses and OpenSSL key pair generation.
Run the test suite:
vendor/bin/phpunit
Expected output:
OK (24 tests, 73 assertions)
๐ Security
If you discover any security-related issues, please email atikhasan2090@gmail.com instead of using the public issue tracker.
๐ License
UniPay BD is open-sourced software licensed under the MIT License.
Crafted with โค๏ธ for the Bangladeshi Developer Community.