REST · JSON · X-API-Key

Tài liệu API CloudMoon

Tự động hoá việc mua và quản lý dịch vụ từ hệ thống của bạn — cùng giá, cùng luật và cùng ví tiền như khi thao tác trên web.

Trên trang này
  1. Bắt đầu nhanh
  2. Xác thực & khoá API
  3. Định dạng phản hồi
  4. Mã lỗi chung
  5. Giới hạn tần suất
  6. Chống trùng lệnh
  7. Chạy thử miễn phí
  8. Lệnh mua & theo dõi
  9. Phân trang
  10. Hoa hồng giới thiệu
  11. Tài khoản đại lý
  12. Client mẫu

Bắt đầu nhanh

  1. Tạo khoá API ở trang Khoá API (cần đăng nhập): đặt tên, chọn quyền Chỉ đọc hoặc Toàn quyền, có thể giới hạn IP được gọi. Khoá có dạng ak_ + 48 ký tự và xem lại được bất cứ lúc nào.
  2. Gọi thử một endpoint đọc — gửi khoá trong header X-API-Key:
Yêu cầu
curl 'https://cloudmoon.net/api/v1/account/info' \
  -H 'X-API-Key: ak_...'
Yêu cầu
import requests

r = requests.get(
    "https://cloudmoon.net/api/v1/account/info",
    headers={"X-API-Key": "ak_..."},
    timeout=30,
)
print(r.status_code, r.json())
Yêu cầu
// Node.js 18+ — lưu thành tệp .mjs

const res = await fetch("https://cloudmoon.net/api/v1/account/info", {
  headers: { "X-API-Key": "ak_..." },
});
console.log(res.status, await res.json());
Yêu cầu
// cm_api(): xem mục "Client mẫu" ở trang Tổng quan
$kq = cm_api('GET', '/v1/account/info');
print_r($kq);
  1. Chọn sản phẩm — mỗi sản phẩm có trang tham chiếu riêng: danh mục, báo giá, lệnh mua, thao tác, nhịp và mã lỗi riêng.
    • Cloud VPS — VPS thuê theo tháng ở nhiều khu vực — mua, gia hạn, nâng cấp và quản lý trọn vòng đời.
    • Cloud VPS theo giờ — VPS trả tiền theo giờ từ số dư — có máy sau vài phút, xoá là dừng tính tiền.
    • VPS Giá Rẻ — VPS giá tốt thuê theo tháng / năm — đặt mua, theo dõi bàn giao, gia hạn, gửi yêu cầu khởi động lại / cài lại hệ điều hành.
    • Dedicated Server — Máy chủ vật lý thuê theo tháng / năm — đặt mua, theo dõi bàn giao, gia hạn, gửi yêu cầu khởi động lại / cài lại hệ điều hành.
    • Domain — Tên miền quốc tế (.com, .net, …) — kiểm tên, báo giá, đăng ký (người đứng tên theo hồ sơ tài khoản, hoặc khai trong lệnh để đăng ký hộ), chuyển về, gia hạn, DNS.
    • Hosting — Hosting web (panel CyberPanel) thuê theo tháng / năm — mua là có ngay tài khoản panel, gia hạn, nâng gói, đổi chu kỳ, đổi mật khẩu, xoá.
    • SSL/TLS — Chứng chỉ SSL DV của Sectigo (1 tên miền / wildcard), 1–3 năm — mua, theo dõi xác minh tên miền, tải chứng chỉ, gia hạn, đổi chu kỳ, huỷ.

Địa chỉ gốc của mọi endpoint:

Base URL
https://cloudmoon.net/api/v1

Xác thực & khoá API

Mọi lượt gọi gửi khoá trong header X-API-Key. Khoá thuộc về tài khoản đã tạo nó: lệnh mua hay gia hạn trừ đúng ví của tài khoản ấy, và mỗi tài khoản chỉ thấy đơn của chính mình.

Quyền khoáGọi đượcKhông gọi được
Chỉ đọcMọi endpoint mang nhãn Chỉ đọc — danh mục, báo giá, trạng thái, nhật ký, làm mới trạng tháiLệnh tiêu tiền hoặc đổi trạng thái tài nguyên · thông tin đăng nhập · console
Toàn quyềnTất cả, kể cả mua, gia hạn, thao tác, xoá, và thông tin đăng nhập của tài nguyên đã sẵn sàng—

