laravel maintained by sslcommerz
SSLCOMMERZ Laravel Package
Table of Contents
- Installation
- Configuration
- Quick Start
- Payment Flow
- Usage
- Callback Handling
- Events
- Hash Verification
- Custom Controllers
- Testing
- API Reference
- Security
- Troubleshooting
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_KEYis 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.
-
Publish the Controller Stub:
php artisan vendor:publish --tag=sslcommerz-controller -
Update Configuration: In your
config/sslcommerz.php, update thecontrolleroption to point to your new controller:'routes' => [ 'controller' => \App\Http\Controllers\SslcommerzCallbackController::class, // ... ], -
Customize Logic: Edit
app/Http/Controllers/SslcommerzCallbackController.phpto 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' => 'john@example.com',
'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:
- Hash Verification: All IPN callbacks are verified using SSLCOMMERZ's MD5 signature algorithm
- API Validation: Every successful payment is validated server-side via the Order Validation API
- CSRF Exemption: Only callback routes from SSLCOMMERZ are CSRF-exempt
- Logging: All gateway interactions are logged for audit trails
- Environment Isolation: Separate endpoints for sandbox and production
Best Practices
- Always validate transactions via the API, never trust callback data alone
- Monitor
risk_levelin validation responses (0 = Safe, 1 = Risky) - Use
value_athroughvalue_dto 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.