Cơ sở tri thức

Bán dịch vụ lưu trữ Zinn® từ HostBill, Blesta hoặc hệ thống của riêng bạn

Bán dịch vụ lưu trữ Zinn® từ HostBill, Blesta hoặc hệ thống của riêng bạn: mô-đun HostBill miễn phí, ứng dụng PHP một tệp duy nhất, hai quy tắc gây tốn kém khi bị vi phạm và hai trường yêu cầu dễ bị bỏ sót.

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.

  1. Tải xuống và giải nén.
  2. Tải thư mục zinn lên includes/modules/Hosting/ để các tệp nằm tại
  3. includes/modules/Hosting/zinn/class.zinn.php và includes/modules/Hosting/zinn/ZinnHostBillClient.php.

  4. 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)
  1. 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.
  2. 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

  1. 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.
  2. 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.

Mới nhất từ blog

Những gì chúng tôi đã viết về lưu trữ web, SEO và vận hành trang web ở quy mô lớn.

SEO và xây dựng liên kết từ tầng lưu trữ: Góc nhìn của nhà vận hành năm 2026

Cách dịch vụ lưu trữ định hình việc lập chỉ mục và giá trị liên kết (link equity) vào năm 2026: giữ cho các trang luôn được lập chỉ mục, kiểm tra kỹ lưỡng các tên miền cũ trước khi xây dựng, xây dựng liên kết mà không để lại dấu vết (footprint), và một cái nhìn thẳng thắn về những gì cơ sở hạ tầng có thể và không thể làm cho SEO.

Đọc bài viết →

Giúp WordPress nhanh chóng và an toàn: Danh sách kiểm tra hiệu suất và plugin

Danh sách kiểm tra thực tế cho một trang WordPress nhanh và an toàn: lưu vào bộ nhớ đệm ở cấp độ máy chủ, bộ nhớ đệm đối tượng cho từng trang web, số ít plugin đáng sử dụng, duy trì ngăn xếp công nghệ luôn mới nhất và các trang WooCommerce mà quý vị tuyệt đối không bao giờ được lưu vào bộ nhớ đệm.

Đọc bài viết →

Cách chọn dịch vụ lưu trữ web được quản lý vào năm 2026: Hướng dẫn cho người mua

Điều thực sự tạo nên sự khác biệt giữa dịch vụ lưu trữ được quản lý tốt và một máy chủ giá rẻ có bảng điều khiển — di chuyển dữ liệu, sao lưu, cách ly, bộ nhớ đệm thực sự và khả năng mở rộng trung thực — và cách đánh giá dịch vụ đó trước khi bạn cam kết.

Đọc bài viết →

Đọc blog →

Vẫn gặp khó khăn?

Hỗ trợ được bao gồm trong mọi gói, bộ phận chăm sóc khách hàng hoạt động 24 giờ một ngày và quý khách có thể viết thư cho chúng tôi bằng bất kỳ ngôn ngữ nào trong số 58 ngôn ngữ của chúng tôi — chúng tôi sẽ trả lời quý khách bằng ngôn ngữ của quý khách.

Liên hệ hỗ trợ → Tất cả bài viết →