All work
B2B SaaS · 2025

Multi-tenant CRM with realtime chat and M-Pesa billing for East Africa.

Edge360 consolidates 4–6 disconnected tools (spreadsheets, email, Slack, separate CRM/billing/support) into a single workspace for B2B service organizations. A multi-tenant platform pairing a React 18 SPA with a Node.js/Express + PostgreSQL backend, layering Socket.IO realtime chat and M-Pesa STK Push billing for the East African market.

Multi-tenant CRM with realtime chat and M-Pesa billing for East Africa.
Tools replaced4–6
  • React 18
  • Node.js · Express
  • PostgreSQL
  • Socket.IO
  • M-Pesa Daraja
  • JWT
  • CryptoJS / bcrypt
— 01 The approach

How we framed it.

Multi-tenancy is enforced at the application layer through organization_id scoping — every prospect, relationship, message, and ticket is filtered by the JWT-resolved org context. A single Postgres database serves every tenant without per-tenant schemas or row-level security, keeping infrastructure simple while maintaining strict logical separation.

— 02 How it works

Inside the build.

Application-layer multi-tenant isolation

Every prospect, relationship, message, target, and ticket is scoped by organization_id. Single Postgres database, isolation enforced at the controller layer — inexpensive infrastructure, strict logical separation, no per-tenant schemas required.

Realtime chat with room targeting

Socket.IO mounted on the same Express HTTP server. (userId, prospectId | relationshipId) tuples key the in-memory presence map; sendMessage dispatches either to a room (broadcast minus sender) or directly to receiver_id (DM).

M-Pesa STK Push pipeline

Daraja OAuth token → STK push → callback persistence → client polling. Raw callback JSON is written to disk before processing — invaluable for debugging payment edge cases and reconciling disputed transactions in a market underserved by Stripe-centric SaaS billing.

Encrypted-transit authentication

Clients AES-encrypt the password before transit using a shared key; the server decrypts then bcrypt-hashes for storage. JWTs in localStorage, per-user single-active-session lock prevents silent account sharing.

Per-tenant pipeline configuration

Each organization stores its own milestones, happiness rating choices, lead sources, services, industries, and currency as Postgres text/jsonb arrays. Tenants customize the entire CRM vocabulary without schema migrations.

— 03 Outcomes

What shipped.

  • Consolidated 4–6 disconnected tools into one workspace
  • Multi-tenant CRM serving every customer from a single Postgres database
  • M-Pesa STK Push subscription billing for the Kenyan / East African market
  • Per-tenant vocabulary customization without backend deployments

Want something like this shipped?

Book a 30-min intro