Naar de inhoud

Blog ·

Facturatie-automatisering voor Pelican Panel

Van betaalde bestelling naar draaiende Pelican-server, en van onbetaalde factuur naar een opgeschorte. De levenscyclus, de asynchrone regel en de grenzen.

Door Provibr

Pelican heeft een suspended-vlag op elke server. Niets in Pelican zet hem ooit. Die ene zin is de hele reden dat deze pagina bestaat: het paneel kán de server van een klant stopzetten, maar het heeft geen idee of die klant betaald heeft.

Deze pagina beschrijft hoe een werkende automatisering eruitziet: het bestelpad, het aanmaningspad, en de onderdelen die lastiger zijn dan ze lijken.

Twee lagen facturatie, en dat is niet hetzelfde

Scheid ze eerst. Mensen halen deze twee voortdurend door elkaar en discussiëren dan over het verkeerde probleem.

LaagWie factureert wieWat er geteld wordt
Jouw facturatieJij → je klantEen gameserver, per maand, voor wat jij ervoor rekent
PlatformfacturatieProvibr → jijCapaciteit: hoeveel servers van elke soort je tegelijk mag draaien

Wat jij je eigen klanten rekent, en hoe, blijft volledig binnen jouw facturatiesysteem. Provibr ziet nooit een klantfactuur, stelt nooit een prijs voor je vast en praat nooit met jouw klanten; het factureert jou voor gereserveerde capaciteit per resourcesoort, tegen een stuksprijs die in staffels daalt naarmate het aantal stijgt.

Die scheiding maakt de automatisering behapbaar. Jouw facturatiesysteem bezit het besluit; de provisioninglaag bezit de uitvoering.

De levenscyclus, in kaart

Dit is de vertaling die elke gameserverautomatisering nodig heeft, welk gereedschap je ook gebruikt:

FacturatiegebeurtenisWat er moet gebeurenEffect in Pelican
Bestelling betaaldServer aanmaken uit het planServer gebouwd uit het egg, allocatie toegewezen, installatie loopt
Factuur vervallenOpschortensuspended gezet, de server stopt en blijft stil
Betaling ontvangenHervattensuspended gewist, klant start hem zelf weer
OpzeggingVerwijderenServer weg, allocatie vrij
Upgrade / downgradeHerinstalleren of resizenDraait het installatiescript van het egg opnieuw

Pelican is hier comfortabel, en dat is het waard om hardop te zeggen, want niet elk gamepaneel is dat. Pelican heeft een echt opschort-primitief. Een opgeschorte server is opgeschort in het paneel: iemand met directe toegang tot Pelican kan hem niet zomaar weer starten. Wanneer de handhaving ertoe doet (en bij aanmaningen doet ze dat), is dat het verschil tussen een beleid en een wens.

(Ter vergelijking: PufferPanel heeft geen eigen opschorting, dus daar is een opschorting een platformbegrip dat het paneel niet afdwingt.)

De regel die alles bepaalt: niets is meteen klaar

Dit is het deel dat mensen fout doen als ze zelf een API aan elkaar knopen.

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, en geeft je iets om te volgen:

http
POST /v1/servers/{serverId}/actions/suspend
Authorization: Bearer pvk_...
Idempotency-Key: dunning-inv-10482
json
{
  "command": {
    "id": "cmd_...",
    "kind": "game.suspend",
    "status": "pending"
  }
}

Je krijgt 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 foutcode van de agent zelf, met zijn argumenten.

Lezen werkt nooit zo: een inventaris, een adres of een factuur antwoordt meteen, want dat antwoord komt uit een database en niet van jouw host.

Ontwerp je facturatiehooks hierop. Een hook die "de API antwoordde" leest als "het werk is gedaan" meldt succes voor een opschorting die nooit gebeurd is, op precies de dag dat het ertoe deed.

Een verzoek 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, een tweede opdracht of een tweede afschrijving.

Voor aanmaningen is dat geen luxe. Een cron die elk kwartier draait, een webhook die opnieuw gestuurd wordt, een beheerder die twee keer klikt: alle drie normaal, en alle drie horen ongevaarlijk te zijn. Sleutel het verzoek op iets stabiels van jouw kant: het factuurnummer, het dienst-id, de aanmaningsfase. 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

Ze worden bewaakt door de huidige status van de server, en dat is strenger dan het lijkt:

ActieToegestaan vanuit
startstopped, error, unknown
stop / restart / killrunning, error, unknown
suspendrunning, stopped, installing, error, unknown
resumesuspended
reinstallrunning, stopped, error

