Eliminate manual TrxID verification. Match customer payments in real-time from bKash, Nagad, and Rocket, authoritatively confirm transactions, and trigger signed webhooks instantly.
INV-2026-449 · Ref: verifiedBuilt on pure modular domain logic and tested across 570+ automated checks. Never misrepresents untrusted SMS as bank-confirmed without authoritative verification.
An incoming SMS reaches at most matched status. Invoice settlement requires authoritative API confirmation or audited manual sign-off with dual verification proofs.
Zero floating-point calculation errors. Financial amounts are converted into integer minor units (poisha), supporting Bengali numerals and strict exact-match rules.
Signed HMAC-SHA256 payloads with DNS rebinding protection and private IP filtering. Automatic exponential backoff retries over 24 hours.
Offline-first Room database queue, WorkManager deferred sync, encrypted tokens, and strict sender whitelisting. Zero personal SMS reading.
Strict fail-closed tenant scoping with Spatie role and permission integration. Finance, Developer, Admin, and Auditor roles built in.
Database-level unique constraints and row locks prevent race conditions, duplicate TrxID submissions, and double-allocation to multiple invoices.
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.
// Press "Trigger Simulated Payment" to start the pipeline test...
Start with a free evaluation tier or unlock full capabilities with our single monthly plan. No hidden transaction percentage cut.
Verify incoming webhooks with standard HMAC-SHA256 signatures. Compatible with Laravel, generic PHP, Node.js, Python, and WordPress.
// 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']);
});