Blog ·
Automatisation de la facturation pour PufferPanel
De la commande au serveur et de la facture impayée au serveur arrêté sur PufferPanel. Le cycle de vie, la règle asynchrone et l’absence de suspension.
Par Provibr
La plupart des pages sur l’automatisation de la facturation commencent par le chemin heureux. Celle-ci commence par le trou, car sur PufferPanel c’est le trou qui détermine la conception.
PufferPanel n’a pas de suspension. Pas de colonne, pas d’endpoint. Le statut d’un serveur ne connaît que running et installing. Tout ce qui suit en découle.
Mesuré sur PufferPanel 3.0.9.
Deux couches de facturation, et ce n’est pas la même chose
| Couche | Qui facture qui | Ce qui est compté |
|---|---|---|
| Votre facturation | Vous → votre client | Un serveur de jeu, par mois, au prix que vous fixez |
| Facturation de la plateforme | Provibr → vous | La capacité : combien de serveurs de chaque type vous pouvez faire tourner en même temps |
Ce que vous facturez à vos propres clients reste entièrement dans votre système de facturation. Provibr ne voit jamais une facture client et ne parle jamais à vos clients. Votre système de facturation détient la décision, la couche de provisionnement détient l’exécution.
Le cycle de vie, en correspondance
| Événement de facturation | Ce qui doit se produire | Effet côté PufferPanel |
|---|---|---|
| Commande payée | Créer le serveur depuis le plan | Définition complète du modèle en ligne, serveur créé, installateur lancé |
| Facture échue | Suspendre | Conteneur arrêté + accès bloqué dans la plateforme (voir ci-dessous) |
| Paiement reçu | Réactiver | Accès rétabli ; le client démarre le serveur |
| Résiliation | Supprimer | Serveur arrêté d’abord, puis retiré |
| Montée / descente en gamme | Réinstaller | Relance l’installation du modèle |
Quatre de ces cinq lignes sont ordinaires. La deuxième ne l’est pas.
Le trou de la suspension, et comment concevoir autour
Quand une plateforme suspend un serveur de jeu PufferPanel (pour faire respecter une limite de licence, ou parce que vous l’avez ordonné pour impayé), elle arrête le conteneur et bloque l’accès à ce serveur dans son propre panneau. Le serveur ne tourne pas, et votre client ne peut pas le démarrer depuis votre tableau de bord.
Mais ce blocage est une notion de plateforme, pas une notion de panneau. Quiconque a un accès direct à l’installation PufferPanel peut redémarrer le serveur. PufferPanel n’impose rien, car il n’a rien pour imposer.
Cela mérite d’être dit clairement plutôt qu’enfoui, car cela change ce que vous devriez vendre :
| Votre configuration | Le trou compte-t-il ? |
|---|---|
| Les clients n’utilisent que votre tableau de bord, sans compte panneau | Non. Ils ne peuvent pas atteindre PufferPanel directement. |
| Les clients ont des identifiants PufferPanel | Oui. Un client suspendu peut annuler la suspension. |
| Vous revendez à des revendeurs ayant accès à l’hôte | Oui, et gravement. |
Si vous êtes dans la deuxième ou la troisième ligne et que l’application des relances compte, utilisez un panneau doté d’un vrai indicateur suspended. Pelican en a un, et un serveur suspendu y reste suspendu, quel que soit celui qui se connecte.
Une voie médiane si vous tenez à garder PufferPanel : résilier plus tôt. Puisqu’une suspension est molle, traitez-la comme une étape d’avertissement plutôt que d’application, et déplacez l’application réelle vers la suppression, avec une politique de conservation et une sauvegarde préalable, annoncées d’avance. C’est une décision produit, pas une décision technique.
La règle qui façonne tout : rien n’est instantané
Votre panneau vit dans votre propre réseau, et une plateforme sensée l’atteint via un agent qui se connecte vers l’extérieur : aucun port entrant, aucun trou dans le pare-feu. La conséquence est inévitable : un endpoint qui modifie une machine ne peut pas répondre par le résultat. Il répond que l’ordre a été accepté :
POST /v1/servers/{serverId}/actions/suspend
Authorization: Bearer pvk_...
Idempotency-Key: dunning-inv-10482{
"command": {
"id": "cmd_...",
"kind": "game.suspend",
"status": "pending"
}
}202 Accepted, pas 200. Ensuite vous relisez cette commande jusqu’à ce que son statut soit définitif : done, failed, timed_out ou cancelled. Une commande échouée porte le code d’erreur propre à l’agent, avec ses arguments. La lecture, elle, est différente : un inventaire, une adresse ou une facture répond immédiatement, car cela vient d’une base de données et non de votre hôte.
Concevez vos hooks de relance en conséquence. Un hook qui lit « l’API a répondu » comme « le travail est fait » signalera une suspension réussie qui n’a jamais eu lieu, précisément le jour où cela comptait.
Répéter sans risque
Tout ce qui crée quelque chose accepte un en-tête Idempotency-Key que vous composez vous-même. Répétez la même requête avec la même valeur et vous récupérez le premier résultat au lieu d’un deuxième serveur. Indexez sur quelque chose de stable de votre côté (le numéro de facture, l’identifiant du service, l’étape de relance), car les webhooks renvoyés et les crons au quart d’heure sont normaux, et les deux doivent être inoffensifs. Réutiliser cette valeur pour une autre requête est refusé volontairement : une clé qui signifie deux choses ne signifie rien.
Les verbes, et quand ils sont autorisés
Un serveur de jeu accepte six actions via l’API : start · stop · restart · kill · suspend · resume, gardées par l’état courant du serveur :
| Action | Autorisée depuis |
|---|---|
| start | stopped, error, unknown |
| stop / restart / kill | running, error, unknown |
| suspend | running, stopped, installing, error, unknown |
| resume | suspended |
| reinstall | running, stopped, error |
Vous pouvez suspendre un serveur déjà arrêté, et c’est délibéré : une application de la règle que l’on contourne en appuyant sur « stop » n’en est pas une. suspend depuis installing suit la même logique : une résiliation qui arrive au milieu d’une installation ne devrait pas attendre la fin de celle-ci.
Commander passe par un plan, et cela ne peut pas être autrement
Sur certains panneaux, vous pouvez composer une commande à la main. Sur PufferPanel, pratiquement pas, et la raison est structurelle : PufferPanel exige la définition complète du modèle en ligne à la création d’un serveur. Il n’y a pas de « fabrique-en un à partir du modèle X » par référence : la définition doit donc venir d’un catalogue. Un plan de jeu porte le nom du modèle et les limites de ressources ; la commande pointe vers le plan. Si vous bâtissez votre propre pont, vous bâtirez ce catalogue de toute façon.
Deux détails mesurés sur lesquels on trébuche facilement :
- Les modèles communautaires utilisent par défaut un environnement hôte, qui exige des binaires qu’un hôte de panneau neuf n’a pas. Basculez sur la variante docker du modèle, sinon chaque commande échoue avec une erreur de binaire manquant qui se lit comme un bug de plateforme.
- La suppression arrête d’abord le serveur. Le démon refuse de retirer un conteneur en cours d’exécution ; une suppression contre un serveur en marche renvoie un 500.
Ce qui n’est délibérément pas là
- Pas de facturation à l’usage. Le point de statistiques de PufferPanel ne renvoie que le pourcentage de processeur et la mémoire, pas de disque, pas de réseau, pas de durée de fonctionnement. Deux des quatre graphiques standard resteraient vides en permanence : les graphiques d’utilisation sont donc désactivés pour ce fournisseur. On ne facture pas au compteur des données qui n’existent pas.
- Pas de console dans le tableau de bord. La console de PufferPanel repose sur du sondage et n’est pas un terminal en direct ; une poignée de main WebSocket conforme à la spécification sur
/consolerenvoie 200 JSON au lieu de 101. Vos clients obtiennent la console dans PufferPanel lui-même. - Pas de placement tenant compte de la capacité. PufferPanel expose ses nœuds mais pas leur mémoire, leur disque ni leur processeur : un panneau à plusieurs nœuds est choisi par ordre de nom plutôt que par espace libre. C’est vous le planificateur de capacité.
- Pas de changement de plan en un appel. Changer de plan est une réinstallation, avec les conséquences que cela implique pour les données du client.
- Pas de boucle de réconciliation d’inventaire. La synchronisation
_ListAccountsde WHMCS résilie tout service absent de la réponse, et « absent » a des causes innocentes : une portée d’API plus étroite, un membre restreint à une partie de l’inventaire, une limitation de débit, une page courte dont le curseur n’a pas été suivi. Chacune supprimerait des machines clientes.
Depuis WHMCS plutôt qu’en code
Si vous faites déjà tourner WHMCS, Provibr fournit un module de provisionnement sous forme d’une simple archive zip que vous installez vous-même. Un produit WHMCS pointe vers un plan Provibr ; le flux de commande habituel de WHMCS se charge de créer, suspendre, réactiver et résilier. Deux décisions méritent d’être reprises même dans votre propre pont :
Une livraison encore en cours compte comme un succès. Si le budget d’attente expire pendant que l’installateur travaille, le module signale un succès : la commande a été acceptée, et WHMCS ne connaît pas de statut « en cours d’installation » (Pending y signifie rien ne s’est encore produit, ce qui est faux). Un ordre qui échoue réellement, c’est autre chose : le service reste Pending et l’administrateur voit pourquoi.
Un serveur qui n’existe déjà plus est une résiliation réussie. Un 404 signifie plusieurs choses à la fois (identifiant inconnu, autre organisation, invisible pour ce membre, déjà supprimé), et pour un hook de résiliation l’action correcte est la même dans tous les cas : il n’y a plus rien à nettoyer.
Compter la capacité, et comment cela rejoint les relances
La facturation de la plateforme compte la capacité, pas l’usage, avec une règle qui surprend tout le monde le premier mois : chaque serveur compte, qu’il tourne ou non. Seul un serveur suspendu ne compte pas, et un serveur supprimé non plus. Arrêter une machine ne libère pas de place.
Cela s’articule bien avec les relances : un client que vous suspendez cesse de compter tant qu’il est suspendu, et recompte dès qu’il paie et que vous réactivez.
PufferPanel à côté de tout le reste
Vous n’êtes pas obligé de choisir un seul panneau. Provibr couvre ses panneaux de contrôle, ses hyperviseurs et ses panneaux de jeu dans un seul tableau de bord, avec une seule API et un seul chiffre de capacité.
POST /v1/servers/{id}/actions/suspend fait la même chose qu’il y ait dessous un serveur Pelican, un serveur PufferPanel ou un compte d’hébergement DirectAdmin. Les différences vivent dans le fournisseur, pas dans votre code d’intégration. Et là où un fournisseur ne sait vraiment pas faire quelque chose, vous obtenez un refus qui nomme la capacité manquante plutôt qu’une absence silencieuse d’effet.