Skip to content
Projects
2026 ·Pre-launch ·Featured

Shared accounts and billing

The account platform underneath every product: organisations, a prepaid wallet in taka, subscriptions, API keys and notifications, in a modular monolith built to be split later.

GoPostgreSQLSvelteKit

The problem

Running several products as separate SaaS means separate logins, separate bills and separate security models. It gives a business one account, one set of organisations and one wallet: top up once, switch products on, and each product charges for what it uses, with plain, published prices.

Challenges

Tenant isolation in the database, not the app

Application-level filtering is one forgotten clause away from a data leak. Every organisation-scoped table (more than a hundred of them) has row-level security keyed on the account set for that transaction, and the application role sees zero rows without it. API keys resolve to an account too, so machines get exactly the same isolation as people.

A wallet that cannot go wrong

Money is stored as integers in the smallest unit, and every balance change is a ledger entry. The wallet row is locked for the duration of a debit, so two concurrent charges can never both pass the balance check.

Subscriptions people can predict

The wallet is charged before access is granted, and price and period are copied onto the subscription so a later price change never touches existing customers. Renewals are a sweep over due dates, dated from the due date so a late sweep gives nothing away; a renewal that cannot be paid suspends access rather than deleting anything.

Payments that cannot be replayed

Gateway callbacks are validated against the exact transaction they name, and a payment can leave the pending state only once, so a duplicated or forged callback cannot credit a wallet twice.

Implementation

A monolith with seams

Each product reaches the others only through small interfaces it declares itself, so any product can move into its own service later with only that interface changing. Tokens are already verified through a published key set rather than a shared secret.

Everything a team needs around it

Members and roles, API keys, per-device sessions, an audit log, and a notification bell pushed over WebSockets, built once and shared by every product.

Why this stack

Go
One binary for every product keeps deployment to a handful of machines simple.
PostgreSQL
Row-level security is the tenant boundary, and the same database carries the ledger and the job queue.
SvelteKit
One server-rendered console, marketing site and documentation for every product.

What it does

  • One account and wallet across every product
  • Prepaid balance in taka with a full ledger
  • Predictable subscriptions with dependency rules between products
  • Organisations, roles, API keys and per-device sessions
  • Real-time notifications and an audit log