LaravelPackages.net
Acme Inc.
Toggle sidebar
sslcommerz/laravel

Production-ready Laravel package for SSLCOMMERZ payment gateway integration (API v4)

34
0
v1.1.2
About sslcommerz/laravel

sslcommerz/laravel is a Laravel package for production-ready laravel package for sslcommerz payment gateway integration (api v4). It currently has 0 GitHub stars and 34 downloads on Packagist (latest version v1.1.2). Install it with composer require sslcommerz/laravel. Discover more Laravel packages by sslcommerz or browse all Laravel packages to compare alternatives.

Last updated

SSLCOMMERZ Laravel Package

Table of Contents


Installation

composer require sslcommerz/laravel

Publish Configuration

php artisan vendor:publish --tag=sslcommerz-config

Publish Routes (Optional)

php artisan vendor:publish --tag=sslcommerz-routes

Publish Everything

php artisan vendor:publish --tag=sslcommerz

Configuration

Add these variables to your .env file:

SSLCOMMERZ_SANDBOX=true SSLCOMMERZ_STORE_ID=your_store_id SSLCOMMERZ_STORE_PASSWORD=your_store_password # Your application URL (IMPORTANT: SSLCOMMERZ sends callbacks to this URL) APP_URL=https://yourdomain.com

Note: SSLCOMMERZ_SALT_KEY is required for recurring payments (Easycheckout).

Quick Start

use Sslcommerz\Laravel\Facades\SSLCOMMERZ;

public function checkout(Request $request)
{
    $response = SSLCOMMERZ::initiate([
        'tran_id'      => 'ORDER_' . uniqid(),
        'total_amount' => 1500.00,
        'cus_name'     => $request->name,
        'cus_email'    => $request->email,
        // ...
    ]);

    if ($response->isSuccessful()) {
        return $response->redirect(); // Fluent redirect to SSLCOMMERZ
    }

    return back()->with('error', $response->failedReason);
}

Sandbox Test Credentials

Register at https://developer.sslcommerz.com/registration/ to get your sandbox credentials.

Test Card Numbers:

| Card Type | Number | Expiry | CVV | |------------|-------------------|--------|-----| | VISA | 4111111111111111 | 12/36 | 111 | | Mastercard | 5111111111111111 | 12/36 | 111 | | Amex | 371111111111111 | 12/36 | 111 |

Mobile OTP: 111111 or 123456


Custom Controllers

You can easily override the default callback behavior.

  1. Publish the Controller Stub:

    php artisan vendor:publish --tag=sslcommerz-controller
    
  2. Update Configuration: In your config/sslcommerz.php, update the controller option to point to your new controller:

    'routes' => [
        'controller' => \App\Http\Controllers\SslcommerzCallbackController::class,
        // ...
    ],
    
  3. Customize Logic: Edit app/Http/Controllers/SslcommerzCallbackController.php to suit your needs.

Note: If you want to customize the URLs, you can also publish the routes: php artisan vendor:publish --tag=sslcommerz-routes

Payment Flow

┌──────────┐     ┌──────────────┐     ┌─────────────┐
  Customer│────▶│  Your Server │────▶│ SSLCOMMERZ  
  Browser        (Laravel)           API       
└──────────┘     └──────────────┘     └─────────────┘
                                            
       1. Checkout                          
     │─────────────────▶│                     
                         2. Create Session  
                       │────────────────────▶│
                         3. GatewayPageURL  
                       │◀────────────────────│
       4. Redirect                          
     │◀─────────────────│                     
                                            
       5. Pay on SSLCOMMERZ page             
     │───────────────────────────────────────▶│
                                            
                         6. IPN Notification│
                       │◀────────────────────│
                         7. Validate (API)  
                       │────────────────────▶│
                         8. VALID           
                       │◀────────────────────│
                                            
       9. Redirect to success_url            
     │◀───────────────────────────────────────│
                                            

Usage

Initiate Payment

use Sslcommerz\Laravel\Facades\SSLCOMMERZ;

$response = SSLCOMMERZ::initiate([
    'tran_id'          => 'ORDER_' . uniqid(),
    'total_amount'     => 1000.00,
    'cus_name'         => 'John Doe',
    'cus_email'        => '[email protected]',
    'cus_phone'        => '01711111111',
    // ...
]);

