Skip to content
Hosting · Mod và gói mod

API cho tác giả gói mod: mã kích hoạt và cập nhật

Cách tác giả gói mod trả phí có thể phát hành mã kích hoạt và đăng cập nhật qua API của Millida Hosting: phiên bản gói mod, tải lên tệp lưu trữ, phát hành, khôi phục, trạng thái mã và webhook.

Cập nhật 6 tháng 9, 2026

Bạn không cần phải viết code. Mọi thứ mô tả bên dưới giờ đều có sẵn dưới dạng nút bấm: nếu gói mod của bạn đã được liên kết với tài khoản Millida, một tab “Gói mod của tôi” sẽ xuất hiện trong hồ sơ của bạn — tại đó bạn tải lên các phiên bản, chỉnh sửa thẻ và tạo landing page. Chưa liên kết — hãy viết cho chúng tôi và chúng tôi sẽ liên kết. API dành cho những ai triển khai từ CI riêng của mình.

Bài viết này dành cho các tác giả gói mod trả phí tự bán sản phẩm và giao phần cài đặt máy chủ cho chúng tôi. Người mua không phải tải bất cứ thứ gì: họ nhập mã và nhận được gói mod đã triển khai. Để xem nó trông như thế nào từ phía họ, hãy đọc Gói mod trả phí qua mã kích hoạt.

Những gì bạn cần để bắt đầu

  1. Gửi cho chúng tôi file lưu trữ máy chủ của gói mod — một file .zip có mods/ ở thư mục gốc (không có thư mục bao như Server Files/) hoặc một file .mrpack. File lưu trữ được lưu trong kho riêng tư của chúng tôi, và đường dẫn không bao giờ được chia sẻ ra bên ngoài.
  2. Cho chúng tôi biết core, phiên bản game và dung lượng bộ nhớ tối thiểu — trình hướng dẫn dùng chúng để lọc ra những gói không chạy được gói mod.
  3. Nhận từ chúng tôi một khóa gói mod (key, ví dụ arcania) và một token phát hành — trang web của bạn dùng nó để tạo mã.

Token chỉ được hiển thị một lần: chúng tôi chỉ lưu dấu vân tay của nó. Nếu bạn làm mất, hãy yêu cầu chúng tôi cấp lại — token cũ sẽ ngừng hoạt động.

Cách thức hoạt động

  • Bạn tự nhận thanh toán, ở phía bạn.
  • Sau khi thanh toán, trang web của bạn gọi API của chúng tôi và nhận một mã kích hoạt.
  • Bạn đưa mã cho người mua — qua email, bot, hoặc trên trang “cảm ơn”.
  • Người mua nhập mã ở phía chúng tôi và nhận một máy chủ có gói mod trên gói đã trả phí.
  • Các file gói mod trên máy chủ bị khóa: không thể tải mods từ bảng điều khiển hoặc qua SFTP.

Về mặt thực tế, người mua không bao giờ cầm được gói mod máy chủ trong tay — chỉ có một máy chủ đang hoạt động.

Endpoint và xác thực

Base URL — https://millida.net/v2/hosting.

Token được truyền trong header X-Pack-Token. Đây không phải JWT hay Bearer token — mà là một secret riêng cho gói mod của bạn.

X-Pack-Token: mpk_pack_XXXXXXXXXXXXXXXX
Content-Type: application/json

Token nằm trên máy chủ của bạn — hãy giữ nó trong biến môi trường, không phải trong code frontend.

Phát hành mã

POST /v2/hosting/packs/{key}/keys

TrườngKiểuMặc địnhChức năng
countsố 1–2001Số mã tạo ra mỗi lần gọi
notechuỗi tối đa 120—Ghi chú của bạn: số đơn hàng, nickname người mua
maxServerssố 1–201Một mã có thể kích hoạt trên bao nhiêu máy chủ
expiresAtngày ISO—Ngày hết hạn của mã
curl -X POST https://millida.net/v2/hosting/packs/arcania/keys \
  -H "X-Pack-Token: $PACK_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"count": 1, "note": "order 4821"}'
{
  "code": "A7K2-9MHD-4RTP-QW38",
  "codes": ["A7K2-9MHD-4RTP-QW38"]
}

Trường code là mã đầu tiên trong lô, được giữ để tương thích; khi count > 1, hãy dùng codes.

Mã chỉ được trả về ở đây và không nơi nào khác. Chúng tôi lưu hash của chúng — giống như mật khẩu. Nếu bạn làm mất một mã, chúng tôi không thể khôi phục: hãy phát hành mã mới và thu hồi mã cũ.