Mỗi endpoint trong tài liệu ghi rõ quyền khoá cần có (nhãn Chỉ đọc / Toàn quyền).

  • Mỗi tài khoản giữ tối đa 5 khoá còn hiệu lực. Tạo khoá phải nhập lại mật khẩu, và hệ thống gửi email báo cho chủ tài khoản.
  • Giới hạn IP (tuỳ chọn, theo từng khoá): mỗi dòng một địa chỉ IPv4 / IPv6 hoặc một dải CIDR (IPv4 từ /8, IPv6 từ /16), tối đa 20 dòng. Gọi từ IP khác ⇒ 403 IP_NOT_ALLOWED.
  • Hạn dùng (tuỳ chọn, theo từng khoá): quá hạn ⇒ 401 KEY_EXPIRED. Khi chuỗi khoá đang dùng có hạn, mọi phản hồi thành công mang header X-API-Key-Expires (ISO 8601) để script của bạn biết trước.
  • Tạm tắt: chủ tài khoản tắt khoá mà không thu hồi ⇒ 401 KEY_PAUSED cho tới khi bật lại.
  • Xoay khoá sinh chuỗi mới, giữ nguyên quyền · IP · hạn dùng; chuỗi cũ ngừng ngay hoặc dùng tiếp tối đa 7 ngày (chủ tài khoản chọn) để đổi script không gián đoạn.
  • Thu hồi có hiệu lực ngay ở lượt gọi kế tiếp. Đổi mật khẩu tài khoản không làm khoá hết hiệu lực — nghi lộ khoá thì thu hồi nó.
  • Khoá thiếu, sai hoặc đã thu hồi ⇒ 401 UNAUTHORIZED. Một IP gửi quá nhiều khoá sai trong một phút sẽ bị chặn tạm (429).
  • Giữ khoá ở máy chủ của bạn — đừng nhúng vào mã chạy trên trình duyệt hay ứng dụng phát cho người khác.

Định dạng phản hồi

Mọi phản hồi là JSON UTF-8 với cùng một phong bì. msg là câu tiếng Việt cho người đọc; mã máy đọc nằm ở code (khi lỗi) và ở mã trạng thái HTTP.

Thành công — HTTP 200 (lệnh mua trả về trước khi tài nguyên sẵn sàng, và yêu cầu gửi kỹ thuật: 202)
JSON
{
    "status": "success",
    "msg": "OK",
    "data": {
        "…": "…"
    }
}
Lỗi — HTTP 4xx / 5xx
JSON
{
    "status": "error",
    "code": "NOT_FOUND",
    "msg": "Không tìm thấy đơn"
}

Mã lỗi chung

Hãy rẽ nhánh theo code — câu chữ ở msg có thể được chỉnh cho dễ hiểu hơn bất cứ lúc nào. Bảng dưới gồm các mã mọi endpoint đều có thể trả; mỗi trang sản phẩm có thêm bảng mã lỗi riêng của sản phẩm ấy.

HTTPcodeÝ nghĩaNên làm gì
400 BAD_REQUEST Thiếu tham số hoặc tham số sai định dạng. Sửa lệnh theo msg rồi gửi lại.
400 SANDBOX_NOT_SUPPORTED Endpoint này chưa hỗ trợ chạy thử, hoặc lựa chọn của lệnh nằm ngoài phạm vi chạy thử mô phỏng được — lệnh gửi kèm X-Sandbox: 1 bị chối, KHÔNG được thực hiện. Bỏ header X-Sandbox nếu muốn chạy thật.
400 FAILED Hệ thống không thực hiện được lệnh. Với lệnh có trừ tiền: đừng gửi lại — liên hệ hỗ trợ kèm order_code.
401 UNAUTHORIZED Thiếu khoá, khoá sai hoặc khoá đã bị thu hồi. Kiểm header X-API-Key.
401 KEY_EXPIRED Khoá đã quá hạn dùng do chủ tài khoản đặt (hoặc chuỗi khoá cũ đã hết thời gian dùng tiếp sau khi xoay). Kéo dài hạn (nút Sửa) hoặc tạo khoá mới ở trang Khoá API. Header X-API-Key-Expires của mọi phản hồi thành công báo trước lúc chuỗi đang dùng hết hiệu lực.
401 KEY_PAUSED Khoá đang được chủ tài khoản tạm tắt. Bật lại ở trang Khoá API (cần mật khẩu tài khoản).
402 INSUFFICIENT_BALANCE Số dư không đủ (lệnh mua tính theo số dư khả dụng — đã trừ tiền các lệnh mua còn chờ tạo). Nạp thêm tiền rồi gửi lại.
403 FORBIDDEN Khoá không đủ quyền, hoặc API / endpoint chưa mở cho tài khoản của bạn. Dùng khoá Toàn quyền cho lệnh ghi.
403 IP_NOT_ALLOWED Khoá có giới hạn IP và IP gọi không nằm trong danh sách. Thêm IP vào khoá, hoặc tạo khoá khác.
404 NOT_FOUND Không tìm thấy gói / đơn, hoặc đơn không thuộc tài khoản của khoá. Kiểm order_code / product_id.
405 METHOD_NOT_ALLOWED Sai phương thức HTTP. Dùng đúng GET / POST như tài liệu.
409 IDEMPOTENCY_PENDING Lệnh mang cùng Idempotency-Key đang chạy hoặc bị ngắt giữa chừng, chưa rõ kết quả. Đừng tạo lệnh mới — hỏi endpoint info của sản phẩm, cần thì liên hệ hỗ trợ.
422 IDEMPOTENCY_MISMATCH Idempotency-Key này đã dùng cho một lệnh KHÁC (khác endpoint, khác thân lệnh hoặc query) — lệnh này CHƯA được thực hiện. Mỗi lệnh khác nhau dùng một khoá mới; gửi lại ĐÚNG lệnh cũ thì dùng lại khoá cũ.
429 RATE_LIMITED Vượt giới hạn tần suất của khoá (hoặc giới hạn lượt mua mỗi giờ). Chờ đúng số giây ở header Retry-After.
429 BUSY Hệ thống đang bận (ví dụ một lệnh mua khác của chính bạn đang được ghi nhận). Chờ Retry-After giây rồi gửi lại.
429 TOO_MANY_PENDING Đang có quá nhiều lệnh mua còn chờ — Cloud VPS: lệnh chờ tạo máy (gộp VPS tháng + theo giờ); Dedicated Server / VPS Giá Rẻ: đơn chờ bàn giao (gộp hai mảng). Hai trần tính riêng nhau. Đợi các lệnh / đơn ấy ready hoặc failed rồi đặt tiếp.
500 SERVER_ERROR Lỗi hệ thống. Thử lại sau ít phút.
500 FAILED Lệnh mua chưa được ghi nhận (chưa trừ tiền). Gửi lại — có thể dùng lại đúng Idempotency-Key.
503 SERVICE_DISABLED Bảo trì: một dịch vụ tạm dừng bán mới — danh mục gói, báo giá mua mới và lệnh mua nhận mã này, còn lệnh trên tài nguyên đang có vẫn chạy; hoặc toàn bộ API tạm dừng (mọi lệnh đều nhận mã này). Đọc /services/status, thử lại sau.
503 UNAVAILABLE Tính năng tạm thời chưa dùng được. Thử lại sau.