if ($response['status'] === 'SUCCESS') {
    return $response->redirect();
}

Specialized Parameters (API v4)

| Category | Parameters | |----------|------------| | Airline | pnr, hours_till_departure, flight_type, journey_from_to, third_party_booking | | Travel | hotel_name, length_of_stay, check_in_time, hotel_city | | Telecom | product_type, topup_number, country_topup | | Logistics| logistic_pickup_id, logistic_delivery_type |

Recurring Payments (Easycheckout)

SSLCOMMERZ supports recurring payments via a schedule parameter.

1. Configure SALT Key: Add SSLCOMMERZ_SALT_KEY to your .env file. This key is provided by the SSLCOMMERZ team.

2. Initiate Recurring Payment:

use Sslcommerz\Laravel\Facades\SSLCOMMERZ;

$schedule = json_encode([
    'refer'      => 'REF1234', // Plan ID from Merchant Panel
    'acct_no'    => 'CUS_001',  // Customer account reference
    'type'       => 'monthly',
    'dayofmonth' => '24',
]);

$encryptedSchedule = SSLCOMMERZ::getEncryptionService()->encrypt($schedule);

$response = SSLCOMMERZ::initiate([
    // ...
    'schedule'     => $encryptedSchedule,
]);

// If successful, a subscription_id will be returned in the callback/response
if ($response->isSuccessful()) {
    $subscriptionId = $response->subscriptionId;
}

3. Manage Subscriptions:

// Check status
$status = SSLCOMMERZ::getSubscriptionStatus($refer, $subscriptionId);

// Disable temporarily
SSLCOMMERZ::disableSubscription($refer, $subscriptionId);

// Re-enable
SSLCOMMERZ::enableSubscription($refer, $subscriptionId);

// Cancel permanently
SSLCOMMERZ::cancelSubscription($refer, $subscriptionId);

Validate Transaction

$validation = SSLCOMMERZ::validate($valId);

if ($validation->isSuccessful()) {
    // Payment confirmed - access via array or object
    echo "Amount: " . $validation['amount'];
    echo "Bank Transaction: " . $validation->bankTranId;
}

Refund

// Simply pass an array
$refund = SSLCOMMERZ::refund([
    'bank_tran_id'   => $bankTranId,
    'refund_amount'  => 500.00,
    'refund_remarks' => 'Customer requested refund',
]);

if ($refund->isSuccessful()) {
    echo "Refund Reference: " . $refund['refund_ref_id'];
}

Query Transaction

$result = SSLCOMMERZ::queryTransaction('ORDER_001');

if ($result->hasTransactions()) {
    $latest = $result->getLatestSuccessful();
    echo "Status: " . $latest['status'];
}

Logging

SSLCOMMERZ_LOG_ENABLED=true

By default, the package logs all gateway interactions using Laravel's default log configuration. You can disable logging by setting SSLCOMMERZ_LOG_ENABLED=false.


Callback Handling

The package registers these routes automatically:

| Route | Name | Purpose | |------------------|-----------------------|----------------------------| | POST /ssl/success | sslcommerz.success | Successful payment | | POST /ssl/fail | sslcommerz.fail | Failed payment | | POST /ssl/cancel | sslcommerz.cancel | Cancelled payment | | POST /ssl/ipn | sslcommerz.ipn | Instant Payment Notification |

All routes exclude CSRF verification since SSLCOMMERZ sends POST requests.

By default, the prefix is ssl. You can change it via sslcommerz.routes.prefix in config/sslcommerz.php, or publish routes to customize paths.

Redirect URLs After Payment

Define your own routes and views to show the payment result to the user:

// routes/web.php
Route::get('/payment/success', function () {
    return view('payment.success');
});

Events

Listen to these events in your EventServiceProvider:

use Sslcommerz\Laravel\Events\PaymentSucceeded;
use Sslcommerz\Laravel\Events\PaymentFailed;
use Sslcommerz\Laravel\Events\PaymentCancelled;
use Sslcommerz\Laravel\Events\IpnReceived;
use Sslcommerz\Laravel\Events\RefundInitiated;

protected $listen = [
    PaymentSucceeded::class => [
        UpdateOrderStatus::class,
        SendPaymentConfirmation::class,
    ],
    PaymentFailed::class => [
        HandleFailedPayment::class,
    ],
    IpnReceived::class => [
        ProcessIpnNotification::class,
    ],
];

Persistence (Handling Orders)

Since this package is database-agnostic, you should handle transaction persistence in your own application using listeners.

Example Listener:

namespace App\Listeners;

use Sslcommerz\Laravel\Events\PaymentSucceeded;
use App\Models\Order;

class UpdateOrderStatus
{
    public function handle(PaymentSucceeded $event): void
    {
        // Access callback data via $event->payment
        // Access API validation data via $event->validation
        
        $tranId = $event->payment->tranId;
        $orderId = $event->payment->valueA; // Your custom reference

        Order::where('id', $orderId)->update([
            'status'     => 'paid',
            'paid_at'    => now(),
            'payment_id' => $tranId,
        ]);
    }
}

Hash Verification

The package automatically verifies hash signatures on IPN callbacks. You can also verify manually:

$isValid = SSLCOMMERZ::verifyHash($request->all());

Or use the middleware on your own routes:

Route::middleware('sslcommerz.verify')
    ->post('/custom-callback', [CustomController::class, 'handle']);

Testing

Run Package Tests

composer install
./vendor/bin/phpunit

Mock in Your Application Tests

use Sslcommerz\Laravel\Facades\SSLCOMMERZ;
use Sslcommerz\Laravel\DTOs\PaymentResponseDTO;

SSLCOMMERZ::shouldReceive('initiate')
    ->once()
    ->andReturn(PaymentResponseDTO::fromApiResponse([
        'status'         => 'SUCCESS',
        'GatewayPageURL' => 'https://sandbox.sslcommerz.com/gw.php',
        'sessionkey'     => 'TEST_SESSION',
    ]));

API Reference

SSLCOMMERZ::initiate(PaymentRequestDTO|array $request): PaymentResponseDTO

Creates a payment session. If an array is passed, it is automatically converted to a DTO with sensible defaults.

SSLCOMMERZ::validate(string $valId): ValidationResponseDTO

Validates a transaction using the validation ID from callback/IPN.

SSLCOMMERZ::refund(RefundRequestDTO|array $request): RefundResponseDTO

Initiates a refund for a previously successful transaction.

SSLCOMMERZ::queryTransaction(string $tranId): TransactionQueryDTO

Queries all transactions associated with a merchant transaction ID.

SSLCOMMERZ::queryBySession(string $sessionKey): ValidationResponseDTO

Queries transaction status by SSLCOMMERZ session key.

SSLCOMMERZ::queryRefundStatus(string $refundRefId): RefundResponseDTO

Checks the current status of a refund request.

SSLCOMMERZ::verifyHash(array $data): bool

Verifies the MD5 hash signature of callback data.


Security

This package implements multiple layers of security:

  1. Hash Verification: All IPN callbacks are verified using SSLCOMMERZ's MD5 signature algorithm
  2. API Validation: Every successful payment is validated server-side via the Order Validation API
  3. CSRF Exemption: Only callback routes from SSLCOMMERZ are CSRF-exempt
  4. Logging: All gateway interactions are logged for audit trails
  5. Environment Isolation: Separate endpoints for sandbox and production

Best Practices

  • Always validate transactions via the API, never trust callback data alone
  • Monitor risk_level in validation responses (0 = Safe, 1 = Risky)
  • Use value_a through value_d to pass your own references
  • Set up IPN as the primary notification method (works even if user closes browser)
  • Register your production IP at SSLCOMMERZ for refund API access

Troubleshooting

| Issue | Solution | |-------|---------| | "Invalid Store ID" | Check SSLCOMMERZ_STORE_ID in .env | | CSRF token mismatch | Callback routes already exclude CSRF — check if you overrode routes | | IPN not received | Ensure your server is reachable from internet on port 80/443 | | Hash verification fails | Verify SSLCOMMERZ_STORE_PASSWORD matches your SSLCOMMERZ dashboard | | Connection timeout | Whitelist SSLCOMMERZ IPs: 103.26.139.87 (sandbox), 103.26.139.81 (live) |


License

MIT License. See LICENSE for details.

Comments