Ако користите WHMCS, уместо овога користите WHMCS модул — ова страница је за све остало. Постоје две опције, обе бесплатне и обе под лиценцом GPL-2.0-or-later.
HostBill
Хостинг модул са истих шест радњи као и онај за WHMCS.
- Преузмите га и распакујте.
- Отпремите директоријум
zinn у includes/modules/Hosting/ тако да се датотеке нађу на
includes/modules/Hosting/zinn/class.zinn.php и includes/modules/Hosting/zinn/ZinnHostBillClient.php.
- Идите на Settings → Modules → Hosting, активирајте Zinn Digital® и додајте везу:
- API address:
https://api.zinndigital.com
- API key: ваш Zinn® API кључ (поље типа
password, тако да га HostBill чува шифрованог)
- На производу подесите Product line (нпр.
mainstream), Stack (подразумевано
wordpress), и по жељи Application и PHP version.
- Притисните Test connection.
⛔ Немојте преименовати директоријум zinn. HostBill-ов учитавач изводи класу коју тражи из назива директоријума, тако да преименовање производи модул који панел приказује, али га никада не позива.
Све остало — PHP клијент
Једна датотека, без зависности, без претпоставки о панелу. Убаците ZinnProvisioning.php у сопствену базу кода и позивајте шест метода.
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));
Не пишете у PHP-у? Исти позиви се налазе у API референци и можете их упутити из било чега.
API кључ
Седам дозвола, и ништа више: org.create, org.read, sites.create, sites.view, sites.delete, reseller.view, reseller.provision.
⛔ Не reseller.manage. Кључ који налепите у панел за наплату треба да има могућност суспендовања клијента због неплаћања и његовог пријављивања; не би требало да може да мења ваше сопствене приступне податке за платни пролаз.
Два правила чије кршење кошта
- Вежите налог за свог КЛИЈЕНТА, а сајт за своју УСЛУГУ. Друга поруџбина клијента
мора завршити на налогу који већ поседује. Ако оба вежете за услугу, један клијент завршава са три неповезана налога и три засебна контролна панела.
- Шаљите кључ идемпотентности при сваком креирању, изведен из вашег сопственог ID-ја за ту ставку. Сваки
систем за наплату покушава поново — повратни позив платног пролаза стигне двапут, администратор поново покрене неуспело провизионисање, клијент кликне двапут. Без тога, други покушај креира други сајт и то вам се наплаћује. Оба модула и PHP клијент ово раде уместо вас; ако директно позивате API, пошаљите Idempotency-Key.
Три поља која је лако изоставити
Свако од њих нарушава читав глагол, а ниједно се не приказује другачије осим као валидациона грешка — осим првог, које се приказује као апсолутно ништа:
- ⛔⛔ Клијент мора бити постављен на план ПРЕ него што се провизионише његов први сајт, помоћу
POST /v1/reseller/clients/{orgId}/plan, и његов subscription_id мора бити прослеђен у POST /v1/sites. Ово је оно код ког нема грешке за читање. Нови налог клијента не садржи претплату, а POST /v1/sites нема поље за план, па сајт провизионисан без њега не садржи никакав план: ваш велепродајни обрачун се формира на основу активних претплата ваших клијената, тако да се ставка не додаје и Zinn® вам не наплаћује ништа све док хостинг ради; ваш клијент не наслеђује дозвољене ресурсе, па се квота не примењује на његов сајт; и не постоји ништа што би надоградња могла да измени. Поруџбина враћа 201, сајт се провизионише и функционише беспрекорно. Ништа ни на једном крају не пријављује било шта од овога.
Редослед је важан: POST /v1/sites бележи ону претплату која постоји у тренутку његовог извршавања, тако да се накнадно постављени план не примењује ретроактивно.
POST /v1/sites захтева stack_type. Изоставите га и ниједна поруџбина неће успети.
- **
DELETE /v1/sites/{siteId} захтева тело `{"confirm_domain": "<the site's own
domain>"}** — укуцану потврду, јер је ово деструктивни глагол. Изоставите је и ниједно отказивање неће успети, па услуга наставља да ради и наставља да вам се наплаћује. Прочитајте домен назад из GET /v1/reseller/services/{siteId}` уместо да користите сопствени запис: он се пореди са примарним доменом самог сајта и никада са алијасом.
Прочитајте целу грешку, а не само реченицу
Порука одбијања услед валидације је намерно генеричка — "The request was well-formed but failed validation." — јер се део који захтева радњу налази у details, где се наводи поље и разлог. Оба модула и PHP клијент ово додају поруци коју приказују вашем администратору. Ако сами позивате API, прочитајте error.details; неки уноси садрже само вредност уместо реченице, што је начин на који вам стиже max_sites: 0 када на вашем reseller плану нема места.
Пре ваше прве поруџбине
Сајтови које ваши клијенти купе рачунају се у дозвољени број сајтова вашег reseller плана, тако да вам је потребан план са слободним местом. Тест везе ово не може да открије — он очитава ваш програм и не провизионише ништа — па пријављује исправан налог који још увек не може да продаје. Поруџбина постављена без преостале дозвољене квоте бива одбијена уз поруку која каже управо то.
Верификујте своје преузимање
Обе архиве се испоручују преко TLS-а са нашег сопственог хоста, никада се не преусмеравају на друго место, уз њихове SHA-256 контролне суме исписане поред веза за преузимање на страници за преузимања.