Giới hạn là 30 yêu cầu mỗi phút cho mỗi gói mod. Các lô tối đa 200 mã mỗi lần gọi tồn tại chính là để bán hàng: hãy tạo hàng loạt thay vì một mã mỗi yêu cầu.

Điều gì đã xảy ra với các mã

GET /v2/hosting/packs/{key}/keys?limit=100

[
  {
    "codeHint": "A7K29MHD",
    "note": "order 4821",
    "maxServers": 1,
    "usedCount": 1,
    "state": "spent",
    "expiresAt": null,
    "revokedAt": null,
    "createdAt": "2026-08-03T12:20:11.000Z"
  }
]

Bản thân các mã không có trong phản hồi và không thể có. codeHint là phần đầu của mã — dùng nó để khớp dòng với đơn hàng của bạn.

Các trạng thái: free — chưa dùng, spent — đã dùng, expired — đã hết hạn, revoked — đã bị bạn thu hồi.

Kiểm tra một mã

POST /v2/hosting/packs/{key}/keys/status, body {"code": "A7K2-9MHD-4RTP-QW38"}.

Phản hồi là cùng một dòng như trong danh sách. Mã được đặt trong body, không phải trong URL: URL sẽ lọt vào log proxy và lịch sử trình duyệt, và trước khi kích hoạt thì mã chính là một chìa khóa đang hoạt động.

Dấu gạch nối và chữ hoa chữ thường không quan trọng: a7k29mhd4rtpqw38 sẽ được tìm thấy giống như A7K2-9MHD-4RTP-QW38.

Thu hồi một mã

POST /v2/hosting/packs/{key}/keys/revoke, body {"code": "..."}.

Dùng nó cho việc hoàn tiền, phát hành nhầm hoặc tranh chấp. Thu hồi sẽ chặn các kích hoạt trong tương lai nhưng không gỡ bỏ gói mod đã triển khai — người mua đã kích hoạt vẫn giữ một máy chủ đang hoạt động.

Webhook kích hoạt

Nếu bạn cung cấp cho chúng tôi một URL webhook, chúng tôi sẽ gọi nó ngay khi một mã được sử dụng:

POST <your-address>
X-Millida-Pack: arcania
Content-Type: application/json

{
  "event": "pack.activated",
  "packKey": "arcania",
  "codeHint": "A7K29MHD",
  "serverId": "cm4x...",
  "activatedAt": "2026-08-04T09:14:02.000Z"
}

Cuộc gọi không được ký: bạn có thể xác minh nó bằng chính token đó qua keys/status — dùng codeHint bạn sẽ tìm thấy dòng của mình và thấy state: "spent". Như vậy bạn không phải lưu một secret thứ hai.

Webhook được gửi đi mà không chờ phản hồi và không được thử lại: nếu máy chủ của bạn đang ngừng hoạt động, việc kích hoạt vẫn diễn ra, và bạn có thể thấy nó trong danh sách mã. URL phải công khai — chúng tôi không gọi địa chỉ nội bộ hay cục bộ. Chuyển hướng không được theo dõi.

Thẻ gói mod

GET /v2/hosting/packs/{key} là công khai, không cần token. Nó trả về những gì người mua thấy: tên, core, phiên bản, bộ nhớ tối thiểu, danh sách gói và các cờ bảo vệ. Không có đường dẫn file lưu trữ trong phản hồi.

Tiện cho trang “Mua” trên trang web của bạn: yêu cầu về gói đến từ một nguồn duy nhất và sẽ không lệch với những gì trình hướng dẫn của chúng tôi nói.

Bạn tự chỉnh sửa các trường trưng bày của thẻ: PATCH /v2/hosting/packs/{key} với token chấp nhận name, authorName, authorUrl, iconUrl, webhookUrl. Các điều khoản bán hàng (paidOnly, requireKey, lockFiles, planCodes), việc bật gói mod trong cửa hàng và các cờ khởi chạy JVM không thể thay đổi bằng token — đó là thỏa thuận của chúng ta với bạn và các node của chúng tôi, nên hãy viết cho chúng tôi về chúng.

Cập nhật gói mod

Trước đây, một bản cập nhật nghĩa là gửi email cho chúng tôi và chờ đợi. Giờ đây bạn tự phát hành một phiên bản, và các chủ máy chủ tự chọn nó trong bảng điều khiển của họ.

Điểm mấu chốt: chúng tôi không bao giờ cập nhật cho ai một cách âm thầm. Việc chuyển đổi giữa các phiên bản gói mod có thể không tương thích với thế giới, và chủ máy chủ là người đưa ra quyết định. Phiên bản đã phát hành là phiên bản mà các máy chủ mới nhận được và là phiên bản chúng tôi đề nghị cho những máy chủ đã triển khai; các phiên bản trước vẫn nằm trong danh sách, và bạn có thể ở lại với chúng hoặc quay lui.

