BB
v1.0 · Current

BroadNet Billing Documentation

Everything you need to deploy, configure and manage your ISP billing system — from first install to running hundreds of customers.

BroadNet Billing is a complete ISP billing and hotspot management platform built for African internet service providers. It automates M-Pesa and Airtel Money payments, manages PPPoE and hotspot customers, monitors MikroTik routers and generates invoices — all in one dashboard.

Quickstart
Get your billing system live in under 30 minutes. Step-by-step from zero to first customer.
Installation
Install on Ubuntu VPS or WSL. Covers Node.js, MySQL, FreeRADIUS and Nginx.
Payments
Configure M-Pesa STK push and Airtel Money USSD for automatic payment collection.
MikroTik Router
Connect and configure your routers for PPPoE and hotspot via the RouterOS API.

Architecture

BroadNet Billing consists of three main components running on your VPS:

architecture
# VPS (public IP)
┌─────────────────────────────────────┐
│  Nginx          :80 / :443          │
│    ↓ proxy_pass                     │
│  Node.js        :3000  (billing API)│
│  MySQL          :3306  (billing DB) │
│  FreeRADIUS     :1812  (auth)       │
│                :1813  (accounting)  │
│                :3799  (CoA)         │
└─────────────────────────────────────┘
         ↕ UDP 1812/1813/3799
┌─────────────────────────────────────┐
│  MikroTik Router  (at ISP site)     │
│  PPPoE server + Hotspot             │
└─────────────────────────────────────┘

Key concepts

ConceptDescription
CustomerAn internet subscriber with a RADIUS username and password. Can be PPPoE or Hotspot type.
PackageA speed + duration plan (e.g. 10 Mbps for 30 days). Controls what RADIUS sends to MikroTik.
RouterA MikroTik device managed via RouterOS API. Receives RADIUS attributes for each customer.
PaymentAn M-Pesa or Airtel Money transaction. On success, activates/renews the customer's account.
SessionAn active RADIUS session — tracks bytes in/out, uptime, NAS IP from accounting packets.
InvoiceAuto-generated PDF for every payment. Can be emailed or downloaded.
Getting started

Quickstart

Get BroadNet Billing running on your VPS in under 30 minutes. This guide assumes Ubuntu 22.04 and a domain name pointed at your server.

Prerequisites

  • VPS — Ubuntu 22.04 LTS, minimum 2GB RAM, 2 vCPU, 40GB SSD
  • Domain — e.g. billing.yourisp.co.ke pointed at your VPS IP
  • Ports open — 22, 80, 443, 1812/UDP, 1813/UDP, 3799/UDP
  • M-Pesa Daraja — sandbox or production app credentials

Step by step

