metadata
title: WifiBiz
emoji: 📡
colorFrom: blue
colorTo: indigo
sdk: docker
app_port: 7860
pinned: false
WifiBiz — Multi-Tenant WiFi Hotspot Platform
A backend platform for selling WiFi access via captive portals. Built for small businesses (hotels, restaurants, shops) to monetize their internet connection.
Features
- Captive portal with M-Pesa payment integration (Snippe)
- Per-device WiFi plans with speed limits
- Omada SDN controller integration for client authorization
- Tenant dashboard API (devices, plans, sessions, payouts)
- Super admin panel
- SMS notifications via Android SMS Gateway
- Auto-renew, billing reminders, and session management
Stack
- Runtime: Node.js 20 + Express
- Database: MariaDB (persisted to
/datavolume) - Payments: Snippe (M-Pesa STK Push)
- WiFi Controller: TP-Link Omada SDN
Environment Variables
Set these in Space Settings → Variables and secrets:
| Variable | Description |
|---|---|
JWT_SECRET |
Long random string for tenant JWT signing |
JWT_ADMIN_SECRET |
Long random string for admin JWT signing |
PAYMENT_CREDENTIAL_SECRET |
Long random string used to encrypt tenant-owned payment provider secrets |
ADMIN_TOKEN |
Static bearer token for admin endpoints |
OMADA_URL |
Omada controller URL (e.g. https://1.2.3.4:8043) |
OMADA_USER |
Omada admin username |
OMADA_PASS |
Omada admin password |
SNIPPE_API_KEY |
Snippe live API key |
SNIPPE_WEBHOOK_SECRET |
Snippe webhook signing secret |
SMS_GATEWAY_URL |
Android SMS Gateway endpoint |
SMS_GATEWAY_USER |
SMS gateway username |
SMS_GATEWAY_PASS |
SMS gateway password |
PORTAL_HOST |
Public hostname of this Space (e.g. mbonea-wifibiz.hf.space) |
PORTAL_SCHEME |
https |
DB_NAME |
wifiplatform |
DB_USER |
wifiuser |
DB_PASS |
A strong password for the MariaDB user |
DATA_ROOT |
Persistent data root for this Space, e.g. /data/wifiplatform for production or /data/wifiplatform-v2 for staging |
RESTORE_SQL_PATH |
Optional first-run SQL dump path to restore instead of loading schema.sql |
Cloning Production Data for a v2 Space
Do not run two Spaces against the same MariaDB directory. Use a different DATA_ROOT per Space:
# Production Space
DATA_ROOT=/data/wifiplatform
DB_NAME=wifiplatform
# v2/Staging Space
DATA_ROOT=/data/wifiplatform-v2
DB_NAME=wifiplatform
RESTORE_SQL_PATH=/data/wifiplatform_backup.sql
Create the dump from production while production MariaDB is running:
mysqldump -u "$DB_USER" -p"$DB_PASS" "$DB_NAME" > /data/wifiplatform_backup.sql
Then start the v2 Space. On its first run, entrypoint.sh initializes /data/wifiplatform-v2/mysql and restores RESTORE_SQL_PATH.