Jeśli korzystają Państwo z WHMCS, prosimy użyć zamiast tego modułu WHMCS — ta strona jest przeznaczona dla wszystkich pozostałych przypadków. Dostępne są dwie opcje, obie bezpłatne i obie na licencji GPL-2.0-or-later.
HostBill
Moduł hostingowy oferujący te same sześć akcji, co moduł dla WHMCS.
- Proszę go pobrać i rozpakować.
- Proszę przesłać katalog
zinn do includes/modules/Hosting/, tak aby pliki znalazły się w
includes/modules/Hosting/zinn/class.zinn.php oraz includes/modules/Hosting/zinn/ZinnHostBillClient.php.
- Settings → Modules → Hosting, aktywować Zinn Digital® i dodać połączenie:
- API address:
https://api.zinndigital.com
- API key: Państwa klucz API Zinn® (pole typu
password, więc HostBill przechowuje go w postaci zaszyfrowanej)
- W produkcie należy ustawić Product line (np.
mainstream), Stack (domyślnie wordpress) oraz opcjonalnie Application i PHP version.
- Proszę nacisnąć Test connection.
⛔ Proszę nie zmieniać nazwy katalogu zinn. Mechanizm ładujący HostBill wywodzi poszukiwaną klasę z nazwy katalogu, więc zmiana nazwy spowoduje powstanie modułu, który panel wyświetla na liście, ale nigdy go nie wywołuje.
Wszystko inne — klient PHP
Jeden plik, brak zależności, brak założeń dotyczących panelu. Wystarczy umieścić ZinnProvisioning.php we własnej bazie kodu i wywołać sześć metod.
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));
Nie piszą Państwo w PHP? Te same wywołania znajdują się w dokumentacji API i można je wykonywać z poziomu dowolnego środowiska.
Klucz API
Siedem uprawnień i ani jednego więcej: org.create, org.read, sites.create, sites.view, sites.delete, reseller.view, reseller.provision.
⛔ Nie reseller.manage. Klucz wklejany do panelu rozliczeniowego powinien umożliwiać zablokowanie klienta z powodu braku płatności oraz jego zalogowanie; nie powinien jednak pozwalać na nadpisanie danych uwierzytelniających do Państwa własnej bramki płatności.
Dwie zasady, których złamanie wiąże się z kosztami
- Powiąż konto z KLIENTEM, a witrynę z USŁUGĄ. Drugie zamówienie
klienta musi trafić na konto, które już posiada. Jeśli powiążą Państwo oba elementy z usługą, jeden klient otrzyma trzy niepowiązane konta i trzy osobne panele administracyjne.
- Przy każdym tworzeniu przesyłaj klucz idempotencji (idempotency key), wygenerowany na podstawie własnego identyfikatora danego obiektu. Każdy
system bilingowy ponawia próby — wywołanie zwrotne z bramki dociera dwukrotnie, administrator ponownie uruchamia nieudane wdrożenie, klient klika dwukrotnie. Bez tego druga próba utworzy drugą witrynę, a Państwo zostaną za nią obciążeni opłatą. Zarówno moduły, jak i klient PHP robią to automatycznie; w przypadku bezpośredniego wywoływania API należy przesłać nagłówek Idempotency-Key.
Trzy pola, które łatwo pominąć
Każde z nich uniemożliwia poprawne działanie całej operacji i żadne nie objawia się inaczej niż jako błąd walidacji — z wyjątkiem pierwszego, które objawia się jako kompletnie nic:
- ⛔⛔ Klient musi zostać przypisany do planu PRZED zainicjowaniem jego pierwszej witryny, za pomocą
POST /v1/reseller/clients/{orgId}/plan, a jego parametr subscription_id musi zostać przekazany do POST /v1/sites. W tym przypadku żaden błąd nie zostanie wyświetlony. Nowe konto klienta nie zawiera żadnej subskrypcji, a punkt końcowy POST /v1/sites nie posiada pola planu, więc witryna zainicjowana bez niego nie posiada żadnego planu: Państwa zestawienie hurtowe jest generowane na podstawie aktywnych subskrypcji klientów, więc żadna pozycja nie zostanie naliczona i Zinn® nie pobierze od Państwa żadnych opłat przez cały czas działania hostingu; Państwa klient nie dziedziczy żadnych limitów, więc do jego witryny nie jest stosowany żaden przydział zasobów; nie ma również czego modyfikować w ramach uaktualnienia. Zamówienie zwraca kod 201, witryna zostaje zainicjowana i działa bez zarzutu. Żadna ze stron nie zgłasza w związku z tym jakichkolwiek problemów.
Kolejność ma znaczenie: POST /v1/sites rejestruje subskrypcję istniejącą w momencie jego uruchomienia, więc plan ustawiony później nie zostanie przypisany wstecznie.
POST /v1/sites wymaga parametru stack_type. W przypadku jego pominięcia żadne zamówienie nie zakończy się powodzeniem.
- **
DELETE /v1/sites/{siteId} wymaga treści `{"confirm_domain": "<the site's own
domain>"}** — wpisanego potwierdzenia, ponieważ jest to operacja destrukcyjna. W przypadku jej pominięcia żadne anulowanie nie zakończy się powodzeniem, w związku z czym usługa będzie nadal działać, a opłaty za nią będą nadal naliczane. Wartość domeny należy pobrać zwrotnie z GET /v1/reseller/services/{siteId}`, zamiast korzystać z własnych danych: jest ona porównywana z własną domeną podstawową witryny, a nigdy z aliasem.
Przeczytaj cały błąd, a nie tylko jedno zdanie
Komunikat o odrzuceniu walidacji jest celowo ogólny — „The request was well-formed but failed validation.” — ponieważ część wymagająca działania znajduje się w details, gdzie wskazano pole oraz przyczynę. Zarówno moduły, jak i klient PHP dołączają go do komunikatu wyświetlanego administratorowi. Jeśli wywołują Państwo API samodzielnie, należy odczytać error.details; niektóre wpisy zawierają samą wartość zamiast pełnego zdania — w ten sposób otrzymują Państwo max_sites: 0, gdy w Państwa planie resellerskim brakuje miejsca.
Przed pierwszym zamówieniem
Strony kupowane przez Państwa klientów wliczają się do limitu stron w Państwa planie resellerskim, dlatego potrzebują Państwo planu z wolnym miejscem. Test połączenia nie jest w stanie tego wykryć — odczytuje Państwa program i niczego nie wdraża — dlatego zgłasza w pełni sprawne konto, które nie może jeszcze sprzedawać. Zamówienie złożone bez dostępnego limitu zostanie odrzucone z komunikatem informującym dokładnie o tym.
Weryfikacja pobranego pliku
Oba archiwa są serwowane przez protokół TLS z naszej własnej nazwy hosta, bez przekierowań w inne miejsca, a ich sumy kontrolne SHA-256 są podane obok linków do pobrania na stronie pobierania.