All projects
CupidFaces Live

GymProHub

Multi-tenant SaaS gym management platform built for the Nigerian market

4
Subscription tiers
QR, Biometric, Manual, Mobile
Attendance methods
4 (Termii primary)
SMS gateways
REST + Webhooks
Enterprise API
SaaSMulti-tenantFintechNigeriaCRMPWA

Overview

GymProHub is a gym management SaaS platform built specifically for Nigerian gyms. A gym owner signs up, and gets a complete operations platform: member management, attendance tracking, membership plans, payment collection, staff management, class scheduling, analytics, and a self-service member portal. The platform is multi-tenant and every record is scoped by gym_id, so each gym sees only its own data.

Four subscription tiers serve gyms from solo operators to enterprise chains. Free gives 20 members and 1 staff account with the platform watermark visible and ads shown. Core at 15,000 NGN/month adds 100 members, 3 staff, role-based access control, audit logs, and 50 SMS/month. Portal at 25,000 NGN/month adds 300 members, 5 staff, the self-service member portal at a slug-based subdomain, class scheduling, inventory tracking, white-label branding, and 200 SMS/month. Enterprise at 40,000 NGN/month is unlimited members and staff, plus REST API access with webhooks, custom domain support, SSO, 1,000 SMS/month, predictive analytics, and a dedicated account manager.

Every gym gets its own Paystack subaccount. Members pay into the gym's subaccount and settlement goes directly to the gym's bank account. The platform takes a commission at the transaction level.

The QR check-in page is public-facing. Walk-in visitors scan the gym's QR code, select a day-pass plan, and pay via Paystack. The system automatically creates a day-pass member record. No gym staff intervention needed. The platform is also a PWA: when offline, operations queue up and sync automatically on reconnect.

My Role

  • Designed the product from the ground up: multi-tenant architecture, subscription tier structure, feature gating logic, and the overall gym management workflow
  • Defined what sits at each pricing tier and why: free is genuinely usable to prove value, Core adds the operational features gyms need at scale, Portal adds the member-facing experience, Enterprise adds automation and integration
  • Designed the per-gym Paystack subaccount system: gyms receive payments directly into their own bank accounts rather than waiting for a manual payout from the platform
  • Designed the QR check-in flow for walk-in day-pass payments: no staff involvement, no account required, visitor scans, selects plan, pays, and gets access
  • Designed the white-label branding system for Portal+ gyms: custom logo, primary/secondary/accent colours, custom CSS injection, and hidden GymProHub branding
  • Defined the staff permission model: gym owner, trainer, and receptionist each have different access scopes, all configurable at the RBAC level
  • Designed the PWA offline strategy: operations queue locally and sync to the server on reconnect, so gym staff can check in members even when connectivity drops

Architecture

Single codebase, single database, every table scoped by gym_id. The stack is PHP 8+ with PDO/MySQL 8, no framework, Apache with .htaccess routing. This keeps the stack lean and deployable on standard hosting without a build pipeline.

Paystack integration uses a per-gym subaccount model. When a gym owner sets up payment settings, the platform calls the Paystack API to create a subaccount linked to their bank account. From that point, all member payments go into the subaccount with a commission split processed at the transaction level.

SMS uses Termii as the primary gateway, with Africa's Talking, SMSLive247, and BulkSMS Nigeria as alternatives. Quota varies by tier. Email uses PHPMailer with a custom GymMailer wrapper. QR codes are generated via the chillerlan/php-qrcode library.

The member portal (Portal+ tier) is a PHP SPA accessible at {slug}.gymprohub.fun. Members authenticate separately from gym staff. Custom domain support (Enterprise) uses the same routing logic with a different domain pointer.

The PWA service worker lives at /public/sw.js. It caches member and plan data locally in JSON files per gym. Offline operations queue up in session and are submitted to /api/sync-offline.php on reconnect. Enterprise API endpoints authenticate via SHA256-hashed API keys in the X-API-Key header with rate limiting and full audit logging.

Key Decisions

Per-gym Paystack subaccounts instead of a platform wallet
The alternative was to collect all gym revenue into a platform wallet and run manual payouts. That would have required building payout reconciliation, holding float, and managing the compliance risk of sitting on other people's money. Per-gym subaccounts delegate all of that to Paystack: each gym gets direct settlement into their own bank account, and the platform takes a commission split at the transaction level. The operational overhead is near zero.
QR check-in for walk-ins with self-serve Paystack payment
Walk-in day-pass customers were previously handled manually: a staff member would create a temporary record, take payment however they could, and mark it done. The QR check-in page replaced this entirely. The visitor scans, picks a plan, pays, and a day-pass record is created automatically. Staff focus stays on the gym floor, not on manual admin.
PHP without a framework for deployment simplicity
The target customer is a Nigerian gym owner, most of whom are on shared Namecheap or cPanel hosting. A Laravel or Symfony app with Composer dependencies and build tooling would create deployment complexity that does not exist on shared hosting. Pure PHP with PDO means the app deploys by uploading files. That constraint informed the stack decision.
Free tier that is genuinely usable, not crippled
A free tier designed only to frustrate users into upgrading creates churn, not conversions. Free on GymProHub supports 20 members and 1 staff account with full core functionality. Small gyms can run on it indefinitely. The limits are real: the platform watermark shows, ads appear, and SMS is disabled. But the product works. That means gyms that outgrow Free have already seen the value and the upgrade is a continuation, not a gamble.
PWA offline support as a baseline requirement
Nigerian gym staff cannot rely on consistent internet connectivity. If the check-in system stops working when the connection drops, it creates friction at the front desk during busy periods. The PWA caches what it needs, queues operations locally, and syncs when the connection returns. Staff never need to know or care about connectivity state.

Challenges

Building a product that works for gyms that have nothing digital yet
A lot of the gyms that signed up had no existing system. Member records were in notebooks. Payments were cash only. Attendance was not tracked at all. The product had to be simple enough that a gym owner with no technical background could set it up, add members, and see value within a session. That meant the free tier onboarding flow needed to reach a working state in under 10 minutes with no documentation required.
Per-tenant configuration without a schema migration per gym
Each gym has different payment methods, different SMS preferences, different branding, different Paystack credentials, and different KYC requirements. Storing all of this in the database without creating a migration every time a new configuration option was added required the gym_settings and white_label_settings tables to be flexible enough to absorb new keys without schema changes. JSONB-style configuration columns handled most of this.
Offline sync without conflict resolution complexity
When staff operate offline, they queue check-ins, payments, and member updates locally. When connectivity returns, those operations need to sync without creating duplicate records or overwriting data that changed server-side while the device was offline. The sync strategy was designed to favour local operations for attendance (check-in is time-stamped at the point of action) and surface conflicts for payments rather than auto-resolving them.

Stack & Integrations

PHP 8+MySQL 8Paystack SubaccountsTermii SMSAfrica's TalkingPHPMailerchillerlan/php-qrcodePWA Service WorkerApache + .htaccess