In het kort
- Vraag
- Een opleidingspraktijk had een platform nodig voor activiteiten met reeksen en opties, inschrijvingen in meerdere talen, betalingen en facturen.
- Aanpak
- Ik breng in kaart wat de praktijk nodig heeft, ontwerp en bouw het platform, en beheer het sinds 2015.
- Opgeleverd
- Een eigen platform met inschrijvingen, online betalen via Mollie, facturen klaar voor Peppol, cadeaukaarten, online cursussen en een site in vijf talen.
De context
Hilde Van Bulck is opleider en coach. Ze geeft familieopstellingen in workshops, reeksen en online cursussen. Sinds 2015 ben ik de enige technische partner van haar praktijk, Samtati: ik breng in kaart wat ze nodig heeft, beslis wat we bouwen en in welke volgorde, en bouw en beheer het.
Van WordPress naar een eigen platform
De eerste jaren draaide de site op WordPress, een tijd met een webshop in WooCommerce, en daarna op Squarespace. Voor wat de praktijk nodig had, schoot dat tekort: activiteiten met reeksen, dagen en opties, inschrijvingen in meerdere talen, facturen. Vanaf 2019 bouwde ik daarom een eigen platform in PHP, en in 2020 ging het live op hildevanbulck.com (opent in een nieuw venster), met accounts en in drie talen. Sindsdien groeit het mee met de praktijk: inschrijven en betalen via Mollie, facturen en kortingscodes, pagina’s die Hilde zelf bewerkt, en later cadeaukaarten, online cursussen en vijf talen.
Activiteiten: het hart van de praktijk
Het grootste deel van de praktijk draait om activiteiten: workshops, reeksen en opleidingsdagen. Een activiteit is meer dan een datum met een prijs. Ze heeft reeksen met dagen, drie manieren om te prijzen (per dag, per dag met twee tarieven, of één prijs voor de hele reeks), opties met een eigen btw-tarief, kortingen en een voertaal, en dat alles in vijf talen.
Dat moest ik eerst als datamodel uittekenen, zodat één bron van waarheid overal doorwerkt. Uit dat ene record bouwt de site de activiteitenpagina, de agenda, het menu, het aanbod, de sitemap en de gestructureerde gegevens voor zoekmachines (schema.org/Event). Of een activiteit boekbaar, volzet of al gestart is, leidt het platform er zelf uit af. Hilde past iets aan op één plek, en het klopt overal.
Hilde bewerkt de pagina zelf
De tekst, foto’s en video’s van een activiteitenpagina past Hilde aan op de live pagina zelf, niet in kleine vakjes van een beheeromgeving. Ze ziet meteen wat bezoekers zullen zien. Dat kom je weinig tegen buiten platformen als Squarespace, en het maakt het werk voor haar veel aangenamer.
Om dat te bouwen, zette ik een editor in de pagina die enkel voor beheerders laadt: bezoekers krijgen gewone HTML. Een schakelaar wisselt tussen bewerken en bekijken als bezoeker, en wie de pagina verlaat met onbewaarde tekst, krijgt eerst een vraag. Een foto die Hilde in de tekst sleept, gaat meteen naar de server, wordt gecontroleerd, verkleind en als WebP geleverd. Wat uit Word geplakt wordt, wordt opgeschoond. En wie een pagina in een andere taal bewerkt, maakt er een eigen vertaling van, die de automatische vertaling nooit meer overschrijft.
Inschrijven en betalen
Inschrijven gaat in drie genummerde stappen: data kiezen, opties kiezen en gegevens invullen, met ernaast een overzicht dat live meerekent. Wie nog niet aangemeld is, meldt zich tussendoor aan, en de keuzes blijven bewaard. De server vertrouwt niets van wat de browser stuurt: hij herleidt elke keuze tot de activiteit zelf, rekent de prijs opnieuw uit en weigert een inschrijving als de reeks intussen veranderde. Kortingscodes, vroegboekkortingen en cadeaukaarten worden opnieuw gecontroleerd.
Betalen loopt via een integratie met de API van Mollie. De site maakt de betaling aan, stuurt de bezoeker door, en verneemt de uitkomst langs twee wegen: de bezoeker die terugkeert en een melding van Mollie. Elke betaling wordt precies één keer verwerkt, ook als beide tegelijk binnenkomen. Bedragen rekent het platform in centen, als gehele getallen, met één prijsmodule voor de site en het beheer: de prijs die je ziet, is de prijs die je betaalt, met de btw per tarief.
Facturen en creditnota’s volgen een doorlopende nummering, terugbetalingen lopen mee, en het platform zet elke factuur klaar voor e-facturatie via Peppol. Elk kwartaal maakt het een bestand voor de boekhouder.
Cadeaukaarten
Een cadeaukaart lijkt eenvoudig, tot je ze bouwt. Ze moet in stukken te gebruiken zijn, tot op de cent, en twee mensen die tegelijk afrekenen, mogen hetzelfde saldo niet twee keer gebruiken. Daarom reserveert het platform het bedrag in één transactie in de databank, houdt het vast zolang de betaling loopt, en geeft het terug als die mislukt of terugbetaald wordt.
Ik ontwierp de codes zo dat je ze goed leest (zonder tekens die op elkaar lijken) en toch niet kunt raden, en wie probeert, wordt na enkele pogingen geblokkeerd. Een kaart kan op een gekozen dag per mail vertrekken, zonder aparte planner. En samen met de boekhouder vertaalde ik de btw-regels voor waardebonnen naar code, tot in de export van elk kwartaal.
Online cursussen
Naast de activiteiten bouwde ik een leerplatform. Een cursus bestaat uit modules en lessen met tekst, video, audio, vragen en oefeningen. De toegang volgt de betaling: na een terugbetaling sluit de cursus vanzelf. Een traject bundelt cursussen in één bestelling, en wie er al een heeft, betaalt een persoonlijke prijs naar verhouding.
Wat het werk vroeg, zit in de details. Antwoorden van deelnemers blijven bij hun vraag, ook als Hilde vragen toevoegt of verschuift, en ze worden bewaard terwijl je typt. Video’s staan achter ondertekende links die na enkele uren vervallen. Audio streamt het platform zelf, zodat je kunt springen, en de luisterpositie wordt op de server bewaard: je luistert verder op een ander toestel. En wie zijn gegevens opvraagt of zijn profiel wist, krijgt ook die antwoorden mee of kwijt.
Bij de lessen horen interactieve oefeningen. Elke oefening is één eigen motor in SVG en JavaScript, zonder bibliotheek, die in een les, in een werkboek en op volledig scherm werkt, zodat Hilde er ook live mee kan werken. Slepen en draaien kan ook met het toetsenbord.
Aanmelden zonder wachtwoord
Deelnemers melden zich aan met een code van zes cijfers die ze per mail krijgen, of met een passkey. Voor de code moest ik zelf de veiligheid bouwen: de code wordt enkel versleuteld bewaard, vervalt na een kwartier, en pogingen en nieuwe codes zijn beperkt per adres en per toestel.
Voor passkeys bouwde ik op een bewezen bibliotheek voor WebAuthn, met eigen controles erbovenop, want de details maken het verschil: uitdagingen die maar één keer gelden, een strikte controle van de herkomst, en enkel de publieke sleutel op de server. Tests sturen een echte browser met een nagebootste authenticator en bewijzen dat aanvallen afketsen: een opnieuw afgespeeld antwoord, een gewijzigde handtekening, een vreemde uitdaging en een ontbrekend CSRF-token.
Vijf talen
De site bestaat in het Nederlands, Engels, Frans, Duits en Spaans, elk met eigen adressen, vertaalde URL's en de juiste hreflang voor zoekmachines. Een taal toevoegen is een map toevoegen; de code kent geen taal bij naam, behalve de bron.
Elke dag vertaalt AI wat nieuw of gewijzigd is, maar daar zitten waarborgen omheen die ik zelf bouwde. Een vingerafdruk van de tekst zorgt dat niets twee keer vertaald wordt. Afbeeldingen, video en code gaan er vooraf uit en komen achteraf terug. Een vertaling waarin de opmaak verandert, wordt geweigerd. En Hildes eigen vertaling gaat altijd voor.
Een beheeromgeving voor de telefoon
Hilde beheert haar praktijk vaak vanop haar telefoon. Daarom bouwde ik de beheeromgeving zo dat ze op een scherm van 390 pixels werkt: een tabel die niet past, wordt vanzelf een kaartje per rij. Een test opent elke soort beheerpagina op die breedte en faalt als er één opzij scrolt.
Elke e-mail van het platform is daar na te kijken, in elke taal, op een desktop- of telefoonbreedte. En als de gewone verzending faalt, vertrekt dezelfde mail langs een tweede weg, zodat een bevestiging nooit zomaar verloren gaat.
Zien wat er misloopt
Een platform dat geld en inschrijvingen verwerkt, moet je kunnen opvolgen. Daarom bouwde ik een eigen logboek. Fouten worden gegroepeerd tot één regel per probleem, en e-mailadressen en IP-adressen worden gemaskeerd. Wat bezoekers of geld raakt, mailt me meteen, hoogstens één keer per uur.
Elke week schrijft AI er een verslag van, met enkel leesrechten en opgeschoond, want logs komen deels van vreemden. Dat helpt enorm, maar het vervangt het werk niet: ik lees het verslag, bekijk de problemen in het beheer, los ze op en vink ze af. Opvolgen blijft mensenwerk, en het vraagt tijd.
Veilig en getest
Het platform draait in Docker bij DigitalOcean, achter Cloudflare, met een beheerde MySQL-databank en elke nacht een back-up naar een andere regio. Uit de logs stelde ik een eigen regel bij Cloudflare op tegen scanners die naar bekende zwakke plekken zoeken. Wat erdoor raakt, krijgt een kale 404 voordat er een sessie of databank geladen wordt.
Achter dat alles staan unittests en end-to-endtests. Die laatste sturen een echte browser door inschrijven, betalen, cursussen, trajecten en cadeaukaarten, tegen de testmodus van Mollie en nooit tegen productie, en ruimen hun testgegevens daarna zelf op.
Hoe ik bouw
Het platform draait op een eigen lichte basis in PHP, zonder extern framework: een router per taal, views, vertalingen en een datalaag. Jarenlang bouwde ik alles alleen: het datamodel van de activiteiten, de koppeling met Mollie, facturen en creditnota’s, het bewerken op de pagina, de verhuis naar Docker en de cloud, en de voorbereiding op Peppol.
Sinds 2026 werk ik met een AI-codeerassistent als bouwpartner. Daarmee frisste ik de site en de beheeromgeving op en moderniseerde ik ze, op dezelfde basis en bovenop wat er al stond, en kwamen er cadeaukaarten, het leerplatform, passkeys en vijf talen bij. De AI helpt enorm, maar ik bepaal wat er gebouwd wordt en in welke volgorde, schrijf de analyse en de regels uit, en review en test elke wijziging. De documentatie groeide mee, tot een uitgebreide handleiding.
Waarom dit telt
Zo lang voor dezelfde klant werken betekent leven met je eigen beslissingen. Het platform groeide van een inschrijvingsformulier uit tot de ruggengraat van de praktijk, en elke stap bouwde voort op de vorige.


