SaaS en Abonnementen

Van idee tot
schaalbaar product.

Wij bouwen SaaS-producten die groeien. Multi-tenant, abonnementsgestuurd en klaar voor honderden klanten.

Starter

5 gebruikers
1 GB opslag
E-mail support
Populairste

Pro

25 gebruikers
10 GB opslag
Priority support
API toegang

Enterprise

Onbeperkt
Dedicated server
SLA en compliance
MRR Groei 12 maanden
Start Nu
MRR +340% Churn < 2% NPS 72

Isolatie is geen feature, het is de architectuur.

Veel SaaS-projecten beginnen met "multi-tenant" als checkbox en ontdekken een half jaar later dat elke nieuwe feature een extra vergeten tenant-check bleek te bevatten. Een data-leak is dan niet ver weg. De juiste aanpak is omgekeerd: tenant-bewustzijn zit op het laagste niveau, zodat ontwikkelaars niet eens de kans krijgen om scoping per ongeluk te vergeten.

Wij bouwen SaaS-platforms waarin tenant-ID zo diep in de querybuilder zit dat een vergeten where onmogelijk is. Policies controleren elke mutatie tegen de actieve tenant. Bestandsdownloads lopen via signed URLs die niet zomaar uit te wisselen zijn tussen tenants. Cross-tenant toegang retourneert een 404, bestaan van andermans data mag niet eens lekken.

Daarbovenop komt waar klanten écht om vragen: custom domains, white-label branding, per-tenant billing en een onboarding-flow die ofwel in vijf minuten zelfvoorzienend is, ofwel past in je verkoopproces. Laravel en Filament vormen daarvoor een stack die we op de detailniveaus kennen.

// wat_we_bouwen

Wat we bouwen

De bouwstenen van een SaaS-platform dat met je klantenbestand meeschaalt.

Multi-tenancy

Elke klant zijn eigen afgeschermde omgeving, één applicatie, honderden klanten.

Filament::tenant(Organization::class);

Abonnementsbeheer

Mollie of Stripe ingebouwd. Upgrades, downgrades en facturen automatisch.

Onboarding flow

Nieuwe klanten in 3 stappen actief, geen handmatig werk.

Usage-based billing

Factureer op gebruik. API-calls, gebruikers, opslag, wat bij jou past.

Tenant-scoping op query-niveau

Global scopes op elk Eloquent-model, een tenant-middleware die op elk request de context zet, en policies die tegen die context valideren. Scoping overslaan is structureel onmogelijk.

Custom domains en white-label

Subdomeinen én volledige custom domains met automatische SSL. Per-tenant logo, kleuren en e-mailsjablonen.

Admin en klant apart

Twee Filament-panels: eentje voor je interne team (ziet alle tenants), eentje voor eindgebruikers (ziet alleen hun eigen tenant). Verschillende rollen, verschillende UI.

Security by default

Row-level security op Postgres, signed URLs voor downloads, APP_KEY-rotatie zonder downtime. Cross-tenant pogingen leveren altijd een 404 op, geen hint over andermans data.

// aanpak

Zo werken we

01

Business model

Pricing-strategie, doelgroep en feature-tiers leggen we samen vast voordat er code wordt geschreven. Welk segment betaalt voor welke feature, welke usage telt mee, waar zitten de tier-grenzen.

02

Tenant-architectuur

Tenant-resolver, scoping-strategie, isolatie. Shared schema, database-per-tenant of hybride, vastgelegd vanuit compliance- en volume-eisen, niet vanuit voorkeur.

03

Bouw met tenant-tests

Elke feature krijgt expliciete cross-tenant tests in CI. De build faalt als een query tenant-scoping mist, dus een vergeten where wordt nooit een productie-incident.

04

Provisioning en launch

Onboarding-flow, admin-tooling voor support, monitoring per tenant. We onboarden je eerste klanten samen, daarna rolt het breder uit.

// stack

Waarmee we werken

Een stack die we op productie hebben staan, inclusief de foutafhandeling.

Platform en multi-tenancy

  • Laravel (PHP 8.4)
  • Filament 5 voor admin en portal
  • Livewire 3 waar interactief
  • Tenancy for Laravel + subdomain routing
  • Custom domains met automatische SSL

Billing en data

  • Stripe en Mollie subscriptions
  • Laravel Cashier waar passend
  • PostgreSQL met row-level security
  • Redis voor cache, sessions en queues
  • Laravel Horizon voor jobs

Infra en observability

  • AWS Route53 + ACM voor SSL
  • Cloudflare voor wildcard-domains
  • Sentry voor errors en releases
  • Per-tenant metrics in Grafana
  • GitHub Actions CI/CD
// scenarios

Hoe dit er in de praktijk uitziet

Branchespecifieke SaaS voor een niche

