mainul12501/bkash-payment-b2c 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

mainul12501/bkash-payment-b2c

最新稳定版本:v1.0.0

Composer 安装命令:

composer require mainul12501/bkash-payment-b2c

包简介

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

README 文档

README

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

  • 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

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

Installation

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

Configuration

Default config file: 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

Facade entry point

use Mainul12501\Bkash\Facades\Bkash;

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

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

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

Search transaction

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

Refund

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

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

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

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

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

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

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

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

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

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

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

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

  • 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

Bkash::checkout()

  • 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()

  • 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()

  • grantToken(): array
  • refreshToken(): array
  • initiate(array $payload): BkashResponse
  • b2b(array $payload): BkashResponse

Bkash::webhooks()

  • 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

统计信息

  • 总下载量: 1
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 9
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-05-01

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固