BoomPay/partners

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.

WalletPaytm Payment Gateway APIParallel checkout option

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

01

Checkout prepared

Server creates a Paytm transaction token (unchanged) and a BoomPay intent in parallel.

02

Customer chooses

Page shows Paytm's checkout form/button and a separate Boomcoin button.

03

BoomPay path

Customer selects Boomcoin — browser redirects to BoomPay's hosted page.

04

Customer pays

Customer approves from their Boom wallet.

05

Signed return

BoomPay redirects with paymentIntentId and X-Boom-Signature.

06

Confirm

Handler verifies, confirms via getPayment(), notifies merchant.

Code

paytm/prepare-checkout.js
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 */ }
paytm/boompay-return.js
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.