Chu trình trông như thế nào

# 1. Create a version
curl -X POST https://millida.net/v2/hosting/packs/arcania/versions \
  -H "X-Pack-Token: $PACK_TOKEN" -H "Content-Type: application/json" \
  -d '{"label":"1.5.0","changelog":"Updated Create to 0.5.1, fixes crash on portals","minRamMb":10240}'

# 2. Upload the archive in chunks (32 MB each), addressing by offset
curl -X POST "https://millida.net/v2/hosting/packs/arcania/versions/1.5.0/archive?offset=0" \
  -H "X-Pack-Token: $PACK_TOKEN" -H "Content-Type: application/octet-stream" \
  --data-binary @part0.bin

# 3. Say the archive is finished, and publish after parsing
curl -X POST https://millida.net/v2/hosting/packs/arcania/versions/1.5.0/finish \
  -H "X-Pack-Token: $PACK_TOKEN" -H "Content-Type: application/json" \
  -d '{"archiveSha256":"<sha256 of archive>","publish":true}'

# 4. Wait for parsing
curl https://millida.net/v2/hosting/packs/arcania/versions/1.5.0 -H "X-Pack-Token: $PACK_TOKEN"

Phiên bản

TrườngKiểuCông dụng
labelchuỗi tối đa 40 ký tựSố phiên bản: chữ cái Latin, chữ số, dấu chấm, dấu gạch ngang, dấu gạch dưới. Không thể thay đổi: cùng một label với các tệp khác nhau sẽ biến việc điều tra khiếu nại thành phỏng đoán
changelogchuỗi tối đa 4000 ký tựNhững gì đã thay đổi — chủ máy chủ đọc phần này trước khi cập nhật
core, gameVersionchuỗiNếu cấu hình máy chủ đã chuyển sang core hoặc phiên bản game khác
loaderBuild, javaVersionchuỗiGhim bản dựng loader và Java, nếu phiên bản đó cần
minRamMbsốMức RAM tối thiểu cho riêng phiên bản này. Ai không đủ sẽ thấy lý do và không bị mất thế giới của mình
archiveSha256hex 64Chúng tôi xác minh trước khi phân tích: thà từ chối một tệp nén chưa đến đầy đủ còn hơn giải nén nó dở dang

Tải lên

POST /v2/hosting/packs/{key}/versions/{label}/archive?offset=N, body — một phần của tệp .zip, Content-Type: application/octet-stream. Mỗi phần tối đa 32 MB, toàn bộ tệp nén tối đa 4 GB.

Mỗi phần được định địa chỉ bằng offset, không phải “nối vào cuối”: một phần bị ngắt giữa chừng đã ghi một phần vào tệp, và lần thử lại sẽ nối lại đúng số byte đó lần thứ hai — tệp nén sẽ hỏng một cách âm thầm. Phản hồi trả về uploadedBytes, dùng để tiếp tục tải lên sau khi bị gián đoạn.

Phân tích

POST .../finish phản hồi ngay (status: "processing"), trong khi quá trình phân tích chạy nền: giải nén một cấu hình máy chủ cỡ gigabyte mất vài phút. Đọc trạng thái từ GET .../versions/{label}: processing → ready hoặc failed kèm văn bản lý do trong error.

Tệp nén phải đáp ứng những điều sau:

  • đây là gói máy chủ: sau khi gỡ lớp bọc duy nhất (Server Files/ và tương tự), mods/ hoặc plugins/ nằm ở thư mục gốc. Gói client đặt trên máy chủ sẽ tạo ra thế giới trống, nên chúng tôi từ chối thay vì cài đặt;
  • không có .., đường dẫn tuyệt đối hay dấu phân cách Windows trong tên bên trong tệp nén;
  • không có mật khẩu, không dùng phương thức nén lạ (chỉ store và deflate);
  • giới hạn: 60.000 tệp, 12 GB sau khi giải nén, tỷ lệ nén tối đa 200×.

Thất bại không ảnh hưởng đến phiên bản đã phát hành: người chơi của bạn vẫn chạy phiên bản trước đó, và bạn tải lên lại. Bản nháp chưa hoàn thành: không quá ba bản cho mỗi cấu hình máy chủ, những bản bị bỏ sẽ được dọn tự động sau một ngày.

Phát hành, khôi phục và xóa

