Blog ·
Facturatie-automatisering voor PufferPanel
Van bestelling naar server en van onbetaalde factuur naar gestopte server op PufferPanel. De levenscyclus, de asynchrone regel en het opschortgat eromheen.
Door Provibr
De meeste pagina's over facturatie-automatisering beginnen bij het gelukkige pad. Deze begint bij het gat, want op PufferPanel bepaalt het gat het ontwerp.
PufferPanel heeft geen opschorting. Geen kolom, geen endpoint. De serverstatus kent alleen running en installing. Alles hieronder volgt daaruit.
Gemeten tegen PufferPanel 3.0.9.
Twee lagen facturatie, en dat is niet hetzelfde
| Laag | Wie factureert wie | Wat er geteld wordt |
|---|---|---|
| Jouw facturatie | Jij → je klant | Een gameserver, per maand, voor wat jij ervoor rekent |
| Platformfacturatie | Provibr → jij | Capaciteit: hoeveel servers van elke soort je tegelijk mag draaien |
Wat jij je eigen klanten rekent blijft volledig binnen jouw facturatiesysteem. Provibr ziet nooit een klantfactuur en praat nooit met jouw klanten. Jouw facturatiesysteem bezit het besluit, de provisioninglaag bezit de uitvoering.
De levenscyclus, in kaart
| Facturatiegebeurtenis | Wat er moet gebeuren | Effect in PufferPanel |
|---|---|---|
| Bestelling betaald | Server aanmaken uit het plan | Volledige templatedefinitie inline mee, server aangemaakt, installatie loopt |
| Factuur vervallen | Opschorten | Container gestopt + toegang geblokkeerd in het platform (zie hieronder) |
| Betaling ontvangen | Hervatten | Toegang hersteld; klant start de server |
| Opzegging | Verwijderen | Server eerst gestopt, dan verwijderd |
| Upgrade / downgrade | Herinstalleren | Draait de installatie van de template opnieuw |
Vier van die vijf regels zijn gewoon. De tweede niet.
Het opschortgat, en hoe je eromheen ontwerpt
Als een platform een PufferPanel-gameserver opschort (om een licentielimiet af te dwingen, of omdat jij het opdroeg wegens niet betalen), stopt het de container en blokkeert het de toegang tot die server in het paneel van het platform zelf. De server draait niet, en je klant kan hem niet starten vanuit jouw dashboard.
Maar de blokkade is een platformbegrip, geen paneelbegrip. Iedereen met directe toegang tot de PufferPanel-installatie kan de server weer starten. PufferPanel dwingt niets af, want het heeft niets om mee af te dwingen.
Dat is het waard om hardop te zeggen in plaats van te begraven, want het verandert wat je zou moeten verkopen:
| Jouw opzet | Maakt het gat uit? |
|---|---|
| Klanten gebruiken alleen jouw dashboard; geen paneelaccounts | Nee. Ze kunnen PufferPanel niet rechtstreeks bereiken. |
| Klanten hebben PufferPanel-logins | Ja. Een opgeschorte klant kan de opschorting ongedaan maken. |
| Je verkoopt door aan resellers met hosttoegang | Ja, en erg. |
Zit je in de tweede of derde regel en doet handhaving van aanmaningen ertoe, gebruik dan een paneel met een echte suspended-vlag. Pelican heeft er een, en een opgeschorte server blijft daar opgeschort, wie er ook inlogt.
Een tussenweg als je PufferPanel wilt houden: eerder beëindigen. Omdat een opschorting zacht is, behandel je hem als waarschuwingsfase in plaats van handhavingsfase, en verplaats je de echte handhaving naar verwijderen, met een bewaarbeleid en een back-up vooraf, van tevoren gecommuniceerd. Dat is een productbeslissing, geen technische.
De regel die alles bepaalt: niets is meteen klaar
Je paneel staat in je eigen netwerk, en een verstandig platform bereikt het via een agent die uitgaand verbindt: geen inkomende poort, geen gat in de firewall. Het gevolg is onontkoombaar: een endpoint dat een machine wijzigt kan niet met de uitkomst antwoorden. Het antwoordt dat de opdracht is aangenomen:
POST /v1/servers/{serverId}/actions/suspend
Authorization: Bearer pvk_...
Idempotency-Key: dunning-inv-10482{
"command": {
"id": "cmd_...",
"kind": "game.suspend",
"status": "pending"
}
}202 Accepted, geen 200. Daarna lees je die opdracht tot zijn status definitief is: done, failed, timed_out of cancelled. Een mislukte opdracht draagt de eigen foutcode van de agent met zijn argumenten. Lezen is anders: een inventaris, een adres of een factuur antwoordt meteen, want dat komt uit een database en niet van jouw host.
Ontwerp je aanmaningshooks hierop. Een hook die "de API antwoordde" leest als "het werk is gedaan" meldt een geslaagde opschorting die nooit gebeurd is, op precies de dag dat het ertoe deed.
Veilig herhalen
Alles wat iets aanmaakt accepteert een zelfgekozen Idempotency-Key-header. Herhaal hetzelfde verzoek met dezelfde waarde en je krijgt de eerste uitkomst terug in plaats van een tweede server. Sleutel op iets stabiels van jouw kant (het factuurnummer, het dienst-id, de aanmaningsfase), want opnieuw gestuurde webhooks en kwartiercrons zijn normaal, en allebei horen ze ongevaarlijk te zijn. Diezelfde waarde voor een ander verzoek hergebruiken wordt met opzet geweigerd: een sleutel die twee dingen betekent, betekent niets.
De werkwoorden, en wanneer ze mogen
Een gameserver accepteert zes acties over de API: start · stop · restart · kill · suspend · resume, bewaakt door de huidige status van de server:
| Actie | Toegestaan vanuit |
|---|---|
| start | stopped, error, unknown |
| stop / restart / kill | running, error, unknown |
| suspend | running, stopped, installing, error, unknown |
| resume | suspended |
| reinstall | running, stopped, error |
Je kunt een server opschorten die al gestopt is, en dat is bewust: handhaving die je omzeilt door op "stop" te drukken is geen handhaving. suspend vanuit installing volgt dezelfde logica: een opzegging die midden in een installatie binnenkomt hoort niet te wachten tot die klaar is.
Bestellen is plan-gedreven, en dat moet ook
Op sommige panelen kun je een bestelling met de hand bouwen. Op PufferPanel kan dat feitelijk niet, en de reden is structureel: PufferPanel eist de volledige templatedefinitie inline bij het aanmaken van een server. Er is geen "maak er een uit template X" via een verwijzing, dus de definitie moet uit een catalogus komen. Een gameplan draagt de templatenaam en de resourcelimieten; bestellen wijst naar het plan. Bouw je je eigen brug, dan bouw je die catalogus toch.
Twee gemeten details die goedkoop zijn om over te struikelen:
- Community-templates staan standaard op een host-omgeving, die binaries nodig heeft die een verse paneelhost niet heeft. Schakel over naar de docker-variant van de template, of elke bestelling mislukt met een missing-binary-fout die leest als een platformbug.
- Verwijderen stopt de server eerst. De daemon weigert een draaiende container te verwijderen; een delete op een draaiende server geeft een 500.
Wat er bewust niet is
- Geen verbruiksfacturatie. Het statistiekenendpoint van PufferPanel meldt alleen CPU-percentage en geheugen. Geen schijf, geen netwerk, geen uptime. Twee van de vier standaardgrafieken zouden permanent leeg staan, dus verbruiksgrafieken staan voor deze provider uit. Gemeten facturatie kan niet op data die niet bestaat.
- Geen console in het dashboard. De console van PufferPanel is poll-gebaseerd in plaats van een live terminal; een spec-conforme websocket-handshake op
/consolegeeft 200 JSON in plaats van 101. Je klanten krijgen de console in PufferPanel zelf. - Geen capaciteitsbewuste plaatsing. PufferPanel toont zijn nodes maar niet hun geheugen, schijf of CPU, dus een paneel met meerdere nodes wordt op naamvolgorde gekozen in plaats van op vrije ruimte. Jij bent de capaciteitsplanner.
- Geen planwissel in één aanroep. Een plan wisselen is een herinstallatie, met de gevolgen voor klantdata die daarbij horen.
- Geen inventarissynchronisatie. De
_ListAccounts-sync van WHMCS beëindigt elke dienst die in het antwoord ontbreekt, en "ontbreekt" heeft onschuldige oorzaken: een smallere API-scope, een lid dat tot een deel van de inventaris begrensd is, een doorvoerrem, een korte bladzijde waarvan de cursor niet gevolgd werd. Elk daarvan zou klantmachines opruimen.
Vanuit WHMCS in plaats van code
Draai je al WHMCS, dan levert Provibr een provisioningmodule als een gewone zip die je zelf installeert. Eén WHMCS-product wijst naar één Provibr-plan; de normale bestelstroom van WHMCS doet het aanmaken, opschorten, hervatten en beëindigen. Twee keuzes daarin zijn het overnemen waard, ook in je eigen brug:
Een levering die nog loopt geldt als geslaagd. Loopt het wachtbudget af terwijl de installatie bezig is, dan meldt de module succes. De bestelling is aangenomen, en WHMCS kent geen "wordt geïnstalleerd"-status (Pending betekent daar er is nog niets gebeurd, en dat is onwaar). Een opdracht die écht mislukt is anders: de dienst blijft Pending en de beheerder ziet waarom.
Een server die er al niet meer is, is een geslaagde beëindiging. Een 404 betekent meerdere dingen tegelijk (onbekend id, andere organisatie, niet zichtbaar voor dit lid, al verwijderd), en voor een beëindigingshook is de juiste handeling in alle gevallen dezelfde: er valt niets meer op te ruimen.
Capaciteit tellen, en hoe dat op aanmaningen aansluit
Platformfacturatie telt capaciteit, geen verbruik, met één regel die iedereen in de eerste maand verrast: elke server telt mee, of hij nu draait of niet. Alleen een opgeschorte server telt niet mee, en een verwijderde evenmin. Een machine stoppen maakt geen plaats vrij.
Dat sluit goed aan op aanmaningen: een klant die je opschort telt niet meer mee zolang hij opgeschort is, en telt weer mee zodra hij betaalt en jij hervat.
PufferPanel naast al het andere
Je hoeft geen paneel te kiezen. Provibr dekt zijn controlepanelen, hypervisors en gamepanelen in één dashboard, met één API en één capaciteitsgetal.
POST /v1/servers/{id}/actions/suspend doet hetzelfde of er nu een Pelican-server, een PufferPanel-server of een DirectAdmin-hostingaccount onder zit. De verschillen zitten in de provider, niet in jouw integratiecode. En waar een provider iets werkelijk niet kan, krijg je een weigering die de ontbrekende capability noemt in plaats van een stille no-op.