De regel voor suspend is de interessante, en hij is bewust: je kunt een server opschorten die al gestopt is. Zou opschorten alleen op draaiende servers werken, dan kan een klant zijn eigen server stoppen, stoppen met betalen, en immuun zijn: het paneel zou de opschorting weigeren omdat er niets draaide. Handhaving die je omzeilt door op "stop" te drukken is geen handhaving.

suspend vanuit installing doet er ook toe: een opzegging die midden in een installatie binnenkomt hoort niet te wachten tot die installatie klaar is.

Vanuit een facturatiepaneel in plaats van code

Draai je al WHMCS, dan hoef je niets van het bovenstaande te schrijven. Provibr levert een provisioningmodule voor WHMCS als een gewone zip die je zelf installeert: één WHMCS-product wijst naar één Provibr-plan, en de normale bestelstroom van WHMCS doet het aanmaken, opschorten, hervatten en beëindigen.

Twee ontwerpkeuzes in die module zijn het overnemen waard, ook als je je eigen brug schrijft:

Een levering die nog loopt geldt als geslaagd. Loopt het wachtbudget af terwijl de installatie nog bezig is, dan meldt de module succes. De bestelling is aangenomen (de serverrij bestaat, het adres is toegewezen, de opdracht staat bij de agent), en WHMCS kent geen "wordt geïnstalleerd"-status (Pending betekent daar er is nog niets gebeurd, en dat is aantoonbaar onwaar). Een opdracht die écht mislukt is iets anders: dan blijft de dienst Pending, ziet de beheerder waarom, en is een herhaalde klik ongevaarlijk dankzij de idempotency-sleutel.

Een server die er al niet meer is, is een geslaagde beëindiging. Een 404 bij verwijderen betekent vier dingen tegelijk (onbekend id, andere organisatie, niet toegewezen aan dit lid, of al verwijderd), en voor een beëindigingshook is de juiste handeling in alle vier dezelfde: er valt niets meer op te ruimen. Het als fout behandelen laat een dienst voor eeuwig in "terminating" hangen.

Wat bewust niet geautomatiseerd is

Eerlijke grenzen, want dit zijn de vragen die komen nádat je al iets verkocht hebt:

  • Geen verbruiksfacturatie. Metingen per server worden verzameld en in het paneel getoond, maar nog niet via de API aangeboden. Zonder endpoint geen verbruiksfacturatie. Is jouw product "betaal voor het RAM dat je gebruikte", dan kan dit dat vandaag niet.
  • Geen planwissel in één aanroep. Een plan wisselen is ook op Pelican-niveau geen enkele API-aanroep: het is een herinstallatie of een resourcewijziging, met verschillende gevolgen voor de data van de klant.
  • Geen wachtwoordreset via de API. Inloggegevens reizen transient mee en worden nergens bewaard, dus er is niets om opnieuw te sturen.
  • Geen single sign-on vanuit je facturatiepaneel naar het Provibr-paneel.
  • Geen inventarissynchronisatie: een weigering, geen gat. 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. In plaats daarvan leest de klantomgeving de echte status bij elke paginaweergave, en dat is geen synchronisatie en doet ook niet alsof.

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 netjes aan op aanmaningen. Een klant die je opschort wegens niet betalen telt niet meer mee zolang hij opgeschort is, en telt weer mee zodra hij betaalt en jij hervat. Je betaalt dus geen platformcapaciteit voor een klant die jou niet betaalt.

Boven je limiet komen wordt niet geblokkeerd op het moment dat je het doet. Het wordt opgemerkt, je krijgt bericht, en je krijgt een volle werkdag. Verloopt die respijtperiode, dan worden de nieuwste servers boven je limiet opgeschort, nieuwste eerst, zodat wat je het eerst bouwde blijft staan.

Pelican naast al het andere

Een gamehost die groeit blijft zelden op één paneel. Provibr dekt zijn controlepanelen, hypervisors en gamepanelen in één dashboard, met één API en één capaciteitsgetal over alles heen.

POST /v1/servers/{id}/actions/suspend doet hetzelfde of er nu een Pelican-server, een Pterodactyl-server of een DirectAdmin-hostingaccount onder zit. De verschillen zitten in de provider, niet in jouw integratiecode.

Begin met één host en één agent

Maak een account aan, installeer de agent met één commando en koppel je eerste Proxmox-host. De proefperiode loopt 14 dagen en vraagt geen betaalgegevens.