Base de connaissances
Vendez l'hébergement Zinn® depuis HostBill, Blesta ou votre propre système
Vendez l'hébergement Zinn via HostBill, Blesta ou votre propre système : le module HostBill gratuit, le client PHP à fichier unique, les deux règles qui coûtent cher lorsqu'elles sont enfreintes, et les deux champs de requête qu'il est facile d'oublier.
Si vous utilisez WHMCS, utilisez le module WHMCS à la place — cette page traite de tout le reste. Il existe deux options, toutes deux gratuites et sous licence GPL-2.0-or-later.
HostBill
Un module d'hébergement doté des six mêmes actions que celui de WHMCS.
- Téléchargez-le et décompressez-le.
- Téléchargez le répertoire
zinndansincludes/modules/Hosting/afin que les fichiers se trouvent dans - Settings → Modules → Hosting, activez Zinn Digital®, et ajoutez une connexion :
includes/modules/Hosting/zinn/class.zinn.php et includes/modules/Hosting/zinn/ZinnHostBillClient.php.
- API address :
https://api.zinndigital.com - API key : votre clé d'API Zinn® (un champ
password, afin que HostBill la stocke de manière chiffrée)
- Sur le produit, définissez la Product line (par ex.
mainstream), le Stack (wordpresspar - Appuyez sur Test connection.
défaut), et éventuellement l'Application et la PHP version.
⛔ Ne renommez pas le répertoire
zinn. Le chargeur de HostBill déduit la classe qu'il recherche à partir du nom du répertoire, de sorte qu'un renommage produit un module que le panneau liste mais n'appelle jamais.
Tout le reste — le client PHP
Un fichier, aucune dépendance, aucune hypothèse sur le panneau. Placez ZinnProvisioning.php dans votre propre code source et appelez six méthodes.
require_once 'ZinnProvisioning.php';
$zinn = new ZinnProvisioning(getenv('ZINN_API_KEY'));
// When an order is paid — once per CUSTOMER, then once per SERVICE:
$orgId = $zinn->account('customer-4211', 'Acme Ltd');
$siteId = $zinn->provision('service-9915', $orgId, 'acme.com', 'mainstream', 'wordpress');
// Store $orgId against your customer and $siteId against your service.
$zinn->suspend($siteId, 'INV-2026-114 unpaid'); // an invoice goes unpaid
$zinn->unsuspend($siteId); // they pay
$zinn->terminate($siteId); // they cancel — schedules a deletion
// When they click "log in to my hosting" — mint it on the CLICK, never on page render:
header('Location: ' . $zinn->signInLink($siteId));
Vous n'écrivez pas en PHP ? Les mêmes appels se trouvent dans la référence de l'API et vous pouvez les effectuer depuis n'importe quoi.
La clé d'API
Sept autorisations, et pas une de plus : org.create, org.read, sites.create, sites.view, sites.delete, reseller.view, reseller.provision.
⛔ Pas
reseller.manage. Une clé que vous collez dans un panneau de facturation doit être capable de suspendre un client pour non-paiement et de le connecter ; elle ne doit pas être capable de réécrire vos propres identifiants de passerelle de paiement.
Les deux règles qui coûtent de l'argent lorsqu'elles sont enfreintes
- Associez le compte à votre CLIENT, et le site à votre SERVICE. Le deuxième
- Envoyez une clé d'idempotence à chaque création, dérivée de votre propre identifiant pour l'élément. Chaque
commande d'un client doit aboutir dans le compte qu'il possède déjà. Associez les deux au service et un client se retrouve avec trois comptes sans lien entre eux et trois panneaux de contrôle séparés.
système de facturation réessaie — le retour d'une passerelle arrive deux fois, un administrateur relance une provision échouée, un client clique deux fois. Sans cela, la deuxième tentative crée un deuxième site et vous êtes facturé pour celui-ci. Les modules et le client PHP font cela pour vous ; si vous appelez l'API directement, envoyez Idempotency-Key.
Trois champs qu'il est facile d'omettre
Chacun d'eux rompt un verbe entier, et aucun n'apparaît autrement que comme une erreur de validation — à l'exception du premier, qui apparaît comme rien du tout :
- ⛔⛔ Un client doit être rattaché à un forfait AVANT que son premier site ne soit provisionné, avec
POST /v1/reseller/clients/{orgId}/plan, et son subscription_id transmis à POST /v1/sites. C'est celui qui ne présente aucune erreur à lire. Un nouveau compte client ne contient aucun abonnement et POST /v1/sites n'a pas de champ de forfait, de sorte qu'un site provisionné sans forfait ne comporte aucun forfait du tout : votre relevé de gros est établi à partir des abonnements actifs de vos clients, aucune ligne n'est donc générée et Zinn® ne vous facture rien tant que l'hébergement fonctionne ; votre client ne bénéficie d'aucune allocation, aucun quota n'est donc appliqué à son site ; et il n'y a rien à modifier lors d'une mise à niveau. La commande renvoie 201, le site est provisionné, et il fonctionne parfaitement. Rien de part et d'autre ne signale quoi que ce soit de tout cela.
L'ordre a de l'importance : POST /v1/sites enregistre l'abonnement présent au moment où il s'exécute, de sorte qu'un forfait défini après coup ne s'applique pas de manière rétrospective.
POST /v1/sitesrequiertstack_type. Omettez-le et aucune commande ne pourra aboutir.- **
DELETE /v1/sites/{siteId}requiert un corps `{"confirm_domain": "<the site's own
domain>"}** — une confirmation saisie, car il s'agit du verbe destructeur. Omettez-la et aucune annulation ne pourra aboutir, de sorte que le service continue de fonctionner et que vous continuez d'être facturé pour cela. Lisez le domaine à partir de GET /v1/reseller/services/{siteId}` plutôt que d'utiliser votre propre enregistrement : il est comparé au domaine principal du site lui-même et jamais à un alias.
Lire l'erreur en entier, pas seulement la phrase
Le message de refus de validation est délibérément générique — "The request was well-formed but failed validation." — parce que la moitié exploitable se trouve dans details, qui nomme le champ et explique pourquoi. Les modules et le client PHP l'ajoutent tous deux au message qu'ils affichent à votre administrateur. Si vous appelez l'API vous-même, lisez error.details ; certaines entrées comportent une valeur brute plutôt qu'une phrase, ce qui explique comment max_sites: 0 vous parvient lorsque votre forfait revendeur n'a plus de place.
Avant votre première commande
Les sites achetés par vos clients sont décomptés de l'allocation de sites de votre propre forfait revendeur, vous avez donc besoin d'un forfait disposant de l'espace nécessaire. Un test de connexion ne peut pas détecter cela — il lit votre programme et ne provisionne rien — il signale donc un compte sain mais qui ne peut pas encore vendre. Une commande passée sans allocation est refusée avec un message explicitement formulé en ce sens.
Vérifiez votre téléchargement
Les deux archives sont servies via TLS depuis notre propre nom d'hôte, jamais redirigées ailleurs, avec leurs sommes de contrôle SHA-256 affichées à côté des liens de téléchargement sur la page des téléchargements.
Toujours bloqué ?
Le support est inclus dans chaque forfait et les réponses sont rédigées dans votre propre langue.
Contacter le support → Tous les articles →