Yêu cầuCông dụng
POST .../versions/{label}/publishĐưa phiên bản vào phát hành. Đây cũng là cách khôi phục: phát hành phiên bản trước — máy chủ mới sẽ nhận lại nó
POST .../versions/{label}/archive-versionGỡ phiên bản khỏi danh sách chọn. Ai đã có thì vẫn giữ
PATCH .../versions/{label}Sửa mô tả của phiên bản đã tạo: changelog và minRamMb. Tệp của phiên bản là bất biến, nên core, loader và Java không thay đổi
DELETE .../versions/{label}Xóa phiên bản cùng các tệp của nó. Bạn không thể xóa phiên bản đã phát hành hoặc đang chạy trên ít nhất một máy chủ
GET .../versionsCác phiên bản có thể chọn (công khai, không cần token)
GET .../versions/allTất cả phiên bản của bạn, kể cả bản nháp và bản lỗi
GET .../versions/rolloutCó bao nhiêu máy chủ đang ở phiên bản nào — bạn thấy được quá trình cập nhật đang triển khai ra sao

Phát hành sẽ chuyển core, phiên bản game, ghim loader, Java và mức RAM tối thiểu của phiên bản vào thẻ cấu hình máy chủ: máy chủ mới nhận được mà bạn không cần làm gì thêm.

Chủ máy chủ thấy gì

Trong bảng điều khiển, ở khối cấu hình máy chủ premium: phiên bản nào đang cài, phiên bản nào đã phát hành, changelog của bạn, và danh sách phiên bản kèm nút “Chuyển”. Việc cập nhật không ảnh hưởng đến thế giới — chỉ các tệp cấu hình máy chủ được thay, và chúng tôi sao lưu trước khi thay. Các mod tùy chỉnh, nếu bạn cho phép, sẽ phải thêm lại sau khi chuyển: cấu hình máy chủ chuyển nguyên khối, và việc còn sót một nửa phiên bản cũ trong mods/ nghĩa là crash khi khởi động.

Nếu gói của chủ máy chủ không đáp ứng được một phiên bản, chúng tôi hiển thị điều đó kèm lý do thay vì ẩn đi: người ta nên thấy mình cần gì, chứ không phải đoán vì sao cấu hình máy chủ không cập nhật.

Trang cấu hình máy chủ của riêng bạn

Bạn tự dựng trang đích cho cấu hình máy chủ của mình trong tài khoản (hồ sơ → “Cấu hình máy chủ của tôi” → “Trang cấu hình máy chủ”): màn hình đầu, tính năng, ảnh chụp, hỏi đáp, màu sắc của bạn. Các gói và danh sách phiên bản được điền bằng dữ liệu của chúng tôi để không bị lỗi thời.

Trang hoàn chỉnh nằm tại millida.net/sborka/<địa-chỉ-của-bạn> — một trang web thông thường, được công cụ tìm kiếm lập chỉ mục và đưa vào sitemap của chúng tôi. Bản nháp không ai thấy ngoài bạn.

Ảnh được tải lên cùng chỗ, trong tài khoản của bạn: trang được phục vụ từ tên miền của chúng tôi, và các tệp của nó được lưu với chúng tôi — nếu hosting của bạn sập, trang vẫn nguyên vẹn.

Không thể sửa trang qua API: đây là một màn hình, không phải một đợt triển khai.

Mã phản hồi

MãKhi nàoCần làm gì
403Token phát hành không hợp lệKiểm tra X-Pack-Token. Token gắn với một cấu hình máy chủ: nó không hoạt động với key của người khác
404Cấu hình máy chủ bị tắt, chưa kết nối với phát hành, hoặc không có phiên bản đóViết cho chúng tôi
400Ngày expiresAt không phân tích được, label phiên bản sai, phần tải lên trống hoặc quá lớnXem văn bản lỗi
409Phiên bản đã được tạo, đã phân tích, đã phát hành, hoặc đã cài trên máy chủLabel là bất biến: hãy phát hành phiên bản tiếp theo
429Hơn 30 yêu cầu mỗi phút (tải lên — 600)Gửi theo lô, và gửi các phần lớn hơn

Cách kiểm thử mọi thứ trước khi bán

Hãy hỏi chúng tôi vài mã thử nghiệm: phát hành một mã qua API, kích hoạt nó trên máy chủ của bạn tại hosting của chúng tôi, xem thứ đến trong webhook và thứ keys/status hiển thị. Như vậy bạn sẽ thấy toàn bộ hành trình của người mua trước khi khách trả tiền đầu tiên đi qua nó.

Hosting MinecraftMáy chủ của bạn chạy khi bạn offlineTạo máy chủ