PHPackages                             rmdmostakim/bdpayment - 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. rmdmostakim/bdpayment

ActiveLibrary[Payment Processing](/categories/payments)

rmdmostakim/bdpayment
=====================

A Laravel payment integration package supporting bKash, Nagad, Rocket, and other Bangladeshi gateways with unified APIs.

v1.0.0(8mo ago)022MITPHPPHP ^8.2

Since Sep 6Pushed 8mo agoCompare

[ Source](https://github.com/Rmdmostakim/bdpayment)[ Packagist](https://packagist.org/packages/rmdmostakim/bdpayment)[ RSS](/packages/rmdmostakim-bdpayment/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (2)Versions (3)Used By (0)

💳 **BDPayment Laravel Package**
===============================

[](#-bdpayment-laravel-package)

A modern Laravel package for integrating Bangladesh payment gateways — **Bkash**, **Nagad**, and **SSLCommerz** — with unified API endpoints, robust logging, and seamless frontend callback support. Developed and maintained by [Rmdmostakim](https://github.com/Rmdmostakim).

---

✨ Features
----------

[](#-features)

- 🔗 **Bkash, Nagad, and SSLCommerz** payment gateway integration
- 🛠️ Unified API for payment creation, execution, verification, and callback
- ⚙️ Configurable via `.env` and `config/bdpayment.php`
- 🔄 Frontend callback URL support
- 📝 Extensive logging and error handling

---

🚀 Installation
--------------

[](#-installation)

```
composer require rmdmostakim/bdpayment
```

---

⚙️ Configuration
----------------

[](#️-configuration)

**Publish the config file:**

```
php artisan vendor:publish --provider="RmdMostakim\BdPayment\PaymentServiceProvider"
```

**Run migration:**

```
php artisan migrate
```

**Set the following variables in your `.env`:**

```
APP_URL=http://localhost
FRONTEND_PAYMENT_SUCCESS_URL=http://localhost:3000/payment

BKASH_GATEWAY_MODE=sandbox
BKASH_BASE_URL="https://tokenized.sandbox.bka.sh/v1.2.0-beta"
BKASH_USERNAME="sandboxTokenizedUser02"
BKASH_PASSWORD="sandboxTokenizedUser02@12345"
BKASH_APP_KEY="your_app_key"
BKASH_APP_SECRET="your_app_secret"
BKASH_CALLBACK_URL="${APP_URL}/api/gateway/bkash/callback"

NAGAD_PAYMENT_MODE=sandbox
NAGAD_BASE_URL="http://sandbox.mynagad.com:10080"
NAGAD_MERCHANT_ID="your_merchant_id"
NAGAD_PUBLIC_KEY="keys/nagad_public_key.pem"
NAGAD_PRIVATE_KEY="keys/nagad_private_key.pem"
NAGAD_CALLBACK_URL="${APP_URL}/api/gateway/nagad/callback"

SSLCOMMERZ_MODE=sandbox
SSLCOMMERZ_BASE_URL="https://sandbox.sslcommerz.com"
SSLCOMMERZ_STORE_ID="your_store_id"
SSLCOMMERZ_STORE_PASSWORD="your_store_password"
SSLCOMMERZ_CALLBACK_URL="${APP_URL}/api/gateway/sslcommerz/callback"
```

*Edit `config/bdpayment.php` as needed. Default callback URLs use your `APP_URL`.*

---

🧑‍💻 Usage
---------

[](#‍-usage)

### 🔌 API Endpoints

[](#-api-endpoints)

#### 🏦 **Bkash**

[](#-bkash)

- **Create Payment:**
    `POST /api/gateway/bkash/create`
- **Execute Payment:**
    `POST /api/gateway/bkash/execute`
- **Callback:**
    `GET /api/gateway/bkash/callback?paymentID=...`
- **Payload Example**

```
{
  "amount": 100,
  "invoice": "INV123", // optional
  "user_id": 1,        // optional
  "product_id": 5      // optional
}
```

---

#### 📱 **Nagad**

[](#-nagad)

- **Create Payment:**
    `POST /api/gateway/nagad/create`
- **Callback:**
    `GET /api/gateway/nagad/callback?payment_ref_id=...&order_id=...`
- **Payload Example**

```
{
  "amount": 100,
  "invoice": "INV123", // optional
  "user_id": 1,        // optional
  "product_id": 5      // optional
}
```

---

#### 🏦 **SSLCommerz**

[](#-sslcommerz)

- **Create Payment:**
    `POST /api/gateway/sslcommerz/create`
- **Callback:**
    `GET /api/gateway/sslcommerz/callback?val_id=...&tran_id=...`
- **Payload Example**

```
{
  "amount": 100,
  "invoice": "INV123", // optional
  "user_id": 1,        // optional
  "product_id": 5,     // optional
  "customer_name": "John Doe", // custom fields supported
  "order_note": "Special instructions" // custom fields supported
}
```

Or send as `cart_json`:

```
{
  "cart_json": "{\"amount\":100,\"invoice\":\"INV123\",\"user_id\":1,\"product_id\":5}"
}
```

---

#### 📄 **Get All Invoices**

[](#-get-all-invoices)

- **Get All Payments:**
    `GET /api/gateway/payments`
- **Query Parameters (optional):**
    `status`, `mode`, `user_id`, `min_amount`, `max_amount`, `from`, `to`, `sortBy`, `sortDir`, `perPage`
- **Example Request &amp; Response**

*Request:*

```
GET /api/gateway/payments?user_id=1&status=completed&perPage=20

```

*Response:*

```
{
  "success": true,
  "data": [
    {
      "id": 1,
      "invoice": "INV123",
      "amount": 100,
      "status": "completed"
      // ...other fields
    }
  ],
  "meta": {
    "current_page": 1,
    "last_page": 1,
    "per_page": 20,
    "total": 2
  }
}
```

---

#### 🔎 **Find By Invoice**

[](#-find-by-invoice)

- **Find Payment by Invoice:**
    `GET /api/gateway/payments/{invoice}`
- **Example Response**

*Success:*

```
{
  "success": true,
  "data": {
    "id": 1,
    "invoice": "INV123",
    "amount": 100,
    "status": "completed"
    // ...other fields
  }
}
```

*Not found:*

```
{
  "success": false,
  "message": "Payment not found",
  "data": null
}
```

---

📝 Logging
---------

[](#-logging)

All requests, responses, and errors are logged using Laravel's logging system for easy debugging and traceability.

---

🔄 Frontend Callback
-------------------

[](#-frontend-callback)

After payment, users are redirected to the configured frontend callback URL with query parameters:

- `invoice` (invoice)
- `status` (`success` or `failed`)
- `message` (status message)

---

🏷️ Using Facades
----------------

[](#️-using-facades)

You can use the `PaymentManager` facade for direct access to gateway methods in your code:

```
use RmdMostakim\BdPayment\Facades\PaymentManager;

// Create a Bkash payment
$response = PaymentManager::bkash()->createPayment([
    'amount' => 100,
    'invoice' => 'INV123',
    'user_id' => 1,
    'product_id' => 5
]);

// Execute a Bkash payment
$executeResponse = PaymentManager::bkash()->executePayment('bkash_payment_id');

// Verify a Bkash payment
$verifyResponse = PaymentManager::bkash()->verifyPayment('bkash_payment_id');

// Create a Nagad payment
$init = PaymentManager::nagad()->initializePayment('INV123');
$payload = [
    'user_id' => 1,
    'invoice' => 'INV123',
    'amount' => 100,
    'product_id' => 5,
    'transaction_id' => $init['paymentReferenceId'],
    'challenge' => $init['challenge']
];
$nagadResponse = PaymentManager::nagad()->executePayment($payload);

// Verify a Nagad payment
$verifyNagad = PaymentManager::nagad()->verifyPayment($init['paymentReferenceId']);

// Create an SSLCommerz payment
$sslcommerzResponse = PaymentManager::sslcommerz()->createPayment([
    'amount' => 100,
    'invoice' => 'INV123',
    'user_id' => 1,
    'product_id' => 5,
    'customer_name' => 'John Doe', // custom field
    'order_note' => 'Special instructions' // custom field
]);

// Verify an SSLCommerz payment
$verifySslcommerz = PaymentManager::sslcommerz()->verifyPayment('tran_id');

// Get all payments (invoices)
$allPayments = PaymentManager::all([
    'user_id' => 1,
    'status' => 'completed',
    'perPage' => 20
]);

// Find a payment by invoice
$payment = PaymentManager::findByInvoice('INV123');
```

---

🧩 **Bkash: Laravel Web Example**
--------------------------------

[](#-bkash-laravel-web-example)

```

    Awesome Product

        This is a description of the awesome product that you will love!

    $49.99

        @csrf

            Buy Now

```

[![Product Card](https://raw.githubusercontent.com/Rmdmostakim/screens/main/bdpayment-1.png)](https://raw.githubusercontent.com/Rmdmostakim/screens/main/bdpayment-1.png)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

[](#)

[![Payment Page](https://raw.githubusercontent.com/Rmdmostakim/screens/main/bdpayment-2.png)](https://raw.githubusercontent.com/Rmdmostakim/screens/main/bdpayment-2.png)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

[](#-1)

[![Payment Success](https://raw.githubusercontent.com/Rmdmostakim/screens/main/bdpayment-3.png)](https://raw.githubusercontent.com/Rmdmostakim/screens/main/bdpayment-3.png)
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

[](#-2)

[![Payment Failed](https://raw.githubusercontent.com/Rmdmostakim/screens/main/bdpayment-4.png)](https://raw.githubusercontent.com/Rmdmostakim/screens/main/bdpayment-4.png)
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------

[](#-3)

---

🧪 **Bkash: API with Sanctum/Passport**
--------------------------------------

[](#-bkash-api-with-sanctumpassport)

> Ensure Bearer token is sent in the `Authorization` header.

```
DOCTYPE html>

    Product Card

        Awesome Product
        This is a description of the awesome product that you will love!
        ৳ 49.9

            Buy Now

            &times;

        $(document).ready(function () {
            const bkashMode = 'sandbox'; // or 'production' based on your config
            const baseUrl = "http://payment-gateway.test"; // Replace with your gateway base URL
            const token = "1|REIxipB582kMpqcQSy8J5iJaMeBoCF0g79NJcH1U6474785d"; // Replace with real token
            const payAmount = document.getElementById('amount').innerText;

            let paymentID = null;
            let tranId = "";

            // Axios global headers
            axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
            axios.defaults.headers.common['Content-Type'] = 'application/json';

            const messageContainer = $('#message-container');
            const messageText = $('#message-text');
            let messageTimeout = null;

            function showMessage(message, type = 'error') {
                const typeClasses = {
                    error: 'bg-red-500',
                    success: 'bg-green-500',
                    info: 'bg-blue-500',
                };

                const bgClass = typeClasses[type] || 'bg-gray-600';

                if (messageTimeout) clearTimeout(messageTimeout);

                messageContainer
                    .removeClass('hidden bg-red-500 bg-green-500 bg-blue-500 bg-gray-600')
                    .addClass(bgClass)
                    .fadeIn();

                messageText.html(message);

                messageTimeout = setTimeout(() => redirectToHome(), 5000);
            }

            function clearMessage() {
                if (messageTimeout) clearTimeout(messageTimeout);
                messageTimeout = null;

                messageContainer.fadeOut(200, () => {
                    messageText.text('');
                    messageContainer
                        .removeClass('bg-red-500 bg-green-500 bg-blue-500 bg-gray-600')
                        .addClass('hidden');
                });
            }

            function redirectToHome() {
                window.location.href = "/";
            }

            $('#close-message').on('click', function () {
                clearMessage();
                redirectToHome();
            });

            function handleAxiosError(error, context = "Request") {
                const status = error.response?.status;
                const response = error.response?.data;
                let msg = "";

                if (status === 403) {
                    msg = `${context} failed: Unauthorized. Home`;
                } else if (status === 422) {
                    msg = response?.errors
                        ? response.errors[Object.keys(response.errors)[0]][0]
                        : response?.message || "Unprocessable request.";
                } else if (status === 500) {
                    msg = `${context} failed: Internal Server Error.`;
                } else {
                    msg = `${context} failed: Unexpected error (status ${status}).`;
                }

                showMessage(msg, 'error');
                console.error(`${context} error [${status}]:`, error);
            }

            bKash.init({
                paymentMode: 'checkout',
                paymentRequest: {
                    amount: payAmount,
                    intent: 'sale',
                    currency: 'BDT'
                },
                createRequest: function (request) {
                    clearMessage();

                    axios.post(`${baseUrl}/api/gateway/bkash/create`, {
                        amount: payAmount
                    })
                        .then(response => {
                            const data = response.data;

                            if (data.paymentID) {
                                paymentID = data.paymentID;
                                tranId = data.tran_id;
                                const bkashURL = data.bkashURL || data.paymentURL;

                                if (bkashMode === 'sandbox') {
                                    window.location.href = bkashURL;
                                } else {
                                    bKash.create().onSuccess(data);
                                }
                            } else {
                                showMessage('Failed to initiate payment.', 'error');
                                bKash.create().onError();
                            }
                        })
                        .catch(error => {
                            handleAxiosError(error, "Create Payment");
                            bKash.create().onError();
                        });
                },
                executeRequestOnAuthorization: function () {
                    clearMessage();

                    axios.post(`${baseUrl}/api/gateway/bkash/execute`, {
                        transaction_id: tranId
                    })
                        .then(response => {
                            const data = response.data;

                            if (data.paymentID && data.transactionStatus === 'Completed') {
                                showMessage("✅ Payment successful!", "success");
                            } else {
                                showMessage("Payment failed or not completed.", "error");
                            }
                        })
                        .catch(error => {
                            handleAxiosError(error, "Execute Payment");
                        });
                },
                onClose: function () {
                    redirectToHome();
                }
            });

            $('#payBtn').on('click', function () {
                $('#bKash_button').trigger('click');
            });
        });

```

---

⚛️ **Bkash: ReactJS Frontend Integration**
------------------------------------------

[](#️-bkash-reactjs-frontend-integration)

1. Use the `/api/gateway/bkash/create` endpoint to get `bkashURL`.
2. Redirect to that URL using `window.location.href`.

```
import React, { useEffect } from 'react';
import axios from 'axios';

const BkashCheckout = ({
  amount = 499,
  baseUrl = 'http://payment-gateway.test',
  token = '',
  mode = 'sandbox',
}) => {
  useEffect(() => {
    const script = document.createElement('script');
    script.src =
      mode === 'sandbox'
        ? 'https://scripts.sandbox.bka.sh/versions/1.2.0-beta/checkout/bKash-checkout-sandbox.js'
        : 'https://scripts.pay.bka.sh/versions/1.2.0-beta/checkout/bKash-checkout.js';
    script.async = true;
    script.onload = () => initializeBkash();
    document.body.appendChild(script);
  }, []);

  const initializeBkash = () => {
    let paymentID = null;
    let tranId = '';

    axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
    axios.defaults.headers.common['Content-Type'] = 'application/json';

    window.bKash.init({
      paymentMode: 'checkout',
      paymentRequest: {
        amount: amount.toString(),
        intent: 'sale',
        currency: 'BDT',
      },
      createRequest: (request) => {
        axios
          .post(`${baseUrl}/api/gateway/bkash/create`, { amount })
          .then((res) => {
            const data = res.data;
            if (data.paymentID) {
              paymentID = data.paymentID;
              tranId = data.tran_id;
              const bkashURL = data.bkashURL || data.paymentURL;
              if (mode === 'sandbox') {
                window.location.href = bkashURL;
              } else {
                window.bKash.create().onSuccess(data);
              }
            } else {
              alert('Failed to initiate payment.');
              window.bKash.create().onError();
            }
          })
          .catch((err) => {
            console.error('Create Payment Error:', err);
            window.bKash.create().onError();
          });
      },
      executeRequestOnAuthorization: () => {
        axios
          .post(`${baseUrl}/api/gateway/bkash/execute`, { transaction_id: tranId })
          .then((res) => {
            const data = res.data;
            if (data.paymentID && data.transactionStatus === 'Completed') {
              alert('✅ Payment successful!');
            } else {
              alert('❌ Payment failed or not completed.');
            }
          })
          .catch((err) => {
            console.error('Execute Payment Error:', err);
          });
      },
      onClose: () => {
        // cancel is build in method you can skip this
         axios
          .post(`${baseUrl}/api/gateway/bkash/cancel`, { transaction_id: tranId })
          .then((res) => {
            const data = res.data;
            if (data.paymentID && data.transactionStatus === 'Completed') {
              alert('✅ Payment successful!');
            } else {
              alert('❌ Payment failed or not completed.');
            }
          })
          .catch((err) => {
            console.error('Execute Payment Error:', err);
          });
      },
        window.location.href = '/';
      },
    });
  };

  const handleClick = () => {
    const bkashBtn = document.getElementById('bKash_button');
    if (bkashBtn) bkashBtn.click();
  };

  return (

      Awesome Product
      Buy the best product with confidence.
      ৳ {amount}

        Buy Now

  );
};

export default BkashCheckout;
```

---

🧩 **SSLCommerz: Laravel Web Example**
-------------------------------------

[](#-sslcommerz-laravel-web-example)

```

    Pay With SSLCOMMERZ

    function updatePaymentData() {
        let obj = {
            cus_phone: document.querySelector('.cus_phone').value,
            amount: document.querySelector('.total_amount')?.value || 200
        };
        document.getElementById('sslczPayBtn').setAttribute('postdata', JSON.stringify(obj));
    }
    document.querySelector('.cus_phone').addEventListener('change', updatePaymentData);
    updatePaymentData();

```

[![Payment Page](https://raw.githubusercontent.com/Rmdmostakim/screens/main/bdpayment-5.png)](https://raw.githubusercontent.com/Rmdmostakim/screens/main/bdpayment-5.png)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

[](#-4)

[![Gateway Popup](https://raw.githubusercontent.com/Rmdmostakim/screens/main/bdpayment-6.png)](https://raw.githubusercontent.com/Rmdmostakim/screens/main/bdpayment-6.png)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------

[](#-5)

⚛️ **SSLCommerz: ReactJS Example**
----------------------------------

[](#️-sslcommerz-reactjs-example)

```
import { useEffect, useState } from "react";

export default function SslCommerzCheckout() {
  const [phone, setPhone] = useState("");
  const [amount, setAmount] = useState(200); // example static total

  useEffect(() => {
    // Load SSLCOMMERZ embed script
    const script = document.createElement("script");
    script.src = "https://sandbox.sslcommerz.com/embed.min.js?" + Math.random().toString(36).substring(7);
    script.async = true;
    document.body.appendChild(script);
  }, []);

  const handleClick = () => {
    const obj = { cus_phone: phone, amount };
    const btn = document.getElementById("sslczPayBtn");
    btn.setAttribute("postdata", JSON.stringify(obj));
  };

  return (

       setPhone(e.target.value)}
        className="border p-2 mb-2"
      />

        Pay With SSLCOMMERZ

  );
}
```

---

🧩 **Extending**
---------------

[](#-extending)

You can add more gateways by extending the drivers in
`packages/rmdmostakim/bdpayment/src/Drivers` and updating the config.

---

🪪 License
---------

[](#-license)

MIT

---

###  Health Score

33

—

LowBetter than 75% of packages

Maintenance61

Regular maintenance activity

Popularity7

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity49

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 63.6% 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

Unknown

Total

1

Last Release

246d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/777658ad53a39d834afc61e68cf49dcbfc4e2278e75b7ce14af992bbf4b1508e?d=identicon)[Rmdmostakim](/maintainers/Rmdmostakim)

---

Top Contributors

[![Rmdmostakim](https://avatars.githubusercontent.com/u/69758064?v=4)](https://github.com/Rmdmostakim "Rmdmostakim (7 commits)")[![WSITMostakim](https://avatars.githubusercontent.com/u/144409688?v=4)](https://github.com/WSITMostakim "WSITMostakim (4 commits)")

### Embed Badge

![Health badge](/badges/rmdmostakim-bdpayment/health.svg)

```
[![Health](https://phpackages.com/badges/rmdmostakim-bdpayment/health.svg)](https://phpackages.com/packages/rmdmostakim-bdpayment)
```

###  Alternatives

[musahmusah/laravel-multipayment-gateways

A Laravel Package that makes implementation of multiple payment Gateways endpoints and webhooks seamless

852.2k1](/packages/musahmusah-laravel-multipayment-gateways)[wandesnet/mercadopago-laravel

PHP SDK for integration with Mercado Pago

252.4k](/packages/wandesnet-mercadopago-laravel)[devinweb/laravel-youcan-pay

YouCanPay packages for Laravel that provides an easy way to reach the best experience.

111.1k](/packages/devinweb-laravel-youcan-pay)

PHPackages © 2026

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