Nếu quý vị đang chạy WHMCS, vui lòng sử dụng mô-đun WHMCS thay thế — trang này dành cho tất cả các trường hợp khác. Có hai tùy chọn, cả hai đều miễn phí và đều theo giấy phép GPL-2.0-or-later.
HostBill
Một mô-đun hosting với sáu tác vụ tương tự như mô-đun WHMCS.
- Tải xuống và giải nén.
- Tải thư mục
zinn lên includes/modules/Hosting/ để các tệp nằm tại
includes/modules/Hosting/zinn/class.zinn.php và includes/modules/Hosting/zinn/ZinnHostBillClient.php.
- Settings → Modules → Hosting, kích hoạt Zinn Digital®, và thêm một kết nối:
- API address:
https://api.zinndigital.com
- API key: khóa API Zinn® của quý vị (một trường
password, vì vậy HostBill sẽ lưu trữ dưới dạng mã hóa)
- Trên sản phẩm, hãy thiết lập Product line (ví dụ:
mainstream), Stack (mặc định là wordpress), và tùy chọn Application cùng PHP version.
- Nhấn Test connection.
⛔ Không đổi tên thư mục zinn. Trình tải của HostBill suy ra lớp mà nó tìm kiếm từ tên thư mục, vì vậy việc đổi tên sẽ tạo ra một mô-đun mà bảng điều khiển liệt kê nhưng không bao giờ gọi.
Các trường hợp khác — PHP client
Một tệp duy nhất, không phụ thuộc, không giả định về bảng điều khiển. Đặt ZinnProvisioning.php vào cơ sở mã của quý vị và gọi sáu phương thức.
require_once 'ZinnProvisioning.php';
$zinn = new ZinnProvisioning(getenv('ZINN_API_KEY'));
// Khi đơn hàng được thanh toán — một lần cho mỗi CUSTOMER, sau đó một lần cho mỗi SERVICE:
$orgId = $zinn->account('customer-4211', 'Acme Ltd');
$siteId = $zinn->provision('service-9915', $orgId, 'acme.com', 'mainstream', 'wordpress');
// Lưu $orgId cho khách hàng của quý vị và $siteId cho dịch vụ của quý vị.
$zinn->suspend($siteId, 'INV-2026-114 unpaid'); // hóa đơn chưa thanh toán
$zinn->unsuspend($siteId); // họ thanh toán
$zinn->terminate($siteId); // họ hủy — lên lịch xóa
// Khi họ nhấp vào "đăng nhập vào hosting của tôi" — khởi tạo nó khi NHẤP CHUỘT, không bao giờ khởi tạo khi hiển thị trang:
header('Location: ' . $zinn->signInLink($siteId));
Quý vị không lập trình bằng PHP? Các lệnh gọi tương tự đều có trong Tài liệu tham khảo API và quý vị có thể thực hiện chúng từ bất kỳ đâu.
Khóa API
Bảy quyền hạn, và không có quyền nào khác: org.create, org.read, sites.create, sites.view, sites.delete, reseller.view, reseller.provision.
⛔ Không phải reseller.manage. Khóa mà quý vị dán vào bảng thanh toán chỉ nên có quyền tạm ngưng khách hàng vì không thanh toán và đăng nhập cho họ; khóa này không được phép ghi đè thông tin xác thực cổng thanh toán của chính quý vị.
Hai quy tắc gây tốn tiền nếu bị vi phạm
- Khóa tài khoản theo CUSTOMER của quý vị, và trang web theo SERVICE của quý vị. Đơn hàng thứ hai của khách hàng phải được đưa vào tài khoản mà họ đã có. Nếu khóa cả hai theo dịch vụ, một khách hàng sẽ có ba tài khoản không liên quan và ba bảng điều khiển riêng biệt.
- Gửi một idempotency key cho mỗi lần tạo, được lấy từ mã định danh của chính quý vị cho mục đó. Mọi hệ thống thanh toán đều thử lại — một phản hồi cổng thanh toán gửi tới hai lần, quản trị viên chạy lại một tác vụ khởi tạo không thành công, khách hàng nhấp đúp. Nếu không có nó, lần thử thứ hai sẽ tạo ra trang web thứ hai và quý vị sẽ bị tính phí cho trang web đó. Cả hai mô-đun và PHP client đều thực hiện việc này cho quý vị; nếu quý vị đang gọi trực tiếp API, hãy gửi
Idempotency-Key.
Ba trường dễ bị bỏ sót
Mỗi trường này sẽ làm hỏng toàn bộ một hành động, và không có trường nào hiển thị bất cứ điều gì ngoài một lỗi xác thực — ngoại trừ trường đầu tiên, vốn hiển thị là không có gì cả:
- ⛔⛔ Khách hàng phải được chỉ định một gói TRƯỚC KHI trang web đầu tiên của họ được khởi tạo, bằng
POST /v1/reseller/clients/{orgId}/plan, và subscription_id của gói đó được chuyển đến POST /v1/sites. Đây là trường hợp không có lỗi nào hiển thị để đọc. Một tài khoản khách hàng mới không có gói đăng ký nào và POST /v1/sites không có trường gói dịch vụ, vì vậy một trang web được khởi tạo mà không có gói dịch vụ sẽ hoàn toàn không mang gói nào: bảng sao kê bán buôn của quý khách được tạo từ các gói đăng ký đang hoạt động của khách hàng, do đó không có mục nào được tạo và Zinn® không tính phí quý khách trong suốt thời gian dịch vụ lưu trữ hoạt động; khách hàng của quý khách không kế thừa bất kỳ hạn mức nào, vì vậy không có hạn ngạch nào được áp dụng cho trang web của họ; và không có gì để nâng cấp có thể thay đổi. Đơn hàng trả về 201, trang web được khởi tạo và phục vụ hoàn hảo. Không có đầu nào báo cáo bất kỳ điều gì về việc này.
Thứ tự thực hiện rất quan trọng: POST /v1/sites ghi nhận bất kỳ gói đăng ký nào tồn tại tại thời điểm nó chạy, do đó một gói được thiết lập sau đó sẽ không được áp dụng hồi tố.
POST /v1/sites yêu cầu stack_type. Nếu bỏ qua nó, không có đơn hàng nào có thể thành công.
DELETE /v1/sites/{siteId} yêu cầu phần thân {"confirm_domain": "<the site's own domain>"} — một xác nhận bằng văn bản nhập vào, vì đây là hành động mang tính phá hủy. Nếu bỏ qua nó, không có yêu cầu hủy nào có thể thành công, do đó dịch vụ vẫn tiếp tục chạy và quý khách vẫn tiếp tục bị tính phí. Hãy đọc lại miền từ GET /v1/reseller/services/{siteId} thay vì sử dụng bản ghi của chính quý khách: miền này được so sánh với miền chính của trang web chứ không bao giờ so sánh với bí danh.
Đọc toàn bộ lỗi, không chỉ mỗi câu thông báo
Thông báo từ chối xác thực được cố ý để ở dạng chung chung — "The request was well-formed but failed validation." — vì phần thông tin hữu ích nằm trong details, nơi nêu rõ trường và lý do. Cả hai mô-đun và PHP client đều thêm phần này vào thông báo mà chúng hiển thị cho quản trị viên của quý khách. Nếu quý khách tự gọi API, hãy đọc error.details; một số mục chỉ chứa một giá trị đơn thuần thay vì một câu hoàn chỉnh, đó là cách max_sites: 0 hiển thị tới quý khách khi gói đại lý của quý khách không còn chỗ trống.
Trước đơn hàng đầu tiên của quý khách
Các trang web mà khách hàng của quý khách mua sẽ được tính vào hạn mức trang web của gói đại lý của quý khách, vì vậy quý khách cần một gói còn chỗ trống. Việc kiểm tra kết nối không thể phát hiện ra điều này — nó chỉ đọc chương trình của quý khách và không khởi tạo bất kỳ thứ gì — vì vậy nó báo cáo một tài khoản hoạt động tốt nhưng thực tế chưa thể bán hàng. Một đơn đặt hàng được gửi mà không có hạn mức sẽ bị từ chối kèm theo một thông báo nêu chính xác điều đó.
Xác minh tệp tải xuống của quý khách
Cả hai kho lưu trữ đều được phân phối qua TLS từ chính tên máy chủ của chúng tôi, không bao giờ bị chuyển hướng đi nơi khác, với mã kiểm tra SHA-256 được in bên cạnh các liên kết tải xuống trên trang tải xuống.