Blog ·
Automatiser la facturation ISPConfig
ISPConfig répond HTTP 200 à tout, échecs compris. Ce que cela implique pour un déclencheur de facturation, et le cycle de vie du compte sur son API distante.
Par Provibr
ISPConfig a une commande pour chaque moment où l’argent et les machines se touchent : créer le compte, le suspendre, le déplacer vers un autre paquet, le supprimer. Ce qu’il n’a pas, c’est quoi que ce soit qui décide quand les lancer.
Relier les deux moitiés est un travail pour l’essentiel ordinaire. Deux choses chez ISPConfig ne le sont pas, et toutes deux casseront silencieusement une première tentative : le code de statut d’un appel ne vous apprend rien du tout, et un compte n’est pas un client.
Le code de statut ne dit rien
Tout revient en HTTP 200. Les erreurs de validation, le « cela n’existe pas », un mauvais mot de passe, une méthode que l’utilisateur distant n’a pas le droit d’appeler : tous, 200. Le verdict est un champ code à l’intérieur du corps JSON.
code | Signification |
|---|---|
ok | Cela a fonctionné ; response porte le résultat |
remote_fault | Échec : validation, objet manquant, authentification, permission. message explique |
invalid_method | Méthode inconnue, ou méthode absente de cette classe |
permission_denied | L’utilisateur distant n’a pas cette fonction |
Classez sur code et sur le texte, jamais sur le statut. Si cela compte davantage pour une intégration de facturation que pour quoi que ce soit d’autre, c’est à cause du relevé : un client qui traite 200 comme un succès lit un échec d’authentification comme un inventaire vide réussi, puis marque chacun des comptes de ce client comme disparu. Une seule session expirée, et votre réconciliation supprime une activité d’hébergement.
Le champ message se présente sous deux formes, et la différence est utile. Les erreurs de validation venant de la couche formulaire du panneau sont une liste de clés de traduction séparées par <br>, pas des phrases : domain_error_unique pour un domaine déjà hébergé. Les vérifications de la bibliothèque distante sont des phrases anglaises ordinaires : Invalid client_id 99999. Faites correspondre les clés, citez les phrases.
Un compte est un site web, pas un client
ISPConfig sépare deux choses que la plupart des panneaux de contrôle fusionnent. Un client est un identifiant de panneau assorti de limites valables pour tout le compte. Un web_domain est un site hébergé. Un client peut posséder plusieurs sites web.
Un compte d’hébergement Provibr est un site web, identifié par son domaine. En créer un demande donc un propriétaire : l’agent crée un client neuf et un site web dessous, et dérive l’identifiant du client depuis le domaine, pour pouvoir toujours retrouver le propriétaire.
C’est ce choix qui rend le chemin de suppression sûr, et le chemin de suppression est l’endroit où cette intégration a failli mal tourner. Nous y venons plus bas.
Le cycle de vie, en correspondance
| Événement de facturation | Appel ISPConfig | Réponse en cas de succès |
|---|---|---|
| Commande payée | client_add, puis sites_web_domain_add | code: ok, deux fois |
| Facture échue | sites_web_domain_set_status(id, "inactive") | code: ok |
| Paiement reçu | sites_web_domain_set_status(id, "active") | code: ok |
| Montée / descente en gamme | client_update avec un nouveau modèle de client | code: ok |
| Résiliation | sites_web_domain_delete, puis éventuellement le client | code: ok |
Suspendre est idempotent dans les deux sens
La suspension bascule l’indicateur active du site web entre y et n. Il n’y a ni masques de bits ni états partiels : un site est allumé ou il est éteint.
Une deuxième suspension sur un site déjà suspendu répond code: ok avec une réponse de 0, c’est-à-dire zéro ligne modifiée. Ce n’est pas une erreur, et une campagne de relance qui suspend tout ce qui est en retard, y compris ce qu’elle a suspendu hier, n’a rien à faire pardonner. Il vaut la peine d’apprécier à quel point c’est rare : comme le raconte Automatiser la facturation HestiaCP, la même deuxième suspension y donne un HTTP 401, indiscernable d’un mauvais secret, sur un panneau qui bannit votre adresse après cinq connexions refusées.
Une chose à connaître, même si l’intégration ne s’en sert pas : ISPConfig dispose aussi d’un verrou au niveau du client, et le poser bascule d’un coup tous les sites web de ce client en inactif. Un client qui se verrouille lui-même dans le panneau, ou un verrou de revendeur au-dessus de lui, apparaît donc comme suspendu dans le relevé. C’est correct, et ce n’est pas votre système de facturation qui l’a fait.
Changer de paquet est ici une action réelle
Un paquet ISPConfig est un modèle de client : un jeu de limites nommé, construit par un administrateur dans le panneau. L’API distante ne peut pas en créer, ce qui n’est pas gênant, car un plan devrait renvoyer à un paquet plutôt que l’inventer. Provibr transmet le nom du paquet et l’agent en cherche l’identifiant de modèle.
Cela fait d’ISPConfig l’un des panneaux de contrôle où un changement de plan est véritablement un changement de plan. CloudPanel et CyberPanel doivent le refuser purement et simplement ; ici il se produit et les limites bougent aussitôt.
Deux précautions mesurées si vous écrivez cela vous-même. Envoyez une mise à jour minimale, ne portant rien d’autre que le nouveau modèle : une mise à jour contenant l’enregistrement client complet est revenue en remote_fault sans message exploitable, et une mise à jour combinant un modèle explicite avec des limites explicites aussi. Et sachez que le modèle l’emporte sur les limites que vous envoyez également, ce qui est le bon sens de priorité mais surprend la première fois.
Le signal de disponibilité vaut pour tout le serveur
Créer un site web répond en quelques millisecondes, et cette réponse veut dire accepté, pas fait. La ligne de base de données existe ; l’hôte virtuel et la racine des documents sont posés de façon asynchrone par le démon du serveur.
Le signal à attendre est le compteur de la file de tâches de ce serveur, dont il a été mesuré qu’il passait de trois à zéro en huit secondes environ sur une machine calme, et en vingt-trois secondes environ lors d’un essai antérieur. C’est un compteur global, pas un compteur par commande. Sur un serveur mutualisé chargé, il peut rester au-dessus de zéro à cause des tâches d’autres clients, ou atteindre zéro alors que votre travail est encore en attente.
La règle est donc un délai avec un message véridique plutôt qu’une attente infinie : interrogez jusqu’à ce que la file soit vide ou jusqu’à épuisement du budget de création de 180 secondes, puis signalez le compte comme créé, car il l’est. « Le site est encore en cours d’installation » est une meilleure chose à dire à un client payant qu’un indicateur d’attente qui ne s’arrête jamais.
Supprimer est une question de vie privée, pas une question de nettoyage
C’est la partie de l’article à garder si vous n’en gardez rien d’autre, et elle ne parle pas vraiment d’ISPConfig.
Le chemin de suppression avait un défaut qu’aucun jeu de données de test ne pouvait voir : il comparait deux champs qui ne sont jamais réellement égaux, si bien que la branche qui supprimait le client propriétaire était du code mort. Chaque suppression laissait derrière elle un identifiant de panneau portant le nom du client, son adresse e-mail, ses coordonnées et son mot de passe. La commande répondait ok, le site web avait disparu, le compteur tombait à zéro, et les données personnelles d’une personne qui avait demandé à partir restaient sur le nœud.
Rien au-dessus du panneau ne peut voir cela. Un processus de purge et un export de données personnelles nettoient notre côté ; ils n’ont aucune vue sur ce qui reste sur votre nœud d’hébergement. La règle qui en est sortie mérite d’être volée :
> Mesurez un chemin de suppression contre la base de données du panneau lui-même, et jamais contre « la commande a répondu ok ».
Sur ISPConfig cela fait quatre comptages, et les quatre doivent valoir zéro : les sites web, les clients, les identifiants système et le répertoire du client sur disque. Et mesurez-le avec le panneau plutôt qu’avec l’assistant de nettoyage de votre propre test, car cet assistant peut porter le même malentendu, et alors la machine paraît propre pendant que l’intégration fuit.
La règle de suppression sûre tient elle-même en une ligne : supprimez le site web ; ne supprimez le client propriétaire que s’il ne lui reste aucun site web. ISPConfig a un appel qui supprime un client et tout ce qui est dessous, et sur un compte importé cela emporterait les autres sites du client. Ne supprimez jamais plus que ce qui a été demandé.
Rien n’est instantané
Votre panneau n’est joignable que par l’agent qui se trouve dans votre propre réseau, et cet agent sort en connexion sortante ; un point d’accès qui modifie un compte ne peut donc pas répondre par le résultat. Il répond que l’ordre a été accepté et vous remet une commande à suivre jusqu’à ce que son statut soit définitif : terminé, échoué, expiré ou annulé. La lecture ne fonctionne jamais ainsi, car un inventaire ou une facture vient d’une base de données et non de votre hôte.
La conséquence pratique pour un déclencheur de facturation : ne marquez pas la commande comme terminée sur la réponse d’acceptation. Tout ce qui crée quelque chose accepte également une clé d’idempotence que vous composez vous-même, si bien qu’un webhook renvoyé et un double clic ne vous coûtent rien.
Où se trouve la facture
Provibr ne facture pas vos clients, ne les relance pas, et ignore ce que vous leur facturez. Cette relation est la vôtre.
Ce que Provibr facture, c’est la capacité que vous réservez : combien de comptes d’hébergement vous pouvez faire tourner en même temps, à un prix unitaire qui décroît par paliers à mesure que le nombre augmente. Pour un compte d’hébergement il n’existe pas d’état « arrêté » : il y a actif et suspendu, et un compte suspendu ne compte pas. L’action de relance que vous vouliez de toute façon pour des raisons commerciales est donc aussi celle qui libère la place que vous payez.
Ce qui n’est pas automatisé
Provibr gère des comptes, pas le panneau. Il n’installe pas ISPConfig, ne le met pas à jour, et ne touche ni aux boîtes aux lettres, ni aux bases de données, ni au DNS : un client qui supprime sa propre boîte aux lettres le fait sans que rien au-dessus du panneau le sache ni s’en soucie. Il n’y a pas de console pour un compte d’hébergement, pas de réinstallation, et pas de suspension partielle.
Si vous en êtes à une étape antérieure à la partie facturation, l’article compagnon est Vendre de l’hébergement web avec ISPConfig, qui traite de l’utilisateur distant, de la portée des permissions et du modèle un panneau pour plusieurs serveurs. Les identifiants, le certificat et l’écran des paquets sont documentés sur la page de documentation ISPConfig.
Questions fréquentes
Pourquoi chaque appel de l’API ISPConfig renvoie-t-il HTTP 200 ?
Parce que son API distante porte le verdict dans le corps plutôt que dans la ligne de statut. Le champ code vaut ok, remote_fault, invalid_method ou permission_denied. Un client qui se fie au statut lit un échec d’authentification comme une réponse vide réussie.
Un compte ISPConfig, est-ce un client ou un site web ?
Un site web. ISPConfig tient le client, qui est un identifiant de panneau assorti de limites, séparé du web_domain, qui est un site hébergé, et un client peut posséder plusieurs sites. Un compte d’hébergement est ici identifié par son domaine.
Un système de facturation peut-il suspendre deux fois le même site ISPConfig ?
Oui. Le deuxième appel répond ok avec zéro ligne modifiée, ce qui n’est pas une erreur. Réactiver est idempotent également, si bien qu’une campagne de relance nocturne n’a besoin d’aucun état propre.
Supprimer un compte ISPConfig retire-t-il l’identifiant de panneau du client ?
Cela doit être le cas, et cela vaut la peine d’être vérifié sur votre propre installation. Le comportement correct consiste à supprimer le site web, puis le client propriétaire seulement lorsqu’il ne lui reste aucun site web. Une suppression qui laisse le client derrière elle laisse le nom, l’adresse et le mot de passe du client sur le nœud.
Puis-je changer un paquet ISPConfig depuis un système de facturation ?
Oui. Un paquet est un modèle de client, et en assigner un autre déplace les limites immédiatement. N’envoyez que le nouveau modèle dans la mise à jour ; il a été mesuré qu’une charge plus complète échouait sans message d’erreur exploitable.