Paytm
Add BoomPay as a Boomcoin option for merchants who accept Paytm: both run independent flows on the same page, resolved through a shared return handler.
Paytm’s payment gateway handles UPI, Paytm Wallet, credit/debit cards, and EMI through its checkout SDK and transaction API. BoomPay sits alongside it as an additional crypto option: Paytm’s SDK handles the Paytm flow unchanged, and BoomPay’s redirect handles Boomcoin. Your existing Paytm integration is untouched.
Flow
Checkout prepared
Server creates a Paytm transaction token (unchanged) and a BoomPay intent in parallel.
Customer chooses
Page shows Paytm's checkout form/button and a separate Boomcoin button.
BoomPay path
Customer selects Boomcoin — browser redirects to BoomPay's hosted page.
Customer pays
Customer approves from their Boom wallet.
Signed return
BoomPay redirects with paymentIntentId and X-Boom-Signature.
Confirm
Handler verifies, confirms via getPayment(), notifies merchant.
Code
const BoomPay = require('boom-pay-sdk');
// For merchants accepting Paytm, surface BoomPay as a parallel crypto option.
// Paytm's gateway handles UPI/wallet/card; BoomPay handles BMC.
async function prepareCheckout(merchant, order) {
const boomPay = new BoomPay({
apiKey: merchant.boompayApiKey,
sandbox: process.env.NODE_ENV !== 'production',
});
// Generate Paytm transaction token as normal -- unchanged.
const paytmToken = await createPaytmOrder(merchant, order);
// BoomPay intent for the Boomcoin option.
const intent = await boomPay.payments.createIntent({
amount: toBmc(order.total, order.currency),
successUrl: `${process.env.PSP_BASE}/boompay/return?status=success&order=${order.id}&mid=${merchant.id}`,
failureUrl: `${process.env.PSP_BASE}/boompay/return?status=failure&order=${order.id}&mid=${merchant.id}`,
label: `${merchant.name} TXN ${order.id}`,
metadata: { orderId: order.id, merchantId: merchant.id },
});
return { paytmToken, boompayLink: intent.link };
}
function toBmc(amount, currency) { return amount; }
async function createPaytmOrder(merchant, order) { /* your existing Paytm initiate transaction code */ }const crypto = require('crypto');
async function handleBoompayReturn(req, res) {
const { order: orderId, mid, status } = req.query;
const intentId = req.query.paymentIntentId;
const signature = (req.query['X-Boom-Signature'] || '').replace(/ /g, '+');
const merchant = await db.getMerchant(mid);
const expected = crypto.createHmac('sha1', merchant.boompayApiKey).update(intentId).digest('base64');
if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature))) return res.status(403).send('Invalid signature');
const boomPay = new BoomPay({ apiKey: merchant.boompayApiKey, sandbox: process.env.NODE_ENV !== 'production' });
const payment = await boomPay.payments.getPayment(intentId);
if (status === 'success' && payment.paidAt) {
await db.markOrderPaid(orderId, { provider: 'boompay', reference: intentId });
await notifyMerchant(merchant, 'PAYMENT_COMPLETE', orderId);
return res.redirect(merchant.successUrl);
}
await db.markOrderFailed(orderId);
res.redirect(merchant.failureUrl);
}Paytm’s transaction verification uses its own checksum API separate from BoomPay’s HMAC-SHA1 signature. These are independent — verify Paytm’s checksum for Paytm transactions, and BoomPay’s signature for BoomPay transactions. Don’t mix them.
Go-live checklist
- Implement
toBmc()with a real INR→BMC conversion rate if your merchants price in INR. - Confirm BoomPay’s hosted page is accessible for users in India — check for any regional network constraints.
- Lock the order once either Paytm or BoomPay flow activates.