BoomPay/partners

Fortumo

Surface BoomPay as an alternative when carrier billing isn't available: Fortumo handles the carrier billing path, BoomPay handles Boomcoin, giving customers a fallback that doesn't require a phone bill.

Carrier BillingFortumo Payment APIFallback alternative

Fortumo’s carrier billing model works when a customer has a compatible SIM and sufficient prepaid credit or a postpaid plan — but there are always customers for whom carrier billing isn’t available, either due to their carrier, their balance, or their region. BoomPay fills that gap as a parallel checkout option: if Fortumo can’t initiate a carrier charge, your platform presents BoomPay’s Boomcoin redirect as an alternative. No Fortumo-side changes are needed.

Flow

01

Availability checked

Your server checks whether Fortumo carrier billing is available for this customer and device.

02

Options presented

If carrier billing is available, show both options. If not, show only BoomPay.

03

Customer pays via BoomPay

Customer clicks the Boomcoin option — browser redirects to BoomPay's hosted page.

04

Customer approves

Customer pays from their Boom wallet.

05

Signed return

BoomPay redirects with paymentIntentId and X-Boom-Signature.

06

Confirm

Your handler verifies, confirms via getPayment(), notifies merchant, and fulfils the digital good.

Code

fortumo/prepare-checkout.js
const BoomPay = require('boom-pay-sdk');

// Fortumo handles carrier billing for digital goods. BoomPay is offered
// as a fallback/alternative when the customer doesn't have carrier billing
// available (e.g. prepaid SIM with insufficient credit, or a device where
// Fortumo can't initiate a carrier charge).
async function prepareCheckout(merchant, order, carrierInfo) {
  const boomPay = new BoomPay({
    apiKey: merchant.boompayApiKey,
    sandbox: process.env.NODE_ENV !== 'production',
  });

  const intent = await boomPay.payments.createIntent({
    amount: toBmc(order.price, 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} — ${order.productName}`,
    metadata: { orderId: order.id, merchantId: merchant.id },
  });

  const fortumoPossible = await checkFortumoAvailability(carrierInfo);

  return {
    fortumoAvailable: fortumoPossible,
    fortumoPaymentToken: fortumoPossible ? await createFortumoPayment(merchant, order) : null,
    boompayLink: intent.link, // always available as an alternative
  };
}

function toBmc(amount, currency) { return amount; }
async function checkFortumoAvailability(carrierInfo) { /* check if carrier billing is possible */ }
async function createFortumoPayment(merchant, order) { /* your existing Fortumo payment initiation */ }
fortumo/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);
}
i

Fortumo is primarily used for digital goods (games, apps, content). BoomPay settles in BMC — confirm your merchants understand that Boomcoin is a cryptocurrency settlement, separate from and not convertible to carrier billing revenue, before enabling both options together.

Go-live checklist

  • Implement toBmc() with a real conversion rate — Fortumo prices are typically in local currency.
  • Decide your presentation logic: always show BoomPay alongside carrier billing, or only as a fallback when carrier billing is unavailable.
  • Confirm digital good delivery is triggered from your BoomPay return handler, not just the Fortumo callback.