Lệnh mua Cloud VPS bị huỷ trước khi trừ tiền (ví dụ giá vừa thay đổi) báo lý do ở trường error.code của endpoint info; đơn VPS Giá Rẻ · Dedicated Server đã trừ tiền mà không bàn giao được thì bị huỷ và hoàn đủ (refunded_amount); hosting gặp sự cố sau khi trừ tiền mà không hoàn tất được cũng bị huỷ và hoàn đủ; riêng chứng chỉ SSL không cấp được (failed) thì không tự hoàn — bộ phận hỗ trợ xử lý; tên miền đã trừ tiền mà nhà đăng ký chối (failed) cũng không tự hoàn — bộ phận hỗ trợ xử lý — xem mục Lệnh mua & theo dõi.

Giới hạn tần suất

  • Mỗi khoá tối đa 120 lượt gọi / 60 giây (cửa sổ trượt, tính cả lượt lỗi). Mỗi phản hồi kèm X-RateLimit-Limit và X-RateLimit-Remaining (số lượt còn lại sau lượt này).
  • Mọi lời chối 429 đều kèm header Retry-After (giây) — chờ đúng chừng đó rồi gửi lại, đừng gửi dồn.
  • Sản phẩm có tài nguyên chạy thật (máy chủ…) còn có nhịp thao tác trên cùng một tài nguyên — xem mục Nhịp thao tác ở trang của sản phẩm ấy.

Giới hạn lệnh mua

Mỗi tài khoản, với lệnh mua qua API:

  • Cloud VPS (theo tháng và theo giờ, gộp chung): tối đa 3 lệnh mua đang chờ tạo máy (429 TOO_MANY_PENDING) và 10 lượt mua / giờ (429 RATE_LIMITED).
  • VPS Giá Rẻ · Dedicated Server (gộp chung): tối đa 3 đơn đã trả tiền mà chưa bàn giao (429 TOO_MANY_PENDING) và 10 lượt mua / giờ (429 RATE_LIMITED) — hai bộ đếm tính cả đơn đặt trên web, và tính riêng với Cloud VPS.
  • Hosting: 10 lượt mua / giờ (429 RATE_LIMITED) — đếm cả hosting mua trên web, tính riêng với các sản phẩm khác; không có giới hạn số đơn chờ vì lệnh mua xong ngay trong lượt gọi.
  • SSL: 10 lượt mua / giờ (429 RATE_LIMITED) — đếm cả chứng chỉ mua trên web, tính riêng với các sản phẩm khác; không có giới hạn số đơn đang chờ cấp.
  • Tên miền: 10 lượt mua + chuyển về / giờ (gộp chung, 429 RATE_LIMITED) — đếm cả lượt trên web, tính riêng với các sản phẩm khác; không có giới hạn số đơn chờ.

Số dư dùng để xét lệnh mua là số dư khả dụng — đã trừ tiền các lệnh mua Cloud VPS còn chờ tạo máy (lệnh chờ chưa trừ ví).

Chống trùng lệnh — Idempotency-Key

Mạng có thể đứt sau khi máy chủ đã nhận lệnh — gửi lại mù quáng là mua hoặc gia hạn hai lần. Endpoint có trừ tiền nhận header Idempotency-Key (ghi ở bảng tham số của endpoint); hãy kèm một chuỗi ngẫu nhiên duy nhất cho mỗi ý định:

Header
Idempotency-Key: 7f9c2e4b-1a2b-4c3d-9e8f-0123456789ab
  • Máy chủ giữ chỗ khoá trước khi trừ tiền. Gửi lại với cùng khoá ⇒ nhận lại đúng phản hồi lần đầu (cùng order_code, cùng mã HTTP, msg kết thúc bằng (replayed)) — không trừ tiền lần hai, kể cả khi hai lượt gửi cùng lúc.
  • Bí mật không được lưu để phát lại: mật khẩu, license, khoá riêng, lệnh cài agent… chỉ có trong câu trả lời lần đầu. Bản phát lại để các trường ấy là null và thêm secrets_omitted (danh sách tên trường đã bỏ) — đọc lại bằng endpoint thông tin đăng nhập của sản phẩm, với khoá Toàn quyền.
  • Lượt đầu còn đang chạy, hoặc bị ngắt giữa chừng nên chưa rõ kết quả ⇒ 409 IDEMPOTENCY_PENDING. Đừng tạo lệnh mới — hỏi endpoint info của sản phẩm xem tài nguyên đã đổi chưa, cần thì liên hệ hỗ trợ.
  • Lỗi xảy ra sau khi lệnh đã được nhận cũng được ghi nhớ theo khoá: gửi lại cùng khoá nhận lại đúng lỗi ấy. Sửa xong nguyên nhân muốn thử lại thì dùng khoá mới — riêng INSUFFICIENT_BALANCE thì khoá được nhả ngay, nạp tiền xong gửi lại đúng khoá cũ được.
  • Lệnh mới thì dùng khoá mới. Khoá được giữ 30 ngày, tách riêng theo từng tài khoản.

Chạy thử miễn phí — X-Sandbox: 1

Thêm header X-Sandbox: 1 vào lệnh mua, gia hạn hay thao tác: máy chủ kiểm y như lượt thật (quyền khoá, gói, trạng thái máy, nhịp thao tác, số dư…) — lượt thật sẽ lỗi thì lượt chạy thử cũng trả đúng lỗi ấy; qua hết thì trả kết quả mô phỏng cùng khuôn với phản hồi thật. Không trừ tiền, không tạo hay đổi tài nguyên nào. Mọi phản hồi của lượt chạy thử (kể cả lời chối) mang "sandbox": true và header X-Sandbox: 1. Bỏ header là chạy thật.

  • Lệnh mua chạy thử trả order_code dạng SANDBOX…. Hỏi info của sản phẩm với mã ấy (vẫn kèm X-Sandbox: 1): máy mẫu đi đúng các trạng thái của máy thật, rút gọn thời gian — Cloud VPS: queued rồi provisioning (khoảng 10 giây đầu), ready sau khoảng 40 giây; VPS Giá Rẻ · Dedicated Server: provisioning trong 60 giây đầu rồi ready; Hosting: ready ngay trong câu trả lời của lệnh mua; SSL: provisioning (bản ghi xác minh mẫu có sau khoảng 10 giây) rồi ready sau khoảng 40 giây; Tên miền: ready ngay trong câu trả lời của lệnh mua (chuyển về: provisioning khoảng 10 giây đầu rồi ready) — kèm IP và thông tin đăng nhập mẫu (SSL: chứng chỉ mẫu). Máy thật lâu hơn nhiều (Cloud VPS vài phút, đơn bàn giao vài giờ, chứng chỉ SSL thường 10–60 phút sau khi xác minh tên miền, chuyển tên miền về 5–7 ngày). Mã mang theo lựa chọn của lệnh mua (addon, tự gia hạn, trần giờ/tiền) nên máy mẫu đúng cấu hình và đúng giá bạn vừa đặt (riêng Hosting: mã chỉ mang gói, chu kỳ và cờ — giá, hạn mức dựng lại từ gói hiện hành mỗi lần hỏi; SSL: mã mang sản phẩm, số năm và cờ — chứng chỉ mẫu mang tên miền sandbox-….example; Tên miền: mã mang đuôi, số năm và cờ — tên miền mẫu là sandbox-….<đuôi>). Mã chạy thử dài tới 40 ký tự (mã thật 23) — chừa chỗ nếu bạn lưu mã.
  • Mã SANDBOX… dùng được ở mọi lệnh của sản phẩm ấy (bật/tắt, cài lại, gia hạn, xoá…) — đủ để chạy thử trọn vòng mua → chờ sẵn sàng → thao tác → xoá. Máy mẫu không lưu trạng thái: sau lệnh xoá mô phỏng, info vẫn trả máy mẫu; mã không xuất hiện trong list. Máy theo giờ mẫu tính giờ theo tuổi mã và bị xoá khi chạm trần đặt lúc thuê, như máy thật.
  • Với order_code thật của bạn, lệnh chạy thử kiểm trên chính máy ấy rồi trả mô phỏng — máy không bị đụng tới. Lệnh đọc (info, list, báo giá…) chạy như thường; sync chạy thử trả trạng thái đang lưu, không hỏi lại máy.
  • Ép ra một lỗi để thử nhánh xử lý: thêm X-Sandbox-Scenario: <MÃ> (cùng X-Sandbox: 1) ⇒ lượt chạy thử qua hết các bước kiểm rồi trả đúng mã lỗi ấy, phong bì có thêm "scenario". Mỗi endpoint chỉ nhận các mã nó thật sự trả được — danh sách nằm ở dòng Chạy thử của từng endpoint. Riêng PROVISION_FAILED ở lệnh mua: lệnh vẫn được nhận (202), info về sau báo failed — Cloud VPS kèm charged: false (chưa trừ tiền); VPS Giá Rẻ · Dedicated Server kèm refunded_amount (mô phỏng đơn đã trừ tiền rồi được hoàn); riêng Hosting, info đứng ở provisioning (mô phỏng đơn đã trừ tiền đang chờ kỹ thuật hoàn tất); SSL: info về failed sau khoảng 40 giây (mô phỏng chứng chỉ không cấp được — tiền đã trừ, không tự hoàn); Tên miền: info ở provisioning khoảng 10 giây đầu rồi failed (mô phỏng tiền đã trừ mà nhà đăng ký chối — không tự hoàn).
  • Endpoint chưa hỗ trợ chạy thử trả 400 SANDBOX_NOT_SUPPORTED — lệnh không được thực hiện. Gửi X-Sandbox-Scenario mà thiếu X-Sandbox: 1 cũng bị chối (400).
  • Idempotency-Key bị bỏ qua khi chạy thử (không tra, không lưu) — gửi thật về sau với cùng khoá vẫn chạy bình thường. Lượt chạy thử vẫn tính vào giới hạn tần suất và vẫn hiện trong nhật ký /account/logs.