1
Update server and install Node.js
SSH into your VPS and run:
bash
sudo apt update && sudo apt upgrade -y
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs git nginx mysql-server certbot python3-certbot-nginx ufw
node --version  # should show v20.x
2
Clone and configure the app
bash
cd /var/www
sudo git clone https://github.com/yourrepo/isp-billing.git
cd isp-billing
sudo npm install
sudo cp .env.example .env
sudo nano .env   # fill in your DB, M-Pesa, RADIUS values
3
Set up MySQL database
bash
sudo mysql -u root -p
-- In MySQL shell:
CREATE DATABASE isp_billing;
CREATE DATABASE radius;
CREATE USER 'billing'@'localhost' IDENTIFIED BY 'strongpassword';
GRANT ALL ON isp_billing.* TO 'billing'@'localhost';
GRANT ALL ON radius.*      TO 'billing'@'localhost';
FLUSH PRIVILEGES;
EXIT;
4
Install FreeRADIUS and run setup script
bash
sudo apt install -y freeradius freeradius-mysql
# Download and run setup script from admin panel:
# Settings → FreeRADIUS → Download Setup Script
chmod +x setup-freeradius.sh
sudo bash setup-freeradius.sh
5
Start the app with PM2
bash
sudo npm install -g pm2
pm2 start src/app.js --name isp-billing
pm2 startup && pm2 save  # auto-start on reboot
6
Configure Nginx and SSL
nginx
server {
    server_name billing.yourisp.co.ke;

    location / {
        root /var/www/isp-admin/dist;
        try_files $uri /index.html;
    }
    location /api/ {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
    location ~ ^/(hotspot|provision) {
        proxy_pass http://localhost:3000;
    }
}
# Then run:
sudo certbot --nginx -d billing.yourisp.co.ke
7
Open firewall ports
bash
sudo ufw allow 22 && sudo ufw allow 80 && sudo ufw allow 443
sudo ufw allow 1812/udp   # RADIUS auth
sudo ufw allow 1813/udp   # RADIUS accounting
sudo ufw allow 3799/udp   # CoA disconnect
sudo ufw enable
You're live!
Visit https://billing.yourisp.co.ke to access your admin panel. Log in with the default superadmin credentials set in your .env file, then add your first router.

Need help? If you get stuck at any step, check the Troubleshooting guide or contact support at support@broadnetbilling.co.ke

Features

Payments

BroadNet Billing supports M-Pesa (Safaricom Daraja) and Airtel Money. Only one provider can be active at a time. When a payment is confirmed, the customer's account is automatically activated or renewed.

M-Pesa (Safaricom Daraja)

Uses the Daraja Lipa Na M-Pesa Online (STK Push) API. The customer receives a payment prompt on their phone and enters their M-Pesa PIN to confirm.

Configuration

Go to Settings → Payments → M-Pesa Settings and fill in:

FieldWhere to get itExample
Consumer KeySafaricom Developer Portal → your appKu0dqAdnz...
Consumer SecretSafaricom Developer Portal → your appCCZW7l8Wk...
ShortcodeYour M-Pesa paybill or till number174379
PasskeyDaraja portal → Lipa na M-Pesabfb279f9...
Callback URLYour domain (must be HTTPS)https://billing.yourisp.co.ke/api/payments/mpesa/callback

Production requires HTTPS. Safaricom will only POST callbacks to https:// URLs. Use sandbox for local testing, production only after deploying to your VPS with SSL.

Airtel Money

Uses the Airtel Africa Collection API. The customer receives a USSD prompt and enters their Airtel Money PIN. No STK push — the prompt appears automatically on their phone.

Configuration

Go to Settings → Payments → Airtel Settings:

FieldWhere to get it
Client IDdevelopers.airtel.africa → your app → Key Management
Client Secretdevelopers.airtel.africa → your app → Key Management
Callback URLYour domain: https://billing.yourisp.co.ke/api/payments/airtel/callback
CountryKE for Kenya
CurrencyKES for Kenya Shillings

Switching providers

In Settings → Payments, click the card for the provider you want to activate. Only one can be active at a time. All new payments will use the active provider immediately — no restart required.

Payment flow

flow
# Admin-initiated (PPPoE customer)
Admin clicks "Collect Payment"
  → POST /api/payments/initiate
  → M-Pesa STK push / Airtel USSD to customer phone
  → Customer enters PIN
  → Safaricom/Airtel POSTs to callback URL
  → Customer activated, invoice generated, SMS sent

# Customer self-service (Hotspot)
Customer connects to WiFi
  → Redirected to hotspot portal
  → Selects package, enters phone
  → Pays via M-Pesa/Airtel
  → Auto-logged into hotspot
Setup guides

MikroTik Router

Connect your MikroTik router to BroadNet Billing via the RouterOS API. The system auto-configures PPPoE, hotspot, RADIUS and firewall rules through a 3-step wizard.

Router wizard — 3 steps

Step 1: Create router record

In Routers → Add Router, enter:

  • Name — e.g. "Westlands Estate"
  • Service types — PPPoE, Hotspot, or both
  • Ethernet ports — ports to add to the billing bridge (e.g. ether2, ether3)
  • Anti-sharing — enable TTL-based tethering prevention

Step 2: Provision via terminal

Click Generate Command. Copy the one-line command and paste it into your MikroTik terminal (via Winbox or SSH):

The MikroTik fetches a signed script from your server, creates an API user, and calls back with its IP and credentials. The router record updates automatically — you will see it go from Unprovisioned to Provisioned.

The provisioning token expires in 1 hour. If it expires before the MikroTik runs the command, click Generate Command again to get a fresh token.

Step 3: Configure services

Click Configure Services to start the automated setup. A live log streams each step:

  • Creates billing-bridge and assigns gateway IP
  • Adds your ethernet ports to the bridge
  • Sets up DHCP pool (10.10.10.10 – 10.10.10.254)
  • Adds RADIUS server pointing to your VPS
  • Starts PPPoE server on the bridge
  • Uploads hotspot login page and starts hotspot server
  • Applies firewall rules

Network defaults

SettingDefault valueConfigurable
Bridge namebilling-bridgeNo
Bridge gateway10.10.10.1/24Yes — .env
DHCP range10.10.10.10 – 10.10.10.254Yes — .env
RADIUS timeout3 secondsNo
CoA port3799/UDPNo

Requirements

  • RouterOS 6.49+ or 7.x
  • RouterOS API enabled on port 8728
  • MikroTik must be able to reach your VPS on ports 80/443 and 3000
Reference

Environment Variables

All configuration is done through the .env file at the root of the project. Copy .env.example to .env and fill in your values.

Application

VariableRequiredDefaultDescription
APP_PORToptional3000Port the Node.js server listens on
APP_ENVoptionaldevelopmentSet to production on VPS
APP_NAMEoptionalISP BillingUsed in SMS/email messages
JWT_SECRETrequired64-char random hex string for JWT signing
JWT_EXPIRES_INoptional7dAdmin session duration

Database

VariableRequiredDescription
DB_HOSTrequiredMySQL host for billing database
DB_NAMErequiredBilling database name (e.g. isp_billing)
DB_USERrequiredMySQL username
DB_PASSWORDrequiredMySQL password
RADIUS_DB_HOSTrequiredMySQL host for RADIUS database (can be same as DB_HOST)
RADIUS_DB_NAMErequiredRADIUS database name (e.g. radius)
RADIUS_DB_USERrequiredRADIUS DB username
RADIUS_DB_PASSWORDrequiredRADIUS DB password

RADIUS & Provisioning

VariableRequiredDescription
RADIUS_IPrequiredIP of your FreeRADIUS server. Use 127.0.0.1 if on same VPS.
RADIUS_SHARED_SECRETrequiredMust match clients.conf and MikroTik RADIUS config
PROVISION_BASE_URLrequiredPublic URL of your server, e.g. https://billing.yourisp.co.ke/provision
PROVISION_SECRETrequiredJWT secret for signing provisioning tokens

M-Pesa

VariableRequiredDescription
MPESA_CONSUMER_KEYrequiredFrom Safaricom Daraja portal
MPESA_CONSUMER_SECRETrequiredFrom Safaricom Daraja portal
MPESA_SHORTCODErequiredPaybill or till number
MPESA_PASSKEYrequiredLipa Na M-Pesa passkey from Daraja
MPESA_CALLBACK_URLrequiredMust be public HTTPS URL
MPESA_ENVoptionalsandbox or production

Airtel Money

VariableRequiredDescription
AIRTEL_CLIENT_IDrequiredFrom Airtel Developer Portal
AIRTEL_CLIENT_SECRETrequiredFrom Airtel Developer Portal
AIRTEL_CALLBACK_URLrequiredPublic HTTPS URL for payment results
AIRTEL_ENVoptionalsandbox or production
AIRTEL_COUNTRYoptionalKE for Kenya
AIRTEL_CURRENCYoptionalKES for Kenya Shillings

SMS & Email

VariableRequiredDescription
SMS_ENABLEDoptionaltrue or false
AT_USERNAMEoptionalAfrica's Talking username (sandbox for testing)
AT_API_KEYoptionalAfrica's Talking API key
AT_SENDER_IDoptionalBranded sender ID (max 11 chars, must be registered)
EMAIL_ENABLEDoptionaltrue or false
EMAIL_HOSToptionalSMTP server host
EMAIL_PORToptionalSMTP port (587 for TLS)
EMAIL_USERoptionalSMTP username
EMAIL_PASSoptionalSMTP password or app password
Reference

Troubleshooting

Common issues and how to resolve them. If you can't find your issue here, check the server logs with pm2 logs isp-billing or contact support.

MikroTik provisioning

Host is unreachable when running provision command

The MikroTik cannot reach your server. Check in order:

  • Is the server URL correct in PROVISION_BASE_URL? No trailing slash, no extra spaces.
  • Can the MikroTik reach port 80/443? Test: /tool fetch url="https://billing.yourisp.co.ke/health" output=user
  • Is your VPS firewall allowing port 80/443? Run sudo ufw status
  • Is AP isolation enabled on the Wi-Fi the MikroTik is connected to? Disable it on your router.

Provision token expired

Tokens are valid for 1 hour. Click Generate Command again in the admin panel to get a fresh token.

FreeRADIUS

FreeRADIUS fails to start — unknown module rest

bash
sudo rm -f /etc/freeradius/3.0/mods-enabled/rest
sudo service freeradius restart

Too many keys — MySQL error on startup

Sequelize's alter: true has added duplicate indexes. Fix in MySQL:

sql
-- Find duplicate indexes
SELECT TABLE_NAME, INDEX_NAME, COUNT(*)
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = 'isp_billing'
GROUP BY TABLE_NAME, INDEX_NAME
HAVING COUNT(*) > 1;

-- Drop duplicates (example)
ALTER TABLE Settings DROP INDEX settings_category_key_2;

Then set APP_ENV=production in .env to prevent alter: true running again.

MikroTik: UNKNOWNREPLY !empty error

This is normal — RouterOS returns !empty for commands that succeed but return no data (like set commands). It is handled as a success automatically in the current version. If you see it, update mikrotikService.js to the latest version.

Payments

M-Pesa callback not received

  • Callback URL must be HTTPS — Safaricom does not call HTTP endpoints in production
  • URL must be publicly accessible — test with curl https://billing.yourisp.co.ke/api/payments/mpesa/callback from any machine
  • Check Safaricom Daraja portal for delivery logs
  • Check your logs: pm2 logs isp-billing | grep "M-Pesa callback"

STK push sent but customer not activated

The callback was not received or payment failed. Check:

  • Payment record in admin panel — look at status field (pending/completed/failed)
  • If status is pending after 2 minutes, Safaricom callback failed — check callback URL
  • If status is failed, customer cancelled or had insufficient funds

Hotspot portal

Portal loads but "network connection error"

The hotspot client cannot reach port 3000. Add it to the walled garden:

routeros
/ip/hotspot/walled-garden/ip/add action=accept dst-address=YOUR_SERVER_IP
/ip/hotspot/walled-garden/ip/add action=accept protocol=tcp dst-port=3000

Or better — run your app on port 80 so walled garden rules are not needed. Set APP_PORT=80 and update Nginx.

Getting logs

bash
# Live app logs
pm2 logs isp-billing

# FreeRADIUS debug mode (shows every auth attempt)
sudo pkill -9 freeradius && sudo freeradius -X

# Nginx error log
sudo tail -f /var/log/nginx/error.log

# MySQL slow queries
sudo tail -f /var/log/mysql/error.log
Requirements

Coming soon.

Installation

Coming soon.

FreeRADIUS Setup

Coming soon.

VPS Deployment

Coming soon.

Customers

Coming soon.

Packages & Plans

Coming soon.

Hotspot Portal

Coming soon.

Invoices

Coming soon.

Notifications

Coming soon.

Payment Providers

Coming soon.

SMS & Email

Coming soon.

RADIUS Config

Coming soon.

Subscription Plans

Coming soon.

Migration Guide

Coming soon.

API Reference

Coming soon.