PHPackages                             mainul/pay-station-disbursement - 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. mainul/pay-station-disbursement

ActiveLibrary[Payment Processing](/categories/payments)

mainul/pay-station-disbursement
===============================

Laravel package for the PayStation bKash/Nagad/Rocket disbursement API.

v1.0.0(2mo ago)01MITPHP ^8.2

Since May 1Compare

[ Source](https://github.com/Mainul12501/pay-station-disbursement)[ Packagist](https://packagist.org/packages/mainul/pay-station-disbursement)[ RSS](/packages/mainul-pay-station-disbursement/feed)WikiDiscussions Synced 3w ago

READMEChangelogDependencies (7)Versions (2)Used By (0)

Laravel bKash Disbursement Package
==================================

[](#laravel-bkash-disbursement-package)

[![License: MIT](https://camo.githubusercontent.com/08cef40a9105b6526ca22088bc514fbfdbc9aac1ddbf8d4e6c750e3a88a44dca/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d626c75652e737667)](LICENSE.md)[![PHP Version](https://camo.githubusercontent.com/9051b6544f57608ca691a918b38ad8c567657e0ecb6d4e960be274f287d171d8/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e322532422d3838393242462e737667)](https://php.net)[![Laravel](https://camo.githubusercontent.com/599bcec48d5d03f0c3ec636be9f1ee1341f6b37299bb6cc0f933d1061ec0ca59/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d31312e7825323025374325323031322e7825323025374325323031332e782d4646324432302e737667)](https://laravel.com)

`mainul/pay-station-disbursement` is a Laravel package for the PayStation bKash disbursement API.

It currently implements the two documented endpoints:

MethodEndpointDescription`POST``/merchant/disbursement/request`Disburse money to a bKash account`POST``/merchant/disbursement/status`Check the status of a disbursement transactionThe package is designed for Laravel `11`, `12`, and `13`, uses Laravel's HTTP client, validates request payloads before sending them, and throws explicit exceptions for configuration, validation, transport, and API-level failures.

Features
--------

[](#features)

- Laravel auto-discovery support (zero-config registration)
- Publishable configuration file with environment variable support
- Typed request payload and response objects (DTOs)
- Clear exception hierarchy for operational failures
- Runtime credential overrides for multi-merchant use cases
- Built-in request validation before HTTP calls
- Configurable timeout and retry logic
- Testbench test coverage for the documented endpoints

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

[](#requirements)

- PHP `8.2+`
- Laravel `11.x`, `12.x`, or `13.x`

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

[](#installation)

Install the package with Composer:

```
composer require mainul/pay-station-disbursement
```

The service provider and facade are registered automatically via Laravel's package auto-discovery.

Publish the config file:

```
php artisan vendor:publish --tag=bkash-disbursement-config
```

This publishes `config/bkash-disbursement.php` to your application's config directory.

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

[](#configuration)

Add these values to your `.env` file:

```
BKASH_DISBURSEMENT_BASE_URL=https://api.paystation.com.bd
BKASH_DISBURSEMENT_MERCHANT_ID=your_merchant_id
BKASH_DISBURSEMENT_PASSWORD=your_hashed_password
BKASH_DISBURSEMENT_PORTAL_KEY=your_portal_key
```

Optional configuration (with defaults):

```
BKASH_DISBURSEMENT_TIMEOUT=30
BKASH_DISBURSEMENT_CONNECT_TIMEOUT=10
BKASH_DISBURSEMENT_RETRY_TIMES=1
BKASH_DISBURSEMENT_RETRY_SLEEP=200
```

VariableRequiredDefaultDescription`BKASH_DISBURSEMENT_BASE_URL`No`https://api.paystation.com.bd`API base URL`BKASH_DISBURSEMENT_MERCHANT_ID`Yes-Your merchant/store ID`BKASH_DISBURSEMENT_PASSWORD`Yes-Pre-hashed password`BKASH_DISBURSEMENT_PORTAL_KEY`Yes-Portal authentication key`BKASH_DISBURSEMENT_TIMEOUT`No`30`Request timeout (seconds)`BKASH_DISBURSEMENT_CONNECT_TIMEOUT`No`10`Connection timeout (seconds)`BKASH_DISBURSEMENT_RETRY_TIMES`No`1`Number of retry attempts`BKASH_DISBURSEMENT_RETRY_SLEEP`No`200`Delay between retries (milliseconds)> **Note:** The API requires the `password` to be sent in hashed form. The package does **not** hash it for you -- store the pre-hashed value in your environment.

Usage
-----

[](#usage)

### Disbursement request

[](#disbursement-request)

Using the `DisbursementPayload` DTO:

```
use Mainul12501\BkashDisbursement\Data\DisbursementPayload;
use Mainul12501\BkashDisbursement\Facades\BkashDisbursement;

$response = BkashDisbursement::disburse(new DisbursementPayload(
    invoiceNumber: '1213456789199973',
    bankType: 1,
    bankId: 2,
    accountNumber: '01726315133',
    amount: '20.00',
));

$response->transactionId;   // 73KIO6OC
$response->invoiceNumber;   // 1213456789199973
$response->amount;          // 20
$response->charge;          // 0.14
$response->transactionTime; // 2026-01-15 12:30:00
$response->message;         // The amount has been disbursed successfully
```

You can also pass a plain array:

```
$response = BkashDisbursement::disburse([
    'invoice_number' => '1213456789199973',
    'bank_type' => 1,
    'bank_id' => 2,
    'acc_no' => '01726315133',
    'amount' => '20.00',
]);
```

### Transaction status

[](#transaction-status)

```
use Mainul12501\BkashDisbursement\Facades\BkashDisbursement;

$status = BkashDisbursement::status('178881732008099');

if ($status->isSuccessful()) {
    // Disbursement completed successfully.
    $status->transactionId;
    $status->amount;
}

if ($status->isNotFound()) {
    // No transaction matched the invoice number.
}

$status->message;
```

### Dependency injection

[](#dependency-injection)

```
use Mainul12501\BkashDisbursement\Contracts\BkashDisbursementClient;

class CheckDisbursementStatusAction
{
    public function __construct(
        private readonly BkashDisbursementClient $client,
    ) {
    }

    public function handle(string $invoiceNumber): string
    {
        return $this->client->status($invoiceNumber)->message;
    }
}
```

### Runtime credential overrides

[](#runtime-credential-overrides)

Useful when your application serves multiple merchants:

```
use Mainul12501\BkashDisbursement\Contracts\BkashDisbursementClient;

$client = app(BkashDisbursementClient::class)
    ->withCredentials(
        merchantId: 'another-merchant-id',
        password: 'another-hashed-password',
        requestFromMerchantPortalKey: 'another-portal-key',
    );

$response = $client->disburse([
    'invoice_number' => 'INV-2026-0001',
    'bank_type' => 1,
    'bank_id' => 2,
    'acc_no' => '01726315133',
    'amount' => '20.00',
]);
```

Error handling
--------------

[](#error-handling)

The package throws specific exceptions so callers can handle failures precisely:

```
use Mainul12501\BkashDisbursement\Exceptions\ApiException;
use Mainul12501\BkashDisbursement\Exceptions\HttpRequestException;
use Mainul12501\BkashDisbursement\Exceptions\InvalidConfigurationException;
use Mainul12501\BkashDisbursement\Exceptions\RequestValidationException;
use Mainul12501\BkashDisbursement\Exceptions\UnexpectedResponseException;
use Mainul12501\BkashDisbursement\Facades\BkashDisbursement;

try {
    $response = BkashDisbursement::disburse([
        'invoice_number' => 'INV-2026-0001',
        'bank_type' => 1,
        'bank_id' => 2,
        'acc_no' => '01726315133',
        'amount' => '20.00',
    ]);
} catch (RequestValidationException $e) {
    // Local payload validation failed before the HTTP request was sent.
    $errors = $e->errors; // array keyed by field name
} catch (InvalidConfigurationException $e) {
    // Required credentials are missing from config or runtime overrides.
    $message = $e->getMessage();
} catch (HttpRequestException $e) {
    // The remote API returned a non-2xx response or could not be reached.
    $status = $e->httpStatus;     // ?int
    $body   = $e->responseBody;   // ?string
} catch (ApiException $e) {
    // The remote API returned an application-level failure (e.g. duplicate invoice).
    $apiCode     = $e->apiStatusCode; // ?string
    $apiResponse = $e->response;      // array
} catch (UnexpectedResponseException $e) {
    // The remote API returned a malformed or non-JSON response.
    $body = $e->responseBody; // ?string
}
```

### Exception hierarchy

[](#exception-hierarchy)

```
RuntimeException
 └── BkashDisbursementException
      ├── RequestValidationException
      ├── InvalidConfigurationException
      ├── HttpRequestException
      ├── ApiException
      └── UnexpectedResponseException

```

ExceptionWhen it's thrownKey properties`RequestValidationException`Payload validation fails before the HTTP request`errors` (array)`InvalidConfigurationException`Required credentials are missing-`HttpRequestException`Non-2xx HTTP response or connection failure`httpStatus`, `responseBody``ApiException`API returns an application-level error payload`apiStatusCode`, `response``UnexpectedResponseException`API returns non-JSON or malformed response`responseBody`Response objects
----------------

[](#response-objects)

### `DisbursementResponse`

[](#disbursementresponse)

Returned by the `disburse()` method.

PropertyTypeDescription`statusCode``string`API status code`status``string`Status label (e.g. `success`)`invoiceNumber``string`The invoice number sent in the request`amount``string`Disbursed amount`charge``string`Transaction charge`transactionId``string`Unique transaction identifier`transactionTime``?string`Timestamp of the transaction`message``string`Human-readable status message### `DisbursementStatusResponse`

[](#disbursementstatusresponse)

Returned by the `status()` method.

PropertyTypeDescription`statusCode``string`API status code`status``string`Status label`transactionStatus``string`Transaction status (`success` or `not_found`)`invoiceNumber``?string`The invoice number`amount``?string`Disbursed amount`transactionId``?string`Unique transaction identifier`transactionTime``?string`Timestamp of the transaction`message``string`Human-readable status messageHelper methods:

MethodReturnsDescription`isSuccessful()``bool``true` if `transactionStatus === 'success'``isNotFound()``bool``true` if `transactionStatus === 'not_found'`Validation rules
----------------

[](#validation-rules)

The `DisbursementPayload` is validated before each request:

FieldRules`invoice_number`required, string`bank_type`required, integer, must be `1``bank_id`required, integer, min `1``acc_no`required, string`amount`required, numeric, min `20`Testing
-------

[](#testing)

Run the package tests with:

```
composer test
```

API reference
-------------

[](#api-reference)

The package was implemented from the PayStation bKash disbursement API documentation. The two supported endpoints are:

- **Disbursement request:** `POST https://api.paystation.com.bd/merchant/disbursement/request`
- **Status check:** `POST https://api.paystation.com.bd/merchant/disbursement/status`

**Request headers** (sent automatically by the package):

HeaderRequired for`merchantId`Both endpoints`password`Both endpoints`requestFromMerchantPortalKey`Disbursement request only**Disbursement form fields:** `invoice_number`, `bank_type`, `bank_id`, `acc_no`, `amount`

**Status form fields:** `invoice_number`

License
-------

[](#license)

This package is open-sourced software licensed under the [MIT license](LICENSE.md).

###  Health Score

35

—

LowBetter than 77% of packages

Maintenance83

Actively maintained with recent releases

Popularity1

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity46

Maturing project, gaining track record

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

84d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/5ff09c9d3ceaf957dae0f365749477680c0eb6d8d7ada9bcc266e3d4b53552a0?d=identicon)[Mainul12501](/maintainers/Mainul12501)

---

Tags

laravelpaymentspaystationdisbursementbkashBkash disbursementRocket disbursementNagad disbursement

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/mainul-pay-station-disbursement/health.svg)

```
[![Health](https://phpackages.com/badges/mainul-pay-station-disbursement/health.svg)](https://phpackages.com/packages/mainul-pay-station-disbursement)
```

###  Alternatives

[laravel/mcp

Rapidly build MCP servers for your Laravel applications.

77922.3M186](/packages/laravel-mcp)[psalm/plugin-laravel

Psalm plugin for Laravel

3345.3M347](/packages/psalm-plugin-laravel)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9762.4M133](/packages/roots-acorn)[laravel/socialite

Laravel wrapper around OAuth 1 &amp; OAuth 2 libraries.

5.7k108.5M925](/packages/laravel-socialite)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

255.2k](/packages/aedart-athenaeum)[spatie/laravel-export

Create a static site bundle from a Laravel app

674146.0k6](/packages/spatie-laravel-export)

PHPackages © 2026

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