PHPackages                             rayhan-bapari/sslcommerz - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Payment Processing](/categories/payments)
4. /
5. rayhan-bapari/sslcommerz

ActiveLibrary[Payment Processing](/categories/payments)

rayhan-bapari/sslcommerz
========================

A production-ready Laravel package for SSLCommerz payment gateway — supports hosted &amp; checkout modes, IPN with hash verification, order validation, refunds, transaction queries. Laravel 9–12, PHP 8.1–8.5.

v1.0.0(1w ago)03MITPHPPHP ^8.1

Since Mar 10Pushed 1w agoCompare

[ Source](https://github.com/rayhan-bapari/sslcommerz)[ Packagist](https://packagist.org/packages/rayhan-bapari/sslcommerz)[ Docs](https://github.com/rayhan-bapari/sslcommerz)[ RSS](/packages/rayhan-bapari-sslcommerz/feed)WikiDiscussions main Synced today

READMEChangelog (1)Dependencies (8)Versions (4)Used By (0)

SSLCommerz Payment for Laravel
==============================

[](#sslcommerz-payment-for-laravel)

[![Packagist Version](https://camo.githubusercontent.com/69c39ce98326d3412adf9d5f4cfc9d5d326b66ab2720e3332250329f22a91eb1/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f72617968616e2d6261706172692f73736c636f6d6d65727a2e737667)](https://packagist.org/packages/rayhan-bapari/sslcommerz)[![PHP Version](https://camo.githubusercontent.com/d4f43df4fd4f9579c57917e84ecebf579c1ce460880b791696ae8f5f7d739ca5/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e31253230254532253830253933253230382e352d626c75652e737667)](https://php.net)[![Laravel](https://camo.githubusercontent.com/15bab99ebfaae48be42fab2f19f544ec2d4269c25ab1d819303be66cac1f734f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d3925323025453225383025393325323031322d7265642e737667)](https://laravel.com)[![License: MIT](https://camo.githubusercontent.com/fdf2982b9f5d7489dcf44570e714e3a15fce6253e0cc6b5aa61a075aac2ff71b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d79656c6c6f772e737667)](LICENSE)

A production-ready Laravel package for **SSLCommerz** payment gateway — the most popular payment aggregator in Bangladesh.

**Features:**

- ✅ Hosted &amp; Checkout (popup/embed) payment modes
- ✅ IPN (Instant Payment Notification) handler with MD5 hash verification
- ✅ Order validation via SSLCommerz server-to-server API
- ✅ Transaction query by `tran_id` and `sessionkey`
- ✅ Refund initiation &amp; refund status
- ✅ Strongly typed `PaymentData` DTO covering all API fields
- ✅ `PaymentResponse` object with clean API
- ✅ Full IPN payload logging to database
- ✅ Laravel Facade &amp; dependency injection
- ✅ Laravel 9 / 10 / 11 / 12 · PHP 8.1 / 8.2 / 8.3 / 8.4 / 8.5

---

Requirements
------------

[](#requirements)

DependencyVersionPHP^8.1Laravel^9.0 | ^10.0 | ^11.0 | ^12.0ext-curl\*ext-json\*---

Installation
------------

[](#installation)

```
composer require rayhan-bapari/sslcommerz
```

### Publish config &amp; migrations

[](#publish-config--migrations)

```
php artisan vendor:publish --tag=sslcommerz-config
php artisan vendor:publish --tag=sslcommerz-migrations
php artisan migrate
```

---

Configuration
-------------

[](#configuration)

Add the following to your `.env`:

```
# --- Environment ---
SSLCZ_SANDBOX=true              # true = sandbox, false = live

# --- Store Credentials ---
# Sandbox registration: https://developer.sslcommerz.com/registration/
SSLCZ_STORE_ID=your_store_id
SSLCZ_STORE_PASSWORD=your_store_password

# --- Default Currency ---
SSLCZ_CURRENCY=BDT

# --- Callback URLs (can be overridden per-payment) ---
SSLCZ_SUCCESS_URL=https://yourdomain.com/sslcommerz/success
SSLCZ_FAIL_URL=https://yourdomain.com/sslcommerz/fail
SSLCZ_CANCEL_URL=https://yourdomain.com/sslcommerz/cancel
SSLCZ_IPN_URL=https://yourdomain.com/sslcommerz/ipn

# --- Payment display mode ---
SSLCZ_DISPLAY_TYPE=hosted       # 'hosted' (redirect) or 'checkout' (popup)

# --- IPN ---
SSLCZ_IPN_ENABLED=true
SSLCZ_IPN_PATH=sslcommerz/ipn
SSLCZ_IPN_LOG=true
```

### CSRF Exclusion

[](#csrf-exclusion)

SSLCommerz POSTs to your callback and IPN URLs. Exclude them from CSRF verification:

```
// app/Http/Middleware/VerifyCsrfToken.php
protected $except = [
    'sslcommerz/success',
    'sslcommerz/fail',
    'sslcommerz/cancel',
    'sslcommerz/ipn',
];
```

> **Session issue?** If your session is destroyed after SSLCommerz redirects back, add `'same_site' => 'none'` in `config/session.php`.

---

Usage
-----

[](#usage)

### Via Facade

[](#via-facade)

```
use RayhanBapari\SslcommerzPayment\Facades\Sslcommerz;
use RayhanBapari\SslcommerzPayment\DTOs\PaymentData;
```

### Via Dependency Injection

[](#via-dependency-injection)

```
use RayhanBapari\SslcommerzPayment\Contracts\SslcommerzPaymentInterface;

public function __construct(protected SslcommerzPaymentInterface $sslcz) {}
```

---

### 1. Initiate Payment

[](#1-initiate-payment)

```
use RayhanBapari\SslcommerzPayment\DTOs\PaymentData;
use RayhanBapari\SslcommerzPayment\Facades\Sslcommerz;

public function initiatePayment(Request $request)
{
    $dto               = new PaymentData();
    $dto->tran_id      = 'INV-' . uniqid();
    $dto->total_amount = 500.00;
    $dto->currency     = 'BDT';

    // Customer
    $dto->cus_name     = $request->user()->name;
    $dto->cus_email    = $request->user()->email;
    $dto->cus_phone    = $request->user()->phone;
    $dto->cus_add1     = '123 Dhanmondi';
    $dto->cus_city     = 'Dhaka';
    $dto->cus_country  = 'Bangladesh';
    $dto->cus_postcode = '1209';

    // Product
    $dto->product_name     = 'Premium Subscription';
    $dto->product_category = 'subscription';
    $dto->product_profile  = 'non-physical-goods';

    // Shipping (set to NO if digital)
    $dto->shipping_method = 'NO';

    // Pass-through — get them back in success/fail/cancel/ipn callbacks
    $dto->value_a = (string) $request->user()->id;
    $dto->value_b = 'order-reference';

    $response = Sslcommerz::initiatePayment($dto);

    if ($response->success()) {
        return redirect($response->gatewayPageURL());
    }

    return back()->with('error', 'Could not initiate payment: ' . $response->error());
}
```

---

### 2. Handle Callbacks

[](#2-handle-callbacks)

Define routes for SSLCommerz to POST back to:

```
// routes/web.php
Route::post('sslcommerz/success', [PaymentController::class, 'success'])->name('sslcommerz.success');
Route::post('sslcommerz/fail',    [PaymentController::class, 'fail'])->name('sslcommerz.fail');
Route::post('sslcommerz/cancel',  [PaymentController::class, 'cancel'])->name('sslcommerz.cancel');
```

```
// PaymentController.php

public function success(Request $request)
{
    // Step 1: Verify hash
    if (!Sslcommerz::verifyIpnHash($request->post())) {
        abort(403, 'Invalid signature.');
    }

    // Step 2: Server-side validation
    $validation = Sslcommerz::orderValidate($request->val_id);

    if (!in_array($validation['status'] ?? '', ['VALID', 'VALIDATED'])) {
        return redirect()->route('checkout')->with('error', 'Payment validation failed.');
    }

    // Step 3: Confirm the amount matches your order
    $paidAmount = (float) $validation['amount'];
    // ... compare with your stored order amount

    // Step 4: Fulfill order using $request->value_a (your user ID), tran_id, bank_tran_id
    $bankTranId = $request->bank_tran_id; // Save this — needed for refunds

    return redirect()->route('dashboard')->with('success', 'Payment successful!');
}

public function fail(Request $request)
{
    return redirect()->route('checkout')->with('error', 'Payment failed. Please try again.');
}

public function cancel(Request $request)
{
    return redirect()->route('checkout')->with('info', 'Payment cancelled.');
}
```

---

### 3. IPN Handler

[](#3-ipn-handler)

The package auto-registers `POST /sslcommerz/ipn`. Subscribe to the event:

```
// app/Providers/EventServiceProvider.php
protected $listen = [
    'sslcommerz.ipn' => [
        App\Listeners\HandleSslcommerzIpn::class,
    ],
];
```

```
// app/Listeners/HandleSslcommerzIpn.php
namespace App\Listeners;

class HandleSslcommerzIpn
{
    public function handle(array $payload): void
    {
        if (!$payload['verified']) {
            return; // Hash check passed but server validation failed
        }

        $tranId     = $payload['tran_id'];
        $status     = $payload['status'];      // VALID | VALIDATED
        $bankTranId = $payload['bank_tran_id']; // Save for refunds
        $amount     = $payload['amount'];
        $userId     = $payload['value_a'];      // Your pass-through field

        // Update your order in the database here
    }
}
```

> **Note:** IPN does not work on localhost. Use a public URL (e.g. ngrok for local dev). Also configure the IPN URL in your SSLCommerz merchant panel.

---

### 4. Transaction Query

[](#4-transaction-query)

```
// By your tran_id
$result = Sslcommerz::transactionQueryById('INV-12345');

// By SSLCommerz sessionkey
$result = Sslcommerz::transactionQueryBySessionId('session_abc123');
```

---

### 5. Refund

[](#5-refund)

```
// You need the bank_tran_id from the original transaction
$result = Sslcommerz::initiateRefund(
    bankTranId:    '1709162345070ANJdZV8LyI4cMw',
    refundAmount:  50.00,
    refundRemarks: 'Customer request',
    refe_id:       'REF-TRACK-001'   // optional tracking reference
);

// $result['status'] → 'success' | 'failed' | 'processing'
// $result['refund_ref_id'] → save this for status checking

// Check refund status
$status = Sslcommerz::refundStatus($result['refund_ref_id']);
// $status['status'] → 'refunded' | 'processing' | 'cancelled'
```

> **Note:** Your public server IP must be registered with SSLCommerz for live refunds.

---

### 6. Popup / Checkout Mode

[](#6-popup--checkout-mode)

For embedded checkout, set `SSLCZ_DISPLAY_TYPE=checkout` and add the SSLCommerz embed script to your blade template:

```
Pay Now

  var obj = {};
  obj.cus_name = '{{ auth()->user()->name }}';
  obj.cus_email = '{{ auth()->user()->email }}';
  obj.amount = '500';
  $('#sslczPayBtn').prop('postdata', obj);

{{-- Sandbox --}}

  (function (w, d) {
    var s = d.createElement('script');
    s.src =
      'https://sandbox.sslcommerz.com/embed.min.js?' + Math.random().toString(36).substring(7);
    d.getElementsByTagName('script')[0].parentNode.insertBefore(
      s,
      d.getElementsByTagName('script')[0]
    );
  })(window, document);

```

For live, replace the sandbox embed URL with:

```
https://seamless-epay.sslcommerz.com/embed.min.js

```

---

Database Tables
---------------

[](#database-tables)

TablePurpose`sslcz_ipn_logs`Raw + parsed IPN POST payloads---

Error Handling
--------------

[](#error-handling)

```
use RayhanBapari\SslcommerzPayment\Exceptions\SslcommerzException;
use RayhanBapari\SslcommerzPayment\Exceptions\SslcommerzIpnException;

try {
    $response = Sslcommerz::initiatePayment($dto);
} catch (SslcommerzException $e) {
    // Configuration or API communication error
    Log::error('SSLCommerz error: ' . $e->getMessage());
}
```

---

Sandbox Testing
---------------

[](#sandbox-testing)

Get free sandbox credentials:

Set `SSLCZ_SANDBOX=true` and use your sandbox `store_id` and `store_password`.

---

Transaction Status Values
-------------------------

[](#transaction-status-values)

StatusMeaning`VALID`Transaction is valid — fulfill immediately`VALIDATED`Already validated once — still safe`INVALID_TRANSACTION`Something is wrong`FAILED`Payment failed at gateway`CANCELLED`Customer cancelled`UNATTEMPTED`Customer did not attempt`EXPIRED`Session expired---

License
-------

[](#license)

MIT © [Rayhan Bapari](https://github.com/rayhan-bapari)

sslcommerz
==========

[](#sslcommerz)

sslcommerz
==========

[](#sslcommerz-1)

###  Health Score

40

—

FairBetter than 88% of packages

Maintenance98

Actively maintained with recent releases

Popularity4

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity44

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

3

Last Release

12d ago

Major Versions

v0.1.1 → v1.0.02026-03-10

### Community

Maintainers

![](https://www.gravatar.com/avatar/f1a5b24027253182cc0f66e25d011909ef38311b7d39eef84c58a74150c89a5c?d=identicon)[rayhan-bapari](/maintainers/rayhan-bapari)

---

Top Contributors

[![rayhan-bapari](https://avatars.githubusercontent.com/u/126815340?v=4)](https://github.com/rayhan-bapari "rayhan-bapari (3 commits)")

---

Tags

laravelpaymentgatewayecommercecheckoutipnhostedbangladeshsslcommerzssl-commerz

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/rayhan-bapari-sslcommerz/health.svg)

```
[![Health](https://phpackages.com/badges/rayhan-bapari-sslcommerz/health.svg)](https://phpackages.com/packages/rayhan-bapari-sslcommerz)
```

###  Alternatives

[sebdesign/laravel-viva-payments

A Laravel package for integrating the Viva Payments gateway

4843.9k](/packages/sebdesign-laravel-viva-payments)[dena-a/iran-payment

a Laravel package to handle Internet Payment Gateways for Iran Banking System

322.4k](/packages/dena-a-iran-payment)[parsisolution/gateway

A Laravel package for connecting to all Iraninan payment gateways

231.7k](/packages/parsisolution-gateway)[sostheblack/moip

Laravel Package for Moip.

171.9k](/packages/sostheblack-moip)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
