Webhooks
Payment success webhook
When a payment is verified, TakaPay POSTs to your server URL. Set it in Admin → Stores & API → Webhook URL.
Outbound webhook (TakaPay → your server)
Fired on every payment.verified event. Your endpoint should return 2xx within 8 seconds.
POST → your webhook URL
{
"event": "payment.verified",
"paymentId": "987a15a8-c5d6-4e0d-94c6-523f8db581ee",
"storeId": "store-uuid",
"amount": 1490,
"currency": "BDT",
"provider": "bkash",
"trxId": "BKH8X2K1M",
"payerNumber": "01711111111",
"customerName": "Rafi Hasan",
"customerPhone": "01711111111",
"note": "Order #2041",
"verifiedAt": "2026-08-19T15:00:00.000Z"
}Verify the signature
Every request includes X-TakaPay-Signature — HMAC-SHA256 of the raw request body using your store's Webhook Secret. Always verify before fulfilling.
Node.js
const crypto = require('crypto');
function verifySignature(rawBody, secret, sig) {
const expected = crypto
.createHmac('sha256', secret)
.update(rawBody)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(sig)
);
}
// Express example
app.post('/webhook/status', express.raw({ type: '*/*' }), (req, res) => {
const sig = req.headers['x-takapay-signature'];
if (!verifySignature(req.body, process.env.WEBHOOK_SECRET, sig)) {
return res.status(401).send('Invalid signature');
}
const payload = JSON.parse(req.body.toString());
if (payload.event === 'payment.verified') {
// fulfill order using payload.note or payload.paymentId
}
res.json({ ok: true });
});PHP
$rawBody = file_get_contents('php://input');
$sig = $_SERVER['HTTP_X_TAKAPAY_SIGNATURE'] ?? '';
$secret = getenv('WEBHOOK_SECRET');
$expected = hash_hmac('sha256', $rawBody, $secret);
if (!hash_equals($expected, $sig)) {
http_response_code(401);
exit('Invalid signature');
}
$payload = json_decode($rawBody, true);
if ($payload['event'] === 'payment.verified') {
// fulfill order
}
echo json_encode(['ok' => true]);Inbound webhook (TakaPay Android app → TakaPay server)
The TakaPay Android app reads bKash / Nagad / Rocket SMS receipts and forwards them to TakaPay. This is handled automatically — you don't need to call this.
POST/api/webhooks/takapay
Auth: X-Webhook-Secret (set in Admin → Settings)
payload from Android app
{
"app": "TakaPay",
"provider": "bkash",
"kind": "received",
"trxId": "BKH8X2K1M",
"amount": 1490,
"counterparty": "01711111111",
"receivedAt": "2026-08-19T15:00:00.000Z",
"balance": 5000.00,
"currency": "BDT"
}Local testing
POST/api/webhooks/simulate
Simulate an SMS receipt from the merchant dashboard (Admin → Webhooks → Simulate).
curl (JWT)
curl http://localhost:4000/api/webhooks/simulate \
-H "Authorization: Bearer $JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"provider": "bkash",
"trxId": "TEST1234",
"amount": 1490,
"sender": "01711111111",
"type": "in"
}'