MenuPay.Integrate bKash, Nagad & Rocket checkout into your site in under 5 minutes.
https://your-domain.com/apiGo to Dashboard → API Keys and generate a key pair. You will receive:
pk_live_xxxxxxxxxxxxxxxxxxxxSafe to expose in frontend / checkout embeds.
sk_live_xxxxxxxxxxxxxxxxxxxxServer-side only. Never expose in frontend code.
Your backend calls initiate with secret key to get a checkout URL.
Redirect customer to the returned checkout_url.
Customer selects bKash / Nagad / Rocket and completes payment.
MenuPay posts a signed callback to your callback_url.
https://your-domain.com/api/payment/initiateCreate a new checkout session. Returns checkout_url to redirect customer.
https://your-domain.com/api/payment/status?id=:payment_idCheck the current status of any payment session.
https://your-domain.com/api/payment/verifyManually verify a customer-submitted TxnID against a payment session.
After a successful payment, MenuPay sends a signed HTTP POST to your callback_url. Verify the signature in the header before trusting the payload.
x-menupay-signature// Webhook Verification (NodeJS / Express / Next.js API Route)
import crypto from 'crypto';
export async function POST(req: Request) {
const body = await req.json();
const signature = req.headers.get('x-menupay-signature') ?? '';
const webhookSecret = process.env.MENUPAY_WEBHOOK_SECRET!;
// Generate local HMAC SHA256 signature
const localSignature = crypto
.createHmac('sha256', webhookSecret)
.update(JSON.stringify(body))
.digest('hex');
// Constant-time comparison to prevent timing attacks
const isValid = crypto.timingSafeEqual(
Buffer.from(localSignature, 'utf-8'),
Buffer.from(signature, 'utf-8')
);
if (!isValid) {
return Response.json({ error: 'Invalid signature' }, { status: 401 });
}
// Process the event
const { event, payment_id, status, amount, reference } = body;
if (event === 'payment.success') {
// Mark the order as paid in your database
await markOrderPaid(reference, payment_id);
}
return Response.json({ received: true });
}// Initiate Payment (NodeJS / Fetch API)
const initiatePayment = async () => {
const response = await fetch('https://your-domain.com/api/payment/initiate', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer sk_live_your_secret_key_here'
},
body: JSON.stringify({
amount: 1250.00,
currency: 'BDT',
reference: 'inv_982711',
customer_name: 'Rahat Kabir',
customer_phone: '01729112233',
customer_email: 'rahat@gmail.com',
success_url: 'https://yoursite.com/success',
cancel_url: 'https://yoursite.com/cancel',
callback_url: 'https://yoursite.com/api/webhook'
})
});
const data = await response.json();
if (data.success) {
// Redirect customer to the hosted checkout page
window.location.href = data.checkout_url;
} else {
console.error('Initiation failed:', data.error);
}
};{
"success": true,
"payment_id": "pay_cfbc4c4be67f39",
"checkout_url": "https://your-domain.com/checkout/pay_cfbc4c4b...",
"amount": 1250.00,
"currency": "BDT",
"reference": "inv_982711",
"expires_at": "2026-06-04T20:00:00Z"
}{
"success": false,
"error": "Invalid or missing API secret key"
}{
"event": "payment.success",
"payment_id": "pay_cfbc4c4be67f39",
"reference": "inv_982711",
"amount": 1250.00,
"currency": "BDT",
"gateway": "bkash",
"txn_id": "8K2ML9P8D1",
"status": "completed",
"timestamp": "2026-06-04T19:55:22Z"
}