Skip to content
Build With Owais
Retail & E-commerce

Kapda Stock: multi-tenant SaaS for India's textile trade

One platform, one database, and a dedicated schema for every shop that signs up.

Kapda Stock product site hero — 'Run your textile shop like it's 2030', with POS billing, GST invoices, inventory, udhaar ledgers and WhatsApp listed as core features
The product site — positioned for Indian textile and clothing businesses, with a workspace ready in under 10 seconds.

The short version

A multi-tenant SaaS platform that runs the day-to-day of textile and clothing businesses across India — POS, GST invoicing, inventory, khata-style credit, WhatsApp and 80mm thermal printing — where every client gets a fully isolated PostgreSQL schema, provisioned automatically in under ten seconds.

Product
Kapda Stock
Sector
Retail & E-commerce
Built with
Next.js 14Node.js + ExpressPostgreSQL + PrismaRedisRazorpayWhatsApp Cloud API

The challenge

Textile shops across J&K and much of India run on paper registers, WhatsApp forwards, and one-off desktop billing software that doesn't understand GST, can't drive the 80mm thermal printer at the counter, has no discipline around khata-style customer credit, ignores UPI, and isn't available in the languages staff actually work in. The cloud alternatives are generic, English-only, and priced for metros.

The approach

I built it as a product, not a project: one platform I operate and sell as a subscription to many independent businesses. The architecture leads with isolation — every client gets their own PostgreSQL schema inside a shared database, so the safe path is also the default path — and the feature set leads with local reality: GST, UPI, thermal receipts, IST dates, and four languages including Urdu and Kashmiri with proper RTL.

What it does

Capabilities shipped

Self-serve signup that provisions a tenant in under 10 seconds

POS billing tuned for a busy counter

GST invoicing, e-invoice (IRN) and e-way bills

Inventory, suppliers, purchase orders and job-work tracking

Khata-style customer credit and ledgers

UPI QR on every invoice and thermal receipt

WhatsApp, SMS and email messaging on the client's own credentials

English, Hindi, Urdu and Kashmiri with RTL layout

A closer look

Inside the product

Kapda Stock features page — the point-of-sale section covering barcode scanning, offline billing with automatic sync, loyalty points and split multi-currency payments
The counter, spelled out: barcode-gun or phone-camera scanning, offline billing that syncs when the connection returns, and every bill printed on 80mm thermal paper with a UPI QR.
Under the hood

The building blocks

01

Platform Console

My Super Admin control plane: client businesses, plans and subscriptions, coupons and vendor referrals, support tickets, backups, health, on-premise licences and a global audit log.

02

Tenant workspace

Each client's own app — POS, inventory, customers and credit, invoices, orders, suppliers, finance, reports, compliance, team and roles.

03

Tenant resolver

Auth → subscription guard → SET search_path to the caller's schema, so every query in a request touches exactly one business's data.

04

Compliance engine

CGST/SGST vs IGST derived from the customer's GSTIN state code, seeded textile HSN codes (5001–6310), e-invoice IRN and e-way-bill validity tracking.

The deep dive

How it actually works

Schema-per-tenant, deliberately

Every client gets their own PostgreSQL schema — biz_XXXXXXXX — inside one shared database, with the public schema reserved for the platform layer. Each authenticated request runs a fixed pipeline: auth decodes the JWT into a user, business, schema and role; a subscription guard blocks suspended or expired accounts; then the tenant resolver sets the search path for that connection. I chose this over a shared table keyed by a business_id column for one reason — in the shared-table design, a single forgotten WHERE clause leaks one business's books to another. With isolation enforced at the connection level, safety is the default rather than a discipline. An automated cross-tenant test proves it: Client A's token asking for Client B's data must return 403, and that test never gets deleted.

Onboarding measured in seconds

Signup is entirely self-serve. Creating a tenant validates the GSTIN, generates a schema name, writes the platform record, creates the schema, migrates it, then seeds it — five RBAC roles, the textile HSN range, invoice templates, product categories — before creating the owner account, setting up recurring billing and sending a welcome message. Deletion is the mirror image: a soft delete with a 30-day retention window before the schema is dropped, so nobody loses their books to a misclick.

Built for the counter, not the demo

GST is handled properly — CGST plus SGST intra-state, IGST inter-state, derived automatically rather than picked from a dropdown. Every invoice carries a UPI deep link rendered as a QR on the PDF and as an ESC/POS QR on the thermal receipt, so GPay, PhonePe, Paytm, BHIM and JKPay all just work. 80mm thermal printing is treated as a must-work path because it is how these shops print. Money is INR-first with export currencies, customer credit follows the khata model shops already run, and every financial record is soft-deleted — an invoice or ledger row is never truly destroyed. Time is stored in UTC, displayed in IST as DD/MM/YYYY, with a single sanctioned date utility so nothing drifts.

Security is the product

Holding many businesses' commercial data in one system makes security a feature rather than a phase. Access tokens are short-lived and kept in memory; refresh tokens rotate, are single-use, and live in HttpOnly, Secure, SameSite=Strict cookies. TOTP 2FA is mandatory for admins, passwords are bcrypt at cost 12, and logins are throttled by IP. Payment keys, bank details and TOTP secrets are AES-256 encrypted at rest; queries are parameterised through Prisma with no raw interpolation; Helmet sets CSP and HSTS; CORS allow-lists are environment-scoped. Plan limits are enforced at the API, never merely hidden in the UI, and four tiers of Redis rate limiting sit in front of it all.

A fix worth writing down: instant logout

While hardening auth I found that signing out revoked the refresh token but not the access token — so a 15-minute access token could keep opening routes after sign-out, from another tab, the back button, or any lingering client. The Super Admin middleware had no revocation check at all. I wired sign-out into the same immediate-revocation mechanism used for account deactivation: on logout the user's live access tokens are revoked in Redis, and both the tenant and Super Admin middleware reject any token minted before that instant. The next request after sign-out returns 401 — everywhere, immediately, not fifteen minutes later — covered by unit tests and a real-PostgreSQL integration test that logs in, signs out, and asserts the old token is refused.

The economics of one platform

The architecture and the business model are the same decision. Because one platform and one database serve every tenant, infrastructure barely moves as clients are added, which is what makes the subscription pricing viable at a target of 1,000 tenant businesses. Usage-based third-party services — WhatsApp, AI calling, payment gateways — run on each client's own provider credentials and are billed to them directly by those providers, so I never resell metered messaging. That keeps the margins clean and the compliance surface small. Alongside the managed cloud edition there is an on-premise licence, sold manually and tracked separately, for shops that want everything on their own hardware. Kapda Stock is designed, architected and built by me, in collaboration with CodeMites.

What I took away

Isolation should be the default, not a discipline — schema-per-tenant means a forgotten filter cannot leak data across businesses. Auth is a lifecycle, not a login; the interesting bugs live in refresh rotation, revocation and sign-out, not the password check. And local reality wins: thermal printing, UPI QR, GST state logic, IST dates and Kashmiri/Urdu RTL aren't extras here, they're the difference between software a shop adopts and software it ignores.

The model

How it's sold

Subscription plans, billed monthly or yearly, with numeric limits enforced at the API — every feature is available on every plan.

Free (Starter)

₹0

1 user · 10 products · 20 invoices a month

Growth

₹2,499/yr

3 users · 500 products · 1,500 invoices a month

Professional

₹4,999/yr

5 users · 10,000 products · 5,000 invoices a month

Enterprise

Talk to sales

Unlimited users, products and invoices

The shift

Before → after

Onboarding

Manual setup → live workspace in seconds

Tenant data

Shared tables → isolated schema per business

The counter

Paper registers → GST billing with UPI + thermal

Start a project

Tell me what you're building

Share a few details and I'll come back within one business day with an honest take, a realistic timeline and a ballpark cost — no pressure, no sales script.

  • Reply within one business day, from me directly
  • Straight answers on scope, timeline and budget
  • Free 30-minute consultation, no obligation

Let's build yours.

Tell me what you're working on. I'll reply within one business day with honest, practical next steps.