Jorick Michiels

Samtati

Sinds 2015 het platform achter een opleidingspraktijk

Een eigen platform voor de praktijk van Hilde Van Bulck: activiteiten en inschrijvingen, betalen via Mollie, facturen klaar voor Peppol, cadeaukaarten, online cursussen en een site in vijf talen. Sinds 2015 geanalyseerd, ontworpen, gebouwd en beheerd.

Kleine organisatie

  • Requirementsanalyse
  • PHP 8
  • MySQL
  • JavaScript
  • Mollie
  • Peppol
Opdrachtgever
Samtati · Hilde Van Bulck
Rol
Analist, architect en full-stackontwikkelaar
Periode
2015 – nu

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.

Van WordPress naar een eigen platform, 2015–2026.

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.

Eén keer invoeren, zes plekken tegelijk.

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.

Bewerken op de live pagina, in elke taal.

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.

Twee meldingen tegelijk, één verwerking.

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.

Een cadeaukaart in stukken gebruiken, tot op de cent.

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.

Toegang volgt de betaling, ook bij een terugbetaling.

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.

Eén motor per werkvorm, in de les en op het scherm.

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.

Aanmelden zonder wachtwoord: de server kent enkel de publieke sleutel.

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.

Elke dag vertaald, met waarborgen, en Hilde gaat 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.

Beheer op de telefoon, en een test die het bewaakt.

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.

Een logboek dat meekijkt, met een AI-weekverslag.

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.

Verdediging in lagen, en elke wijziging getest.

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.

Tools en technologie

  • Requirementsanalyse
  • PHP 8
  • MySQL
  • JavaScript
  • Mollie
  • Peppol
  • Passkeys
  • Cloudflare
  • DigitalOcean
  • Docker
  • PHPUnit
  • End-to-endtests
  • AI-vertaling

Meer werk

  • Eigen onderneming

    Jorick Michiels Fotografie

    Het platform achter mijn fotografiezaak: galerijen, beeldbank, webshop en een eigen server.

  • Eigen project

    Mijnheer Jongetje

    Bedtijdverhalen die een verhaalwereld en luisterversies worden, vol generatieve AI.

  • Eigen onderneming

    Flesh & Fiction

    Een visuele studie naar wat generatieve AI met beeld doet, in reeksen om traag naar te kijken.

Volgende stap