devrkb21 / bkash-pgw-laravel
Production-ready Laravel integration for bKash Tokenized Checkout V2 (auth, payments, webhooks).
Requires
- php: ^8.1
- illuminate/cache: ^10.0|^11.0|^12.0
- illuminate/http: ^10.0|^11.0|^12.0
- illuminate/support: ^10.0|^11.0|^12.0
Requires (Dev)
- orchestra/testbench: ^8.0|^9.0|^10.0
- phpunit/phpunit: ^10.5|^11.0
README
π Production-ready Laravel bKash package for integrating bKash Tokenized Checkout V2 API with secure webhook, token management, and full payment flow.
The most complete and secure bKash integration for Laravel.
π Quick Start (30 seconds)
composer require devrkb21/bkash-pgw-laravel
use Bkash; $url = Bkash::payment()->createPayment([ 'payerReference' => 'user_123', 'callbackURL' => route('bkash.callback'), 'amount' => '100', 'currency' => 'BDT', 'intent' => 'sale', 'merchantInvoiceNumber' => 'INV123456', ]); return redirect($url->bkash_url);
π Thatβs it. User will be redirected to bKash payment page.
βοΈ Configuration
Publish config:
php artisan vendor:publish --tag=bkash-config
Add credentials:
BKASH_ENV=sandbox BKASH_SANDBOX_BASE_URL=https://tokenized.sandbox.bka.sh/v2/tokenized-checkout BKASH_PRODUCTION_BASE_URL=https://tokenized.pay.bka.sh/v2/tokenized-checkout BKASH_APP_KEY= BKASH_APP_SECRET= BKASH_USERNAME= BKASH_PASSWORD= BKASH_TIMEOUT=30 BKASH_CACHE=true BKASH_TOKEN_CACHE_KEY=bkash.token BKASH_ENABLE_ROUTES=false
Auth APIs
Grant Token - POST /auth/grant-token
Request body keys:
{
"app_key": "{{bkash_app_key}}",
"app_secret": "{{bkash_app_secret}}"
}
Response (normalized by the package, expires_at is computed):
{
"id_token": "string",
"refresh_token": "string",
"expires_in": 3600,
"expires_at": 1730999999
}
Refresh Token - POST /auth/refresh-token
Request body keys:
{
"app_key": "{{bkash_app_key}}",
"app_secret": "{{bkash_app_secret}}",
"refresh_token": "{{bkash_refresh_token}}"
}
Response (normalized by the package, expires_at is computed):
{
"id_token": "string",
"refresh_token": "string",
"expires_in": 3600,
"expires_at": 1730999999
}
Payment APIs (Without Agreement)
Create Payment - POST /payment/create
Request body keys:
{
"payerReference": "{{payer_reference}}",
"callbackURL": "{{callback_url}}",
"amount": "{{amount}}",
"currency": "{{currency}}",
"intent": "{{intent}}",
"merchantInvoiceNumber": "{{merchant_invoice_number}}",
"merchantAssociationInfo": "{{merchant_association_info}}"
}
Response (package normalizes common fields):
{
"paymentID": "payment_123",
"paymentId": "payment_123",
"bkashURL": "https://tokenized.sandbox.bka.sh/checkout/..."
}
Execute Payment - POST /payment/execute
Request body keys:
{
"paymentId": "{{payment_id}}"
}
Response (package normalizes common fields):
{
"trxID": "trx_123"
}
Query Payment - POST /query/payment
Request body keys:
{
"paymentID": "{{payment_id}}"
}
Response (raw bKash payload, normalized keys are added when present):
{
"paymentID": "payment_123",
"trxID": "trx_123",
"...": "additional fields may be returned"
}
Capture Payment - POST /payment/capture
Request body keys:
{
"paymentId": "{{payment_id}}"
}
Response (raw bKash payload, normalized keys are added when present):
{
"paymentID": "payment_123",
"trxID": "trx_123",
"...": "additional fields may be returned"
}
Void Payment - POST /payment/void
Request body keys:
{
"paymentId": "{{payment_id}}"
}
Response (raw bKash payload, normalized keys are added when present):
{
"paymentID": "payment_123",
"trxID": "trx_123",
"...": "additional fields may be returned"
}
Payment APIs (With Agreement)
Create Payment With Agreement - POST /payment-with-agreement/create
Request body keys:
{
"agreementId": "{{agreement_id}}",
"callbackURL": "{{callback_url}}",
"amount": "{{amount}}",
"intent": "{{intent}}",
"currency": "{{currency}}",
"merchantInvoiceNumber": "{{merchant_invoice_number}}"
}
Response (package normalizes common fields):
{
"paymentID": "payment_123",
"paymentId": "payment_123",
"agreementID": "agreement_123",
"agreementId": "agreement_123",
"bkashURL": "https://tokenized.sandbox.bka.sh/checkout/..."
}
Execute Payment With Agreement - POST /payment-with-agreement/execute
Request body keys:
{
"paymentId": "{{payment_id}}",
"agreementId": "{{agreement_id}}"
}
Response (package normalizes common fields):
{
"trxID": "trx_123"
}
Capture Payment With Agreement - POST /payment-with-agreement/capture
Request body keys:
{
"paymentId": "{{payment_id}}",
"agreementId": "{{agreement_id}}"
}
Response (raw bKash payload, normalized keys are added when present):
{
"paymentID": "payment_123",
"agreementID": "agreement_123",
"trxID": "trx_123",
"...": "additional fields may be returned"
}
Void Payment With Agreement - POST /payment-with-agreement/void
Request body keys:
{
"paymentId": "{{payment_id}}",
"agreementId": "{{agreement_id}}"
}
Response (raw bKash payload, normalized keys are added when present):
{
"paymentID": "payment_123",
"agreementID": "agreement_123",
"trxID": "trx_123",
"...": "additional fields may be returned"
}
Agreement APIs
Create Agreement - POST /agreement/create
Request body keys:
{
"payerReference": "{{payer_reference}}",
"callbackURL": "{{agreement_callback_url}}"
}
Response (raw bKash payload):
{
"agreementID": "agreement_123",
"bkashURL": "https://tokenized.sandbox.bka.sh/checkout/...",
"...": "additional fields may be returned"
}
Execute Agreement - POST /agreement/execute
Request body keys:
{
"agreementId": "{{agreement_id}}"
}
Response (raw bKash payload):
{
"agreementID": "agreement_123",
"...": "additional fields may be returned"
}
Query Agreement - POST /query/agreement
Request body keys:
{
"agreementId": "{{agreement_id}}"
}
Response (raw bKash payload):
{
"agreementID": "agreement_123",
"...": "additional fields may be returned"
}
Cancel Agreement - POST /agreement/cancel
Request body keys:
{
"agreementId": "{{agreement_id}}"
}
Response (raw bKash payload):
{
"agreementID": "agreement_123",
"...": "additional fields may be returned"
}
Transaction and Refund APIs
Search Transaction - POST /general/search-transaction
Request body keys:
{
"trxId": "{{trx_id}}"
}
Response (raw bKash payload):
{
"trxID": "trx_123",
"...": "additional fields may be returned"
}
Refund Transaction - POST /refund/payment/transaction
Request body keys:
{
"refundAmount": "{{refund_amount}}",
"paymentId": "{{payment_id}}",
"trxId": "{{trx_id}}",
"sku": "{{sku}}",
"reason": "{{reason}}"
}
Response (raw bKash payload):
{
"paymentID": "payment_123",
"trxID": "trx_123",
"...": "additional fields may be returned"
}
Refund Status - POST /refund/payment/status
Request body keys:
{
"paymentId": "{{payment_id}}",
"trxId": "{{trx_id}}"
}
Response (raw bKash payload):
{
"paymentID": "payment_123",
"trxID": "trx_123",
"...": "additional fields may be returned"
}
Webhook Events (SNS)
Enable the built-in route by setting BKASH_ENABLE_ROUTES=true.
Webhook endpoint:
POST /bkash/webhook
SubscriptionConfirmation Event
Headers:
- Content-Type: application/json
- x-amz-sns-message-type: SubscriptionConfirmation
Request body keys:
{
"Type": "SubscriptionConfirmation",
"MessageId": "11111111-2222-3333-4444-555555555555",
"Token": "{{sns_token}}",
"TopicArn": "{{sns_topic_arn}}",
"Message": "You have chosen to subscribe to the topic.",
"SubscribeURL": "{{sns_subscribe_url}}",
"Timestamp": "2026-04-11T00:00:00.000Z",
"SignatureVersion": "1",
"Signature": "{{sns_signature}}",
"SigningCertURL": "{{sns_signing_cert_url}}"
}
Response (from the package webhook service):
{
"success": true,
"type": "SubscriptionConfirmation",
"data": {
"subscriptionConfirmed": true,
"subscribeURL": "https://sns.us-east-1.amazonaws.com/?Action=ConfirmSubscription"
}
}
Notification Event
Headers:
- Content-Type: application/json
- x-amz-sns-message-type: Notification
Request body keys:
{
"Type": "Notification",
"MessageId": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
"TopicArn": "{{sns_topic_arn}}",
"Subject": "bKash Payment Notification",
"Message": "{\"debitMSISDN\":\"{{debit_msisdn}}\",\"creditShortCode\":\"{{credit_shortcode}}\",\"amount\":\"{{amount}}\",\"trxID\":\"{{trx_id}}\",\"currency\":\"{{currency}}\",\"dateTime\":\"20260411093030\",\"transactionType\":\"{{transaction_type}}\",\"transactionStatus\":\"{{transaction_status}}\"}",
"Timestamp": "2026-04-11T00:05:00.000Z",
"SignatureVersion": "1",
"Signature": "{{sns_signature}}",
"SigningCertURL": "{{sns_signing_cert_url}}"
}
Response (from the package webhook service):
{
"success": true,
"type": "Notification",
"data": {
"trxID": "trx_123",
"trxId": "trx_123",
"amount": "100.00",
"transactionStatus": "Completed"
}
}
Checkout SDK
Checkout Script URL - GET
https://scripts.{{bkash_sdk_host}}.bka.sh/versions/{{bkash_sdk_version}}/checkout/bKash-checkout{{bkash_sdk_suffix}}.js
Response: JavaScript file (200/301/302/304/404).
Payout
Initiate Payout - POST /payout/initiate
Request body keys:
{
"type": "B2C",
"Rereference": "{{payer_reference}}"
}
Response (raw bKash payload):
{
"paymentID": "payment_123",
"...": "additional fields may be returned"
}
π³ Payment Flow
1. Create Payment
Bkash::payment()->createPayment([...]);
2. Handle Callback
Bkash::payment()->handleCallback(request()->all());
3. Query Payment
Bkash::payment()->queryPayment($paymentId);
4. Capture / Void
Bkash::payment()->capturePayment($paymentId); Bkash::payment()->voidPayment($paymentId);
π Agreement (Saved Wallet)
Bkash::agreement()->createAgreement([...]); Bkash::agreement()->executeAgreement($agreementId);
π° Refund API
Bkash::refund()->refundTransaction([ 'paymentId' => $paymentId, 'trxId' => $trxId, 'refundAmount' => '10', 'reason' => 'Customer request', ]);
π Webhook (Secure & Automatic)
Enable in config:
'enable_routes' => true,
Endpoint:
POST /bkash/webhook
Automatically handled:
- SNS Subscription confirmation
- Signature verification
- Replay attack protection
- Notification parsing
π Why this package?
Most Laravel bKash packages:
- β No token management
- β No webhook security
- β Only basic API wrappers
This package provides:
- β Automatic token lifecycle (grant + refresh)
- β Secure SNS webhook verification
- β Replay attack protection
- β Retry-safe HTTP client
- β Full payment + agreement + refund APIs
- β Clean Laravel integration (Facade + DI)
- β Test coverage
π§ͺ Testing
composer test
π¦ Requirements
- PHP 8.1+
- Laravel 10 / 11 / 12
π SEO Keywords
Laravel bKash payment gateway, bKash Laravel package, Bangladesh payment gateway Laravel, bKash Tokenized Checkout V2, Laravel payment integration bKash
π Roadmap
- Event system (PaymentSuccess, Failed)
- Queue-based webhook handling
- Multi-gateway support (bKash + Nagad + SSLCommerz)
π€ Contributing
PRs are welcome. Please ensure tests pass.
π License
MIT License
β Support
If this package helps you, please give it a star β It helps others discover the project.
β Support Development
If you find this package useful, you can support ongoing development: