PHPackages                             mainul12501/bkash-payment-b2c - 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. mainul12501/bkash-payment-b2c

ActiveLibrary[Payment Processing](/categories/payments)

mainul12501/bkash-payment-b2c
=============================

Laravel 11+ package for BKash checkout, tokenized checkout, B2C, B2B payout, refund, search, and wallet operations.

v1.0.0(1mo ago)01MITPHPPHP ^8.2

Since May 1Pushed 1mo agoCompare

[ Source](https://github.com/Mainul12501/bkash-payment-b2c)[ Packagist](https://packagist.org/packages/mainul12501/bkash-payment-b2c)[ RSS](/packages/mainul12501-bkash-payment-b2c/feed)WikiDiscussions master Synced 1w ago

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

Laravel bKash Gateway
=====================

[](#laravel-bkash-gateway)

Laravel 11, 12, and 13 package for bKash payment gateway integrations, covering the public flows exposed in bKash's current developer docs and guides.

Features
--------

[](#features)

- Checkout (URL based) Regular sale payment Auth and capture Void Query payment Search transaction Refund
- Tokenized checkout Grant token Refresh token Create agreement Execute agreement Query agreement Cancel agreement Create payment Execute payment Confirm payment Query payment Search transaction Refund Refund status helper
- Disbursement and wallet operations B2C payout to customer Organization balance query Intra-account transfer B2B merchant payout B2B payout initiation
- Integration helpers Automatic token caching and refresh retry Raw request escape hatch for undocumented or newly-added endpoints Webhook payload parsing and optional shared-secret check

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

[](#requirements)

- PHP 8.2+
- Laravel 11, 12, or 13

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

[](#installation)

```
composer require mainul12501/bkash-payment-b2c
php artisan vendor:publish --tag=bkash-config
```

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

[](#configuration)

Default config file: [config/bkash.php](config/bkash.php)

Minimal `.env` example:

```
BKASH_ENV=sandbox
BKASH_TIMEOUT=30
BKASH_CONNECT_TIMEOUT=10
BKASH_VERIFY_TLS=true
BKASH_CACHE_STORE=

BKASH_USERNAME=
BKASH_PASSWORD=
BKASH_APP_KEY=
BKASH_APP_SECRET=

BKASH_WEBHOOK_SECRET=
BKASH_WEBHOOK_SECRET_HEADER=X-BKASH-WEBHOOK-SECRET
```

The sandbox and production URLs have sensible defaults in the config file. Override them only if bKash changes the endpoints:

```
BKASH_CHECKOUT_SANDBOX_URL=https://checkout.sandbox.bka.sh/v1.2.0-beta
BKASH_CHECKOUT_PRODUCTION_URL=https://checkout.pay.bka.sh/v1.2.0-beta

BKASH_TOKENIZED_SANDBOX_URL=https://tokenized.sandbox.bka.sh/v1.2.0-beta
BKASH_TOKENIZED_PRODUCTION_URL=https://tokenized.pay.bka.sh/v1.2.0-beta

BKASH_PAYOUTS_SANDBOX_URL=https://tokenized.sandbox.bka.sh
BKASH_PAYOUTS_PRODUCTION_URL=https://tokenized.pay.bka.sh
```

If bKash gives you different credentials per service, set the service-specific keys:

```
BKASH_CHECKOUT_USERNAME=
BKASH_CHECKOUT_PASSWORD=
BKASH_CHECKOUT_APP_KEY=
BKASH_CHECKOUT_APP_SECRET=

BKASH_TOKENIZED_USERNAME=
BKASH_TOKENIZED_PASSWORD=
BKASH_TOKENIZED_APP_KEY=
BKASH_TOKENIZED_APP_SECRET=

BKASH_PAYOUTS_USERNAME=
BKASH_PAYOUTS_PASSWORD=
BKASH_PAYOUTS_APP_KEY=
BKASH_PAYOUTS_APP_SECRET=
```

Usage
-----

[](#usage)

### Facade entry point

[](#facade-entry-point)

```
use Mainul12501\Bkash\Facades\Bkash;

$checkout = Bkash::checkout();
$tokenized = Bkash::tokenized();
$payouts = Bkash::payouts();
```

### Checkout payment

[](#checkout-payment)

The public checkout create-payment reference shows these required body fields:

- `amount`
- `currency`
- `intent`
- `merchantInvoiceNumber`

Example:

```
$response = Bkash::checkout()->createPayment([
    'amount' => '150.00',
    'currency' => 'BDT',
    'intent' => 'sale',
    'merchantInvoiceNumber' => 'INV-1001',
    'merchantAssociationInfo' => 'order:1001',
]);

$payment = $response->toArray();
```

### Execute, capture, query, void

[](#execute-capture-query-void)

```
Bkash::checkout()->executePayment($paymentId);
Bkash::checkout()->capturePayment($paymentId);
Bkash::checkout()->queryPayment($paymentId);
Bkash::checkout()->voidPayment($paymentId);
```

### Search transaction

[](#search-transaction)

```
$response = Bkash::checkout()->searchTransaction($trxId);
```

### Refund

[](#refund)

```
$response = Bkash::checkout()->refund([
    'paymentID' => $paymentId,
    'amount' => '150.00',
    'trxID' => $trxId,
    'sku' => 'SKU-1001',
    'reason' => 'Customer requested cancellation',
]);
```

### Tokenized checkout

[](#tokenized-checkout)

The tokenized reference is structured differently from checkout. The package exposes both generic and convenience methods so you can mirror the exact request body from your bKash onboarding docs.

```
$agreement = Bkash::tokenized()->createAgreement([
    'mode' => '0000',
    'callbackURL' => route('bkash.callback'),
    'payerReference' => 'customer-1001',
]);

$executedAgreement = Bkash::tokenized()->executeAgreement([
    'paymentID' => $agreement->json('paymentID'),
]);

$payment = Bkash::tokenized()->createPayment([
    'mode' => '0011',
    'callbackURL' => route('bkash.callback'),
    'agreementID' => 'AGREEMENT_ID',
    'payerReference' => 'customer-1001',
    'amount' => '100.00',
    'currency' => 'BDT',
    'intent' => 'sale',
    'merchantInvoiceNumber' => 'INV-2001',
]);

$executedPayment = Bkash::tokenized()->executePayment([
    'paymentID' => $payment->json('paymentID'),
]);
```

### Tokenized agreement and payment queries

[](#tokenized-agreement-and-payment-queries)

```
Bkash::tokenized()->queryAgreement('AGREEMENT_ID');

Bkash::tokenized()->cancelAgreement('AGREEMENT_ID');

Bkash::tokenized()->confirmPayment('capture', [
    'paymentID' => $paymentId,
]);

Bkash::tokenized()->queryPayment([
    'paymentID' => $paymentId,
]);

Bkash::tokenized()->searchTransaction($trxId);
```

### Tokenized refund and refund status

[](#tokenized-refund-and-refund-status)

```
Bkash::tokenized()->refund([
    'paymentID' => $paymentId,
    'amount' => '10.00',
    'trxID' => $trxId,
    'sku' => 'SKU-2001',
    'reason' => 'Partial refund',
]);

Bkash::tokenized()->refundStatus([
    'paymentId' => $paymentId,
    'trxId' => $trxId,
]);
```

Note:

- The current bKash public guide for refund status is not modeled in the same embedded OpenAPI schema as the main reference pages.
- The guide currently shows `{{tokenized_url}}/v2/tokenized-checkout/refund/payment/status`.
- If your merchant onboarding doc uses a different refund-status path, override it per call:

```
Bkash::tokenized()->refundStatus($payload, '/v2/tokenized-checkout/refund/payment/transaction');
```

### B2C payout

[](#b2c-payout)

The B2C payout guide documents these required fields:

- `amount`
- `currency`
- `merchantInvoiceNumber`
- `receiverMSISDN`

```
$response = Bkash::checkout()->b2cPayment([
    'amount' => '500.00',
    'currency' => 'BDT',
    'merchantInvoiceNumber' => 'B2C-1001',
    'receiverMSISDN' => '017XXXXXXXX',
]);
```

### Organization balance

[](#organization-balance)

```
$response = Bkash::checkout()->organizationBalance();
```

### Intra-account transfer

[](#intra-account-transfer)

The public guide documents `transferType` as one of:

- `Collection2Disbursement`
- `Disbursement2Collection`

```
$response = Bkash::checkout()->intraAccountTransfer([
    'amount' => '1000.00',
    'currency' => 'BDT',
    'transferType' => 'Collection2Disbursement',
]);
```

### B2B payout

[](#b2b-payout)

The public B2B payout guide is a two-step flow.

Step 1: initiate

```
$initiate = Bkash::payouts()->initiate([
    'type' => 'B2B',
    'reference' => 'REF-1001',
]);

$payoutId = $initiate->json('payoutID');
```

Step 2: B2B payout

```
$transfer = Bkash::payouts()->b2b([
    'payoutID' => $payoutId,
    'amount' => '100.00',
    'currency' => 'BDT',
    'merchantInvoiceNumber' => 'B2B-1001',
    'receiverMSISDN' => '01XXXXXXXXX',
]);
```

### Raw request escape hatch

[](#raw-request-escape-hatch)

This package intentionally includes a low-level method because bKash sometimes documents flows in guide pages before the embedded API reference catches up.

```
$response = Bkash::raw(
    service: 'tokenized',
    method: 'POST',
    path: '/tokenized/checkout/payment/status',
    payload: ['paymentID' => $paymentId]
);
```

For absolute paths outside the service base version:

```
$response = Bkash::raw(
    service: 'tokenized',
    method: 'POST',
    path: '/v2/tokenized-checkout/refund/payment/status',
    payload: ['paymentId' => $paymentId, 'trxId' => $trxId],
    absolutePath: true
);
```

Webhooks
--------

[](#webhooks)

The package provides a simple parser and optional shared-secret header check.

```
use Illuminate\Http\Request;
use Mainul12501\Bkash\Facades\Bkash;

Route::post('/bkash/webhook', function (Request $request) {
    Bkash::webhooks()->assertMatchingSecret($request);

    $payload = Bkash::webhooks()->fromRequest($request);

    // Process webhook payload here.

    return response()->json(['received' => true]);
});
```

Response handling
-----------------

[](#response-handling)

All gateway methods return `Mainul12501\Bkash\Support\BkashResponse`.

```
$response->status();
$response->successful();
$response->json();
$response->json('paymentID');
$response->toArray();
$response->headers();
$response->body();
$response->collect();
$response->collect('items');
$response->raw();            // underlying Illuminate HTTP response
```

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

[](#error-handling)

Failed HTTP responses throw `Mainul12501\Bkash\Exceptions\BkashRequestException`.

```
use Mainul12501\Bkash\Exceptions\BkashRequestException;

try {
    $response = Bkash::checkout()->createPayment($payload);
} catch (BkashRequestException $exception) {
    $status = $exception->status();
    $response = $exception->response();
}
```

Notes
-----

[](#notes)

- bKash's product overview currently states TLS 1.2+ only.
- Sandbox and production use different hostnames.
- Checkout and tokenized references expose different schemas and path styles.
- B2B payout is documented in guide pages instead of the same embedded OpenAPI model used by checkout and tokenized reference pages.
- Subscriptions and add-wallet are mentioned in product overview, but their public API details were not exposed in the fetched docs set above. Use `Bkash::raw()` when bKash provides merchant-specific endpoint details.

Package API Summary
-------------------

[](#package-api-summary)

### `Bkash::checkout()`

[](#bkashcheckout)

- `grantToken(): array`
- `refreshToken(): array`
- `createPayment(array $payload): BkashResponse`
- `executePayment(string $paymentID): BkashResponse`
- `capturePayment(string $paymentID): BkashResponse`
- `queryPayment(string $paymentID): BkashResponse`
- `voidPayment(string $paymentID): BkashResponse`
- `searchTransaction(string $trxID): BkashResponse`
- `refund(array $payload): BkashResponse`
- `b2cPayment(array $payload): BkashResponse`
- `organizationBalance(): BkashResponse`
- `intraAccountTransfer(array $payload): BkashResponse`

### `Bkash::tokenized()`

[](#bkashtokenized)

- `grantToken(): array`
- `refreshToken(): array`
- `create(array $payload): BkashResponse`
- `createAgreement(array $payload): BkashResponse`
- `createPayment(array $payload): BkashResponse`
- `execute(array $payload): BkashResponse`
- `executeAgreement(array $payload): BkashResponse`
- `executePayment(array $payload): BkashResponse`
- `queryAgreement(array|string $agreement): BkashResponse`
- `cancelAgreement(array|string $agreement): BkashResponse`
- `confirmPayment(string $confirmationType, array $payload): BkashResponse`
- `queryPayment(array $payload): BkashResponse`
- `searchTransaction(array|string $trx): BkashResponse`
- `refund(array $payload): BkashResponse`
- `refundStatus(array $payload, ?string $path = null): BkashResponse`

### `Bkash::payouts()`

[](#bkashpayouts)

- `grantToken(): array`
- `refreshToken(): array`
- `initiate(array $payload): BkashResponse`
- `b2b(array $payload): BkashResponse`

### `Bkash::webhooks()`

[](#bkashwebhooks)

- `parse(string $payload): array`
- `fromRequest(Request $request): array`
- `hasMatchingSecret(Request $request, ?string $expected = null, ?string $header = null): bool`
- `assertMatchingSecret(Request $request, ?string $expected = null, ?string $header = null): void`

###  Health Score

38

—

LowBetter than 83% of packages

Maintenance92

Actively maintained with recent releases

Popularity1

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity46

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

Unknown

Total

1

Last Release

39d ago

### Community

Maintainers

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

---

Top Contributors

[![Mainul12501](https://avatars.githubusercontent.com/u/45430222?v=4)](https://github.com/Mainul12501 "Mainul12501 (1 commits)")

---

Tags

laravelpaymentgatewayb2brefundB2Cbkash

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/mainul12501-bkash-payment-b2c/health.svg)

```
[![Health](https://phpackages.com/badges/mainul12501-bkash-payment-b2c/health.svg)](https://phpackages.com/packages/mainul12501-bkash-payment-b2c)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3325.1M337](/packages/psalm-plugin-laravel)[spatie/laravel-responsecache

Speed up a Laravel application by caching the entire response

2.8k8.7M64](/packages/spatie-laravel-responsecache)[laravel/pulse

Laravel Pulse is a real-time application performance monitoring tool and dashboard for your Laravel application.

1.7k14.1M120](/packages/laravel-pulse)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9732.3M121](/packages/roots-acorn)[propaganistas/laravel-disposable-email

Disposable email validator

6012.9M7](/packages/propaganistas-laravel-disposable-email)[sebdesign/laravel-viva-payments

A Laravel package for integrating the Viva Payments gateway

4849.3k](/packages/sebdesign-laravel-viva-payments)

PHPackages © 2026

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