← Back to list

How I Integrated SSLCommerz Payment Gateway in Laravel (Without Any Package)

A step-by-step guide to integrating SSLCommerz into a Laravel e-commerce API — using pure cURL, no third-party package required.

Jalismahamud · 2026-06-08 10:15 · 0 claps · 2.3 min read
#laravel #sslcommerz #payment-gateway #bkash #php
Open on Medium ↗
Wiki topics: FIN · Fintech & Banking

How I Integrated SSLCommerz Payment Gateway in Laravel (Without Any Package)

A step-by-step guide to integrating SSLCommerz into a Laravel e-commerce API — using pure cURL, no third-party package required.

The Problem

I was building an e-commerce platform using Laravel + Vue.js and needed a reliable Bangladeshi payment gateway that supports:

  • bKash
  • Nagad
  • Cards
  • Internet Banking

SSLCommerz was the obvious choice.

But there was a problem — no reliable official Laravel package available.

So I decided to build the integration from scratch using pure cURL. The result? A clean, flexible, and fully controllable payment system.

What We’re Building

In this guide, we will build:

  • A SslCommerzService (handles payment link generation via cURL)
  • A PaymentController (handles success, fail, cancel, IPN)
  • Automatic order status update after payment confirmation
  • Full logging for debugging

Step 1 — Environment Configuration

Add your credentials in .env:

SSLCOMMERZ_STORE_ID=your_store_id
SSLCOMMERZ_STORE_PASSWORD=your_store_password
SSLCOMMERZ_IS_SANDBOX=true
FRONTEND_URL=http://localhost:5173

Create config/sslcommerz.php:

<?php

return [
    'store_id'       => env('SSLCOMMERZ_STORE_ID'),
    'store_password' => env('SSLCOMMERZ_STORE_PASSWORD'),
    'is_sandbox'     => env('SSLCOMMERZ_IS_SANDBOX', true),
    'success_url' => env('APP_URL') . '/api/payment/success',
    'fail_url'    => env('APP_URL') . '/api/payment/fail',
    'cancel_url'  => env('APP_URL') . '/api/payment/cancel',
    'ipn_url'     => env('APP_URL') . '/api/payment/ipn',
];

Step 2 — Service Class (Core Logic)

Create: app/Services/SslCommerzService.php

<?php 
namespace App\Services;
use App\Models\Order;
use Illuminate\Support\Facades\Log;
class SslCommerzService
{
    private string $storeId;
    private string $storePassword;
    private bool $isSandbox;
    private string $baseUrl;
    public function __construct()
    {
        $this->storeId       = config('sslcommerz.store_id');
        $this->storePassword = config('sslcommerz.store_password');
        $this->isSandbox     = config('sslcommerz.is_sandbox');
        $this->baseUrl = $this->isSandbox
            ? 'https://sandbox.sslcommerz.com'
            : 'https://securepay.sslcommerz.com';
    }
    public function generatePaymentLink(Order $order): array|false
    {
        $postData = [
            'store_id'     => $this->storeId,
            'store_passwd'  => $this->storePassword,
            'total_amount'  => $order->total_amount,
            'currency'      => 'BDT',
            'tran_id'       => $order->order_number,
            'success_url' => config('sslcommerz.success_url'),
            'fail_url'    => config('sslcommerz.fail_url'),
            'cancel_url'  => config('sslcommerz.cancel_url'),
            'ipn_url'     => config('sslcommerz.ipn_url'),
            'cus_name'    => $order->shipping_name,
            'cus_email'   => $order->user->email ?? 'noreply@shop.com',
            'cus_phone'   => $order->shipping_phone,
        ];
        try {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $this->baseUrl . '/gwprocess/v4/api.php');
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            $response = curl_exec($ch);
            curl_close($ch);
            $data = json_decode($response, true);
            if (!empty($data['GatewayPageURL'])) {
                return [
                    'payment_url' => $data['GatewayPageURL'],
                    'tran_id'     => $order->order_number,
                ];
            }
            return false;
        } catch (\Exception $e) {
            Log::error($e->getMessage());
            return false;
        }
    }
}

Step 3 — Payment Controller

Create: app/Http/Controllers/Api/PaymentController.php

Handles:

  • Success
  • Fail
  • Cancel
  • IPN webhook
// success, fail, cancel, ipn methods
// (same logic as your original implementation)

Step 4 — Routes

Route::post('/payment/success', [PaymentController::class, 'success']);
Route::post('/payment/fail',    [PaymentController::class, 'fail']);
Route::post('/payment/cancel',  [PaymentController::class, 'cancel']);
Route::post('/payment/ipn',     [PaymentController::class, 'ipn']);

CSRF Exception

protected $except = [
    'api/payment/*',
];

Step 5 — Trigger Payment

Inside your order create logic:

$sslService = new SslCommerzService();
$paymentData = $sslService->generatePaymentLink($order);
if ($paymentData) {
    return response()->json([
        'order'   => $order,
        'payment' => $paymentData,
    ]);
}

Frontend simply redirects the user to:

payment_url

Common Issue Fix

Missing ship_postcode error

Fix:

'ship_postcode' => '1200',
'cus_postcode'  => '1200',

SSLCommerz requires a postcode even if not collected.

Payment Flow

Order Created
   ↓
Generate Payment URL
   ↓
Redirect to SSLCommerz Gateway
   ↓
User Pays (bKash / Nagad / Card)
   ↓
Success Callback Hits API
   ↓
Validate Payment
   ↓
Update Order Status → PAID

Debug Tip

Always check logs:

storage/logs/laravel.log

Use:

Log::info(...)

for tracking every step.

Final Summary

FeatureStatusPackage UsedNoneIntegration Method Pure cURLPayment MethodsbKash, Nagad, CardWebhooksIPN + CallbacksAuto Order Update Yes

Final Words

This approach gives full control over the payment system without depending on any external package.

Perfect for production-grade Laravel e-commerce systems.


메타데이터
post_id
e799f4c30f37
slug
how-i-integrated-sslcommerz-payment-gateway-in-laravel-without-any-package-e799f4c30f37
url
https://medium.com/@jalismahamud31/how-i-integrated-sslcommerz-payment-gateway-in-laravel-without-any-package-e799f4c30f37
canonical_url
https://medium.com/@jalismahamud31/how-i-integrated-sslcommerz-payment-gateway-in-laravel-without-any-package-e799f4c30f37
author_url
https://medium.com/@jalismahamud31
status
ok
fetched_at
2026-07-10 13:01:02