Een ondernemer in de uitzendbranche wilde zijn interne urenregistratie-tool als SaaS aanbieden aan concullega's. Wij bouwden een multi-tenant platform waarin elk uitzendbureau zijn eigen omgeving kreeg onder een custom subdomein, met eigen logo, huisstijl en rapportage-sjablonen. Provisioning is self-service: na aanmelding en iDEAL-betaling is een nieuw bureau binnen tien minuten actief. Na achttien maanden zitten er ruim zestig tenants op de stack, zonder aparte codebase per klant.

Holding met meerdere werkmaatschappijen

Een holding met zes dochterondernemingen wilde één intern platform voor projectadministratie, maar met strikte scheiding tussen de entiteiten. Financiële data mag niet tussen maatschappijen heen en weer. Wij zetten een shared-schema multi-tenant op, waarbij elke werkmaatschappij een tenant is en de holding-directie via een overkoepelend admin-panel kpi's ziet zonder dossier-details. Eén codebase, zes werkelijkheden.

Agency die portalen beheert voor haar klanten

Een marketingbureau beheerde voor veertig klanten elk een apart WordPress-portaal. Onderhoud en uitrol van nieuwe features werd een nachtmerrie. Wij herbouwden het als één multi-tenant Laravel-applicatie met custom domains per klant. Eén release rolt uit naar alle veertig klanten tegelijk, maar elke klant ziet zijn eigen branding, eigen content en eigen gebruikers, watertight gescheiden.

Veelgestelde vragen

Shared schema of database-per-tenant, wat kiezen jullie?
Dat hangt af van het aantal tenants en de isolatie-eisen. Tot ruwweg een paar duizend tenants werkt shared schema (één database, tenant_id-kolom, scoped queries) prima: goedkoop, makkelijk te backuppen, snel te migreren. Bij strenge compliance-eisen, medisch, juridisch, of klanten die het contractueel afdwingen, gaan we naar database-per-tenant, of een hybride waarbij gevoelige data apart staat. We leggen de keuze vast in de architectuurfase, niet achteraf.
Hoe voorkomen jullie dat tenant A data van tenant B ziet?
Drie verdedigingslinies. Eén: een tenant-middleware bepaalt op elk request welke tenant actief is en zet die in de querybuilder via global scopes, ontwikkelaars kunnen scoping niet per ongeluk vergeten. Twee: policies controleren elke mutatie tegen de actieve tenant. Drie: cross-tenant toegangspogingen leveren een 404 op, geen 403, existence-leaks zijn óók leaks. Dit wordt gedekt door geautomatiseerde tests die per release draaien.
Kunnen klanten een eigen domein krijgen?
Ja. We ondersteunen zowel subdomeinen (klant1.uwplatform.nl, klant2.uwplatform.nl) als volledige custom domains (portal.klantnaam.nl). Voor white-label werken we met per-tenant branding: logo, kleuren, favicon en e-mailsjablonen. SSL-certificaten regelen we automatisch via Let's Encrypt of AWS ACM, en de tenant-resolver kijkt naar de hostnaam om de juiste context te laden.
Hoe werkt billing per tenant?
We integreren standaard met Stripe of Mollie. Elk tenant-account is gekoppeld aan een customer, met abonnementen op basis van seats, features of usage. Upgrades, downgrades, pro-rated facturen en failed-payment retries lopen automatisch. Voor bedrijfsklanten met handmatige facturatie bieden we een tweede flow die aansluit op je boekhoudpakket, ook dat is geen uitzondering.
Wat gebeurt er als een nieuwe klant aan boord komt?
Dat hangt af van je verkoopproces. Volledig self-service (klant vult formulier in, betaalt, en is binnen vijf minuten live) kan, de provisioning-pipeline maakt dan de tenant aan, seeds basis-configuratie, stuurt een welkomsmail en zet de eerste gebruiker klaar. Voor B2B-klanten met onboarding-gesprekken doen we het vaak andersom: je maakt de tenant aan in een admin-paneel, klant krijgt een uitnodiging met inloglink.
Wat als één tenant heel hard groeit?
Dat is een luxeprobleem dat we voorzien. Indexes en queries worden per tenant-size regelmatig geprofileerd. Bij echt grote tenants kunnen we die fysiek op een eigen database plaatsen zonder dat de applicatiecode verandert, dat is de grote winst van een goed opgezette tenant-resolver. Als het nog verder schaalt, kunnen zware tenants hun eigen worker-pool en queue-kanaal krijgen, zodat ze andere tenants niet vertragen.
+ + + +

// volgende_stap.execute()

SaaS-product laten bouwen?

Vertel waar je product over gaat en voor wie. Wij mappen de tenant-architectuur, billing-flow en provisioning, en geven een concrete fasering terug.