Automated Bangladesh MFS Payment Engine · 100% Verified

Instant MFS Payment Verification for Bangladesh.

Eliminate manual TrxID verification. Match customer payments in real-time from bKash, Nagad, and Rocket, authoritatively confirm transactions, and trigger signed webhooks instantly.

Supported Payment Adapters
bKash Nagad Rocket DBBL Upay tap Sandbox Engine
bKash Personal / Merchant Matched
৳1,500.00 TrxID: BK90184A2X
Invoice: INV-2026-449 · Ref: verified
Webhook Dispatched
https://merchant.com/api/mfs
HTTP 200 OK
// Signature verified: HMAC-SHA256
{ "event": "payment.paid", "amount_minor": 150000, "status": "paid" }
Companion Android Collector
AES-256 encrypted Room queue · Least-privilege sync
Engine Architecture

Engineered for Reliability & Strict Concurrency

Built on pure modular domain logic and tested across 570+ automated checks. Never misrepresents untrusted SMS as bank-confirmed without authoritative verification.

No Fake SMS Verifications

An incoming SMS reaches at most matched status. Invoice settlement requires authoritative API confirmation or audited manual sign-off with dual verification proofs.

Poisha-Precision Integer Math

Zero floating-point calculation errors. Financial amounts are converted into integer minor units (poisha), supporting Bengali numerals and strict exact-match rules.

SSRF-Guarded Webhook Dispatch

Signed HMAC-SHA256 payloads with DNS rebinding protection and private IP filtering. Automatic exponential backoff retries over 24 hours.

Native Android Collector

Offline-first Room database queue, WorkManager deferred sync, encrypted tokens, and strict sender whitelisting. Zero personal SMS reading.

Spatie RBAC Multi-Tenancy

Strict fail-closed tenant scoping with Spatie role and permission integration. Finance, Developer, Admin, and Auditor roles built in.

Idempotency & Row-Locking

Database-level unique constraints and row locks prevent race conditions, duplicate TrxID submissions, and double-allocation to multiple invoices.

Interactive Playground

Test the Verification Pipeline in Real-Time

Simulate an incoming mobile financial service notification from bKash or Nagad. See how our backend validates the payload, matches the invoice, and dispatches the signed webhook.

৳
Verification Engine Terminal
Awaiting Trigger
1. Notification
2. Deduplication
3. Match Invoice
4. Webhook Sent
// Press "Trigger Simulated Payment" to start the pipeline test...
                        
Transparent SaaS Subscription

Simple, Predictable Pricing for Bangladeshi Merchants

Start with a free evaluation tier or unlock full capabilities with our single monthly plan. No hidden transaction percentage cut.

Developer / Starter

Free Evaluation

Perfect for testing in sandbox mode and small shops.
৳0 / forever
  • 1 MFS Payment Account
  • 1 Android Collector Device
  • 100 Transactions / month
  • 1 Webhook Endpoint
  • 3 Team Members
Get Started Free
Most Popular
Production SaaS Plan

Pro Merchant Monthly

Everything needed to automate high-volume payment matching.
৳990 / month
5 Payment Accounts
10 Android Collectors
50,000 txns / month (Soft)
Real-time Signed Webhooks
15 Team Members
Spatie Roles & Permissions
Full REST API & SDK
24/7 Priority Support
Subscribe Now — ৳990 / month
Developer First

Integrate with Your Website in 5 Minutes

Verify incoming webhooks with standard HMAC-SHA256 signatures. Compatible with Laravel, generic PHP, Node.js, Python, and WordPress.

Replay attack protection with signed timestamp tolerance.
Secret rotation window: old and new secrets both valid.
Idempotent processing with unique event IDs.
PHP / Laravel Webhook Verifier routes/api.php
// Verify MHPay Webhook Signature in Laravel
Route::post('/webhook/mhpay', function (Request $request) {
    $timestamp = $request->header('MHPay-Timestamp');
    $signature = $request->header('MHPay-Signature');
    $secret = config('services.mhpay.secret');

    // Reject replays older than 5 minutes
    if (abs(time() - $timestamp) > 300) {
        abort(401, 'Timestamp expired');
    }

    $expected = hash_hmac('sha256', "{$timestamp}.{$request->getContent()}", $secret);
    if (! hash_equals($expected, $signature)) {
        abort(401, 'Invalid signature');
    }

    $event = $request->json('type');
    if ($event === 'payment.paid') {
        $invoiceRef = $request->json('payload.invoice.reference');
        // Mark your order as paid atomically!
    }

    return response()->json(['status' => 'acknowledged']);
});