Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Bkash Laravel Package

sabitahmad/laravel-bkash

Integrate bKash payments into Laravel with full API v1.2.0 support: tokenized and regular checkout, agreements, refunds, queries, token refresh, transaction logging, events, and sandbox/production modes.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

The package follows Laravel's standard package conventions: a service provider with auto-discovery, a Bkash facade, a publishable config file, publishable migrations for transaction logging, and domain events (PaymentCompleted, PaymentFailed, AgreementCreated). That is the idiomatic shape for a Laravel integration and means it can be adopted without architectural surgery in a conventional Laravel monolith or modular monolith.

It is a thin SDK wrapper, not a payment orchestration layer. It maps 1:1 onto bKash's Tokenized Checkout API v1.2.0 (create/execute/query/refund/search for payments; create/execute/query/cancel for agreements; token grant/refresh), and returns typed response objects (PaymentResponse, AgreementResponse, RefundResponse, QueryResponse, SearchResponse) with a consistent isSuccess()/hasError()/getRawData() surface. The response-method tables in the README are the strongest part of the artifact — they make the contract with bKash legible without reading source.

What it deliberately does not provide: an order/cart abstraction, idempotency keys, webhook signature verification, reconciliation jobs, ledgering, multi-tenant credential resolution, or a state machine for the create→redirect→callback→execute lifecycle. Those are ours to build. The helpers/BkashHelper and the examples/BkashController.php cover the happy path only.

Integration feasibility

Low friction to a running sandbox: composer require, publish config + migrations, set six env vars, get a redirect URL back. A spike should be achievable in 1–3 engineering days including a sandbox merchant account.

Caveats we must verify before committing:

  • Laravel/PHP ceiling. README states PHP 8.0+ and Laravel 8.x+. There is no stated support for Laravel 11/12 or PHP 8.3/8.4. If we are on a current LTS, we need to confirm illuminate/support constraints and whether the service provider uses anything deprecated.
  • Production URL is a beta path. The config ships https://tokenized.pay.bka.sh/v1.2.0-beta/... as the production base URL. bKash's own naming may legitimately retain the -beta segment in the tokenized product line, but a TPM cannot accept that on faith — this must be confirmed against current bKash merchant documentation and, ideally, bKash merchant support in writing.
  • Credential model is single-merchant, env-driven, global config. No support for multiple merchant accounts, per-tenant credentials, or secret rotation without a deploy. Fine for a single-store BD launch; a blocker for a multi-tenant or marketplace model.
  • Callback handling is redirect-based (callbackURL posted back with paymentID). There is no signature/HMAC verification in the package. Correctness must be established by calling queryPayment/executePayment server-side before trusting any status — the README's callback example does call executePayment, which is the right instinct, but it is a documentation pattern, not an enforced guarantee.

Technical risk

  • Adoption is effectively zero — 1 star, 0 dependents. There is no crowd-sourced defect discovery. Every edge case is ours to find.
  • Single-maintainer bus factor. MIT license is the mitigation: we can fork and vendor the code. Budget for that possibility from day one rather than treating it as a contingency.
  • Release metadata anomaly. The recorded last release date (2026-09-11) is inconsistent with a normal audit window. Treat the changelog and Packagist release history as unverified until we check them directly; do not assume an active maintenance cadence.
  • No visible test suite or CI in the described maturity signals (readme, changelog, releases). For code that moves money, that is the largest single gap. Our own integration test suite against the bKash sandbox becomes mandatory, not optional.
  • Network resilience features (retry with delay) are a double-edged sword. Retries around create and execute are exactly where duplicate charges originate if the operation is not idempotent at the bKash level. The package exposes BKASH_RETRY_ATTEMPTS and BKASH_RETRY_DELAY; we need to understand which calls are retried and confirm bKash's idempotency behaviour per endpoint.
  • DB logging of transactions is a feature, but it means a schema we now own. Migration and retention policy are ours.
  • Amount/currency validation is configurable (BKASH_MIN_AMOUNT, BKASH_MAX_AMOUNT, BKASH_CURRENCY=BDT). Enforcement at the package layer is not a substitute for enforcement at the order layer.

Key questions for the maintainer / our own engineering

  1. Which bKash API version is pinned, and what is the upgrade path when bKash ships v1.3 or retires v1.2.0?
  2. Is -beta in the production base URL correct and current?
  3. Which operations are retried automatically, and are any of them non-idempotent?
  4. Is there a test suite, and does it run against a sandbox or mocks?
  5. Laravel 11/12 and PHP 8.3/8.4 support status?
  6. What is the maintenance commitment — is this a maintained product or a published project?
  7. How does the package handle token cache invalidation across concurrent requests and across multiple app instances?

Integration Approach

Stack fit

Good fit if we are on Laravel 8–10 with PHP 8.0–8.2 and a single bKash merchant account for a Bangladesh-facing storefront or subscription product. The package's two headline flows map cleanly to two of our likely use cases:

  • Regular Checkout for one-off purchases.
  • Agreement (tokenized) flow for subscriptions, saved instruments, or repeat-charge journeys — this is the differentiating capability and the main reason to consider the package over hand-rolling HTTP calls.

Poor fit if we need multi-merchant routing, marketplace/split settlement, non-BDT presentment, or full payment abstraction across multiple gateways. In that case the package should be treated as a reference implementation and a source of bKash API semantics, not as a dependency.

Migration path

Do not call Bkash:: from controllers or domain services. First move:

  1. Define an internal PaymentGateway port in our domain: createIntent, confirm, refund, query, cancel, plus our own value objects. This is where idempotency keys, correlation IDs, and status normalisation live.
  2. Implement BkashGatewayAdapter that delegates to the package facade and translates its response objects into our value objects. All package-specific types stay behind this boundary.
  3. Persist our own payments and payment_attempts tables with our own state machine. Use the package's transaction log table as a diagnostic/audit side-channel, not as the system of record.
  4. Handle bKash callbacks at a dedicated, authenticated endpoint that: looks up the attempt by our reference, calls queryPayment (or executePayment exactly once, guarded), and transitions state idempotently.

If the adapter boundary is in place, replacing the package with direct Guzzle calls or a fork is a contained change — days, not a quarter.

Compatibility

  • Pin the package to an exact version in composer.json ("sabitahmad/laravel-bkash": "x.y.z"), not a caret range. With 0 dependents and no visible CI, unvetted patch releases are not a risk worth accepting.
  • Confirm illuminate/* constraints resolve against our Laravel version in a scratch branch before any product work.
  • Verify the config cache path works (php artisan config:cache) — packages that read env() outside the config file break in cached deploys.
  • Confirm the migrations are additive and don't collide with existing table names; run them in a reviewable migration batch.
  • Check that BKASH_SANDBOX is driven strictly from config and defaults to true, and add a deploy-time assertion that production cannot boot with sandbox credentials.

Sequencing

  1. Week 0 — Credentials and docs. Open a bKash merchant sandbox account; obtain written confirmation of the current production base URL and API version. This is the critical-path external dependency and it is not ours to control.
  2. Week 1 — Sandbox spike. Install, publish, run the full regular-checkout and agreement flows end-to-end in a scratch app. Timebox to 3 days. Deliverable: a written note on what the package does and does not handle, plus answers to the seven key questions above.
  3. Week 2 — Boundary and hardening. Build the PaymentGateway port and adapter; add idempotency, callback verification via query, structured logging with correlation IDs, and sandbox integration tests in CI.
  4. Week 3 — Failure-path and reconciliation. Build the reconciliation job (searchTransaction / queryPayment sweep over unsettled attempts), the refund runbook, and the token-refresh failure path. Deliberately test: expired token, timeout after bKash accepted, lost callback, duplicate callback, refund partial failure.
  5. Week 4 — Production pilot. Single low-value SKU or a percentage rollout behind a feature flag, with an ops dashboard on success rate, executePayment latency, and callback-to-settlement lag.
  6. Ongoing — Fork readiness. Keep a fork of the package in our org from the moment we go live. We do not need to modify it, but having the fork means a maintainer disappearance is a non-event.

Operational Impact

Maintenance

  • The package is small and stable-by-nature (it mirrors an external API). Expected maintenance is low, but all of it lands on us, not on a vendor. Budget roughly 0.1–0.2 FTE ongoing for dependency and bKash API-version upkeep, plus the fork.
  • Our fork becomes the artifact we patch. Upstream merges are opportunistic; treat the fork as the primary once we are in production, and review upstream releases quarterly rather than tracking them continuously.
  • API drift is the real maintenance driver, not code churn. bKash version changes, endpoint deprecations, or changes to the tokenized flow are the events that will actually page someone.

Support

  • No vendor SLA, no support contract, no security disclosure process. Escalation for bKash-side issues runs through bKash merchant support, which is the correct channel anyway and is unaffected by our package choice.
  • For package-level defects, our own engineers are the support tier. This is acceptable precisely because the surface area is small and the code is MIT and forkable — but it must be an explicit, documented decision, not an accident.
  • Document the "who do we call" matrix in the runbook: bKash merchant support for API/settlement issues, our on-call for application errors, and a named owner for the fork.

Scaling

  • Throughput is bounded by bKash, not by the package. The package is a synchronous HTTP client; the design question is whether payment initiation happens in the request path or via a queued job. For anything beyond modest volume, queue the create call and return an interstitial.
  • Token management is cached (BKASH_TOKEN_CACHE_TTL=3300, ~55 min) and auto-refreshed. With multiple app instances on a shared cache store this is fine; with file/array cache per instance it means N token grants per hour and avoidable 401s. Mandate Redis or a shared cache in production.
  • Database logging grows monotonically. Define retention (e.g. 90 days hot, archive to object storage) at launch, not after the table hits tens of millions of rows.
  • Callback endpoints absorb the redirect traffic and are the burst-prone surface. They must be stateless, fast, and idempotent, with execution deferred to a queue where possible.
  • Multi-region or multi-merchant expansion is not supported by the config model; that becomes a fork-level change.

Failure modes to instrument and runbook

Failure Symptom Mitigation
Token expiry / refresh failure 401s on all operations Shared cache; alert on refresh failures; retry with backoff
Timeout after bKash accepted Order stuck pending, money possibly taken Reconciliation sweep via queryPayment; never blind-retry createPayment
Lost callback (user closes tab) Order never transitions Reconciliation job; show "check status" UX, not a hard failure
Duplicate callback delivery Double execution / double fulfilment Idempotent handler keyed on paymentID; fulfil exactly once
Retry-induced duplicate charge Two trxIds for one order Idempotency at our order layer; verify BKASH_RETRY_ATTEMPTS semantics
Amount/currency mismatch Rejected or wrong-charge Validate at order layer, not only package config
Refund partial failure Refunded in our system, not in bKash Two-phase refund with refundStatus confirmation before closing the ticket
Sandbox credentials in production Test transactions on live traffic Deploy-time assertion; alert on BKASH_SANDBOX=true in prod

Ramp-up

  • The README is genuinely above average for a package of this size: response-method tables, env var reference, and a full controller example materially reduce discovery time. Expect 1–2 days for a Laravel-fluent engineer to reach a working sandbox payment.
  • The real ramp-up cost is not the package, it is bKash domain knowledge: merchant onboarding, sandbox provisioning, settlement timing, refund windows, and the tokenized-agreement UX. Budget 1–2 weeks of calendar time for those external steps, which engineering cannot compress.
  • Because there are no tests, the team's onboarding artifact must be our own integration test suite against sandbox. That suite is what turns "the README says it works" into "we know it works," and it is the single highest-leverage thing we can build on top of this dependency.

Overall TPM read: acceptable as an accelerator behind a strict adapter boundary for a single-merchant BDT launch; not acceptable as an unexamined direct dependency for a money-critical, high-volume, or multi-tenant payments platform. The decision is defensible only if we fund the fork, the adapter layer, and the sandbox test suite as part of the initial integration — roughly 2–4 engineer-weeks beyond the spike.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core