Ví dụ — curl
curl -X POST 'https://cloudmoon.net/api/v1/cloudvps/buy' \
  -H 'X-API-Key: ak_...' -H 'X-Sandbox: 1' \
  -H 'Content-Type: application/json' \
  -d '{"product_id":526,"os_id":17,"billing_cycle":"onemonth"}'
Ví dụ — ép lỗi thiếu số dư
curl -X POST 'https://cloudmoon.net/api/v1/cloudvps/renew' \
  -H 'X-API-Key: ak_...' -H 'X-Sandbox: 1' -H 'X-Sandbox-Scenario: INSUFFICIENT_BALANCE' \
  -H 'Content-Type: application/json' \
  -d '{"order_code":"SANDBOX…"}'

Lệnh mua & theo dõi

Mỗi sản phẩm đi một trong 5 khuôn dưới đây — trang của sản phẩm nói rõ nó đi khuôn nào; bảng provision_status ở cuối mục dùng chung. Tạo một máy chủ có thể mất từ vài phút tới vài chục phút (đơn bàn giao: vài giờ), lâu hơn mọi trần chờ hợp lý của một lượt gọi HTTP, nên lệnh mua máy trả về ngay (HTTP 202) và bạn theo dõi bằng endpoint info của sản phẩm; hosting thì được tạo xong ngay trong lượt gọi; chứng chỉ SSL thì trừ tiền ngay và được cấp sau khi xác minh tên miền; tên miền thì trừ tiền và đăng ký xong ngay trong lượt gọi (chuyển về: chờ nhà đăng ký duyệt vài ngày).

Cloud VPS — máy được tạo tự động

  1. Gọi endpoint buy của sản phẩm — máy chủ kiểm tra hết (gói, cấu hình, số dư khả dụng, giới hạn lệnh mua) rồi trả HTTP 202 kèm order_code, provision_status: "queued".
  2. Hỏi endpoint info của sản phẩm (GET …/info?order_code=…) mỗi 15–30 giây tới khi provision_status là ready hoặc failed. Trong lúc ấy lệnh khác theo order_code có thể nhận 429 IN_PROGRESS (máy chưa tạo xong) hoặc 409 REBUILDING (máy đang khởi động) — chờ rồi gửi lại.
  3. Khi ready, khoá Toàn quyền đọc được thông tin đăng nhập (ip · username · password · port).

VPS Giá Rẻ · Dedicated Server — đơn bàn giao

  1. Endpoint buy kiểm hết rồi trừ ví ngay và trả HTTP 202 kèm order_code, provision_status: "provisioning", charged: true, total_charged và mốc dự kiến estimated_ready_at (không phải cam kết).
  2. Hỏi info thưa thôi — mỗi 5–10 phút — tới khi ready. Không bàn giao được ⇒ failed: đơn bị huỷ và hoàn đủ vào số dư (refunded_amount).
  3. Khi ready và dịch vụ đang hoạt động (order_status: "active"), khoá Toàn quyền đọc được thông tin đăng nhập; dịch vụ tạm ngưng vì quá hạn thì ẩn tới khi gia hạn.

Hosting — tạo xong ngay trong lượt gọi

  1. Endpoint buy kiểm hết rồi trừ ví và tạo tài khoản ngay trong lượt gọi (thường 10–20 giây — đặt thời gian chờ HTTP từ 90 giây): HTTP 200, provision_status: "ready", charged: true kèm thông tin đăng nhập panel — không cần hỏi info.
  2. Hiếm khi gặp sự cố sau lúc đã trừ tiền ⇒ HTTP 202, provision_status: "provisioning", charged: true và order_code: đơn đã tồn tại — đừng mua lại; hỏi info thưa thôi tới khi ready, hoặc failed + refunded_amount (đơn bị huỷ, hoàn đủ).

SSL — trừ tiền ngay, cấp chứng chỉ sau

  1. Endpoint buy kiểm hết rồi trừ ví ngay và trả HTTP 202: provision_status: "provisioning", charged: true, order_code và khối dcv (cách xác minh tên miền). Đơn đã tồn tại và đã trả tiền — đừng mua lại.
  2. Hỏi info mỗi 1–2 phút; tên miền không tự xác minh được thì thêm bản ghi CNAME ở dcv.record khi dcv.action_required: true. Xác minh xong, chứng chỉ thường được cấp sau 10–60 phút ⇒ ready, khoá Toàn quyền tải được chứng chỉ.
  3. Không cấp được ⇒ failed: tiền không tự hoàn — bộ phận hỗ trợ xử lý.

Tên miền — trừ tiền và đăng ký ngay trong lượt gọi

  1. Endpoint buy kiểm hết (kể cả người đứng tên) rồi trừ ví và đăng ký ngay trong lượt gọi (có thể tới khoảng một phút — đặt thời gian chờ HTTP từ 90 giây): thường HTTP 200, provision_status: "ready", charged: true — không cần hỏi info.
  2. Nhà đăng ký cần duyệt thêm ⇒ HTTP 202, provisioning, charged: true: đơn đã tồn tại — đừng mua lại; hỏi info tới ready. Lệnh chuyển tên miền về luôn đi đường này (nhà đăng ký cũ duyệt, thường 5–7 ngày).
  3. Đã trừ tiền mà nhà đăng ký chối ⇒ HTTP 200, provision_status: "failed", charged: true: tiền không tự hoàn — bộ phận hỗ trợ xử lý.
provision_statusCloud VPSVPS Giá Rẻ · Dedicated ServerHostingSSL
queuedLệnh đã nhận, đang xếp hàng.———
provisioningĐang tạo tài nguyên / máy đang khởi động.Đã trả tiền, đang chờ bàn giao.Gặp sự cố sau khi trừ tiền, đang được hoàn tất — hoặc đang chuyển máy chủ.Đã trả tiền, đang chờ xác minh tên miền / chờ cấp — hoặc đang gia hạn.
readySẵn sàng sử dụng.Đã bàn giao.Đã tạo — đọc thêm order_status / account_status (tạm ngưng vì quá hạn, bị khoá).Đã cấp — tải bằng download.
failedKhông tạo được — đọc charged và error.code.Không bàn giao được — đơn đã huỷ, refunded_amount là số đã hoàn.Không hoàn tất được — đơn đã huỷ, refunded_amount là số đã hoàn.Không cấp được — không tự hoàn, bộ phận hỗ trợ xử lý.
rebuilding(máy đang có) Đang cài lại hệ điều hành.— (cài lại là yêu cầu kỹ thuật, xem pending_action)——
expired · deleted— (đọc order_status)Hết hạn hẳn · đã xoá.Hết hạn hẳn · đã xoá (kể cả tài khoản bị dọn sau thời gian tạm ngưng).Gói đã quá hạn — còn gia hạn được trong thời gian tạm ngưng, quá thời gian ấy thì phải mua mới · —
cancelled———Đã huỷ (không hoàn tiền).

Tên miền dùng cùng các giá trị (provisioning đang đăng ký / chuyển về · ready · failed đã trừ tiền mà nhà đăng ký chối · expired quá hạn — còn gia hạn được trong thời gian tạm ngưng, quá thời gian ấy là hết hẳn · cancelled đã xoá khỏi danh sách), thêm suspended (bị tạm ngưng) và transferred_out (đã chuyển sang nhà đăng ký khác) — bảng đầy đủ ở trang Domain.

Trường charged của Cloud VPS — đã trừ tiền chưa?

  • false — chưa trừ đồng nào tới lúc này. Chỉ khi đi kèm provision_status: "failed" (ví dụ PRICE_CHANGED, hết hàng, thiếu số dư) mới chắc chắn không bao giờ trừ ⇒ lúc ấy đặt lại được, bằng Idempotency-Key mới. Còn queued thì lệnh vẫn sẽ được thực hiện — đừng đặt lại.
  • true — đã trừ tiền; đơn đã tồn tại — hỏi tiếp tới ready, đừng đặt lại.
  • null — đang trong lúc tạo, hoặc có sự cố cần kiểm tra. Đừng coi là chưa trừ và đừng gửi lệnh mua mới — hỏi tiếp, hoặc liên hệ hỗ trợ kèm order_code.

Đơn bàn giao và hosting trả charged: true ngay ở lệnh mua; info của chúng không có trường này — đọc provision_status và refunded_amount.

SSL trả charged: true ngay ở lệnh mua — tiền đã trừ dù chứng chỉ chưa cấp; info không có trường này — đọc provision_status. Đơn failed không tự hoàn tiền.

Tên miền trả charged: true ở lệnh mua và ở cả info / list — mọi đơn tên miền được tạo cùng lượt trừ tiền. Đơn failed không tự hoàn tiền.

Ví dụ — HTTP 202 (Cloud VPS)
{
    "status": "success",
    "msg": "Đã nhận lệnh mua — máy đang được tạo",
    "data": {
        "order_code": "071026CLOUDABCDEFGHIJKL",
        "status": "queued",
        "provision_status": "queued",
        "price_buy": 70000
    }
}
Ví dụ — HTTP 202 (VPS Giá Rẻ)
{
    "status": "success",
    "msg": "Đã nhận đơn — đang chờ bàn giao",
    "data": {
        "order_code": "101026VPSSVQWERTYUIOPAS",
        "order_status": "pending",
        "provision_status": "provisioning",
        "charged": true,
        "product_id": 69,
        "billing_cycle": "onemonth",
        "os_id": 86,
        "price_buy": 240000,
        "total_charged": 240000,
        "time_expire_moon": "2026-11-09",
        "estimated_ready_at": "2026-10-12T10:00:00+07:00",
        "note": "Đơn đã trừ tiền và đang chờ bàn giao — hỏi GET /vpssave/info?order_code= tới khi provision_status = ready"
    }
}
Ví dụ — HTTP 200 (Hosting)
{
    "status": "success",
    "msg": "Đã tạo hosting",
    "data": {
        "order_code": "121026HOSTA1B2C3D4E5F6",
        "domain": "khachhang.com",
        "provision_status": "ready",
        "charged": true,
        "product_id": 1,
        "billing_cycle": "onemonth",
        "price_buy": 50000,
        "time_expire": "2026-11-12",
        "panel": {
            "url": "https://panel.example.com:17777",
            "server_ip": "203.0.113.10",
            "username": "cm042a1b2c",
            "password": "Xy7kP2mQ9rT4vW1z",
            "ready_at": "2026-10-12T21:01:30+07:00"
        },
        "website_verified": true,
        "note": "Mật khẩu panel đọc lại được ở GET /hosting/info hoặc /hosting/credentials (khoá toàn quyền) — trỏ bản ghi A của tên miền về panel.server_ip"
    }
}
Ví dụ — HTTP 202 (SSL)
{
    "status": "success",
    "msg": "Đã nhận lệnh mua — chứng chỉ đang được cấp",
    "data": {
        "order_code": "131026SSLA1B2C3D4E5F6",
        "common_name": "khachhang.com",
        "type": "single",
        "product_id": 1,
        "product_code": "positive_ssl",
        "period": 1,
        "provision_status": "provisioning",
        "charged": true,
        "price_buy": 360000,
        "key_source": "server",
        "dcv": {
            "mode": "manual",
            "status": "pending",
            "record": null,
            "action_required": false
        },
        "note": "Bản ghi xác minh (dcv.record — CNAME) có ở GET /ssl/info?order_code= sau khoảng 1–3 phút: thêm vào DNS tên miền, chứng chỉ được cấp sau khi xác minh xong (POST /ssl/sync để kiểm tra ngay)."
    }
}
Ví dụ — HTTP 200 (Tên miền)
{
    "status": "success",
    "msg": "Đăng ký tên miền thành công",
    "data": {
        "order_code": "151026DOMAINHNFPVZRQWUOD",
        "domain": "ten-mien-cua-ban.com",
        "period": 1,
        "provision_status": "ready",
        "order_status": "active",
        "charged": true,
        "price_buy": 418950,
        "need_info": false,
        "time_expire": "2027-10-15",
        "registrant_source": "request",
        "note": "Tên miền đã đăng ký xong — quản lý DNS ở /domain/dns/*."
    }
}

Phân trang

Endpoint trả danh sách (…/list của từng sản phẩm · /account/logs) nhận limit (1–200, mặc định 50) và page (từ 1); phản hồi kèm page, limit, total để bạn biết còn trang sau không.

curl
curl 'https://cloudmoon.net/api/v1/account/logs?limit=50&page=2' \
  -H 'X-API-Key: ak_...'

Hoa hồng giới thiệu

Giao dịch thực hiện qua API — mua mới, chuyển tên miền về, gia hạn, đổi chu kỳ, nâng cấp, thuê theo giờ — không tính hoa hồng giới thiệu. Đơn mua qua API không tính hoa hồng ở mọi kỳ gia hạn về sau, kể cả gia hạn trên web. Chi tiết ở Điều khoản chương trình giới thiệu.

Tài khoản đại lý

Đại lý dùng cùng tài liệu, cùng khoá, cùng endpoint và cùng luật với mọi tài khoản. Điểm khác duy nhất là giá:

  • Sản phẩm có chiết khấu đại lý thì danh mục, báo giá và lệnh mua trả về (và trừ ví) giá đã trừ chiết khấu theo cấp đại lý — cho những khoản được chiết khấu (khoản thu một lần như phí lắp đặt, hay giá gia hạn, có thể khác — xem dòng dưới). Ở danh mục, amount là giá bạn trả, amount_original là giá niêm yết — tài khoản thường thấy hai số bằng nhau.
  • Mỗi trang sản phẩm ghi rõ ở dòng Giá đại lý (mục Tổng quan của trang) việc nào được chiết khấu, việc nào một giá cho mọi tài khoản.
  • GET /account/info trả cấp đại lý (reseller_level) và % chiết khấu từng dịch vụ (discounts); tài khoản thường nhận cùng các trường, chiết khấu bằng 0.
  • Muốn biết chắc số sẽ trừ cho một lệnh — mua mới hay gia hạn — gọi endpoint báo giá (quote) của sản phẩm ngay trước đó: số báo giá là đúng số trừ ví ở thời điểm báo. Báo giá không giữ giá: giá đổi trước khi lệnh tới thì lệnh trừ theo giá mới hoặc bị chối, tuỳ sản phẩm.

Client mẫu

Một hàm gọi chung cho mỗi ngôn ngữ: gắn khoá, gửi thân JSON với lệnh POST, trả về mã HTTP cùng phản hồi. Ví dụ PHP trong tài liệu dùng hàm cm_api() ở tab PHP; ví dụ curl, Python và JavaScript chạy được ngay, không cần hàm này. Ngôn ngữ khác chỉ cần làm đúng ba việc: header X-API-Key, thân JSON với lệnh POST, và đọc status / code của phản hồi.

Client
import requests

CM_API_KEY = "ak_..."    # khoá API — giữ ở máy chủ, đừng đưa vào mã phía trình duyệt
CM_API_BASE = "https://cloudmoon.net/api"   # path = "/v1/…" (mọi endpoint của tài liệu này)


def cm_api(method, path, body=None, idem=None):
    headers = {"X-API-Key": CM_API_KEY, "Accept": "application/json"}
    if idem:
        headers["Idempotency-Key"] = idem
    r = requests.request(method, CM_API_BASE + path, headers=headers,
                         json=None if method == "GET" else (body or {}), timeout=90)
    return r.status_code, r.json()


http, toi = cm_api("GET", "/v1/account/info")
print(toi["data"]["balance"] if toi.get("status") == "success" else "lỗi: %s" % toi.get("code", http))
Client
// Node.js 18+ — lưu thành tệp .mjs
const CM_API_KEY = "ak_...";    // khoá API — giữ ở máy chủ, đừng đưa vào mã phía trình duyệt
const CM_API_BASE = "https://cloudmoon.net/api";   // path = "/v1/…" (mọi endpoint của tài liệu này)

async function cmApi(method, path, body = {}, idem = "") {
  const headers = { "X-API-Key": CM_API_KEY, Accept: "application/json" };
  if (method !== "GET") headers["Content-Type"] = "application/json";
  if (idem) headers["Idempotency-Key"] = idem;
  const res = await fetch(CM_API_BASE + path, {
    method,
    headers,
    body: method === "GET" ? undefined : JSON.stringify(body),
  });
  return { http: res.status, body: await res.json() };
}

const toi = await cmApi("GET", "/v1/account/info");
console.log(toi.body.status === "success" ? toi.body.data.balance : `lỗi: ${toi.body.code ?? toi.http}`);
Client
<?php
const CM_API_KEY  = 'ak_...';             // khoá API — giữ ở máy chủ, đừng đưa vào mã phía trình duyệt
const CM_API_BASE = 'https://cloudmoon.net/api';             // $path = '/v1/…' (mọi endpoint của tài liệu này)

function cm_api(string $method, string $path, array $body = [], string $idem = ''): array
{
    $h = ['X-API-Key: ' . CM_API_KEY, 'Accept: application/json'];
    if ($method !== 'GET') $h[] = 'Content-Type: application/json';
    if ($idem !== '') $h[] = 'Idempotency-Key: ' . $idem;
    $ch = curl_init(CM_API_BASE . $path);
    curl_setopt_array($ch, [
        CURLOPT_CUSTOMREQUEST  => $method,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER     => $h,
        CURLOPT_POSTFIELDS     => $method === 'GET' ? null : json_encode($body ?: new stdClass()),
        CURLOPT_TIMEOUT        => 90,
    ]);
    $raw  = curl_exec($ch);
    $http = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    return ['http' => $http, 'body' => json_decode((string)$raw, true)];
}

$toi = cm_api('GET', '/v1/account/info');
echo $toi['body']['data']['balance'] ?? 'lỗi: ' . ($toi['body']['code'] ?? $toi['http']);
Zalo