Mã lỗi và mã trạng thái HTTP
Mọi lỗi đều trả về một mã cố định để máy đọc, kèm mã trạng thái HTTP. Hãy rẽ nhánh xử lý theo mã, không bao giờ theo nội dung thông báo. Thông báo viết cho người đọc và có thể được sửa câu chữ, còn mã là một phần của hợp đồng API.
Toàn bộ 42 mã lỗi mà API đại lý có thể trả về, nhóm theo loại sự cố. Mỗi mục ghi rõ mã trạng thái HTTP đi kèm và việc cần làm để khắc phục.
Xác thực (401)
| Mã | HTTP status | Ý nghĩa | Cách khắc phục |
|---|---|---|---|
| MISSING_API_KEY | 401 | Cần có khóa APIYêu cầu không có header Authorization, hoặc header sai định dạng. | Thêm header: Authorization: Bearer <keyId>.<secret>action: FIX_INPUT · retryable: false · retry_after: null |
| INVALID_API_KEY | 401 | Khóa API không hợp lệKhóa API bạn gửi không khớp với khóa nào đang hoạt động trong hệ thống. | Kiểm tra lại key ID và secret. Nếu cần, hãy tạo lại khóa trong mục API Access.action: FIX_INPUT · retryable: false · retry_after: null |
Phân quyền (403)
| Mã | HTTP status | Ý nghĩa | Cách khắc phục |
|---|---|---|---|
| ACCOUNT_DISABLED | 403 | Tài khoản đã bị vô hiệu hóaAPI không còn trả về mã này. Tài khoản không thể đặt hàng sẽ nhận ACCOUNT_FROZEN (HTTP 403). | Chuyển sang xử lý ACCOUNT_FROZEN.Không còn được trả về, đã thay bằng ACCOUNT_FROZEN |
| ACCOUNT_FROZEN | 403 | Tài khoản đã bị khóaTài khoản của bạn đã bị tạm khóa, thường do có hoạt động đáng ngờ. | Liên hệ bộ phận hỗ trợ để mở khóa tài khoản của bạn.action: CONTACT_SUPPORT · retryable: false · retry_after: null |
| IP_NOT_ALLOWED | 403 | Địa chỉ IP không nằm trong danh sách cho phépYêu cầu được gửi từ một địa chỉ IP không có trong danh sách cho phép của khóa API. | Thêm IP máy chủ của bạn vào danh sách cho phép trong mục API Access, hoặc bỏ giới hạn IP.action: FIX_INPUT · retryable: false · retry_after: null |
Kiểm tra yêu cầu (400)
| Mã | HTTP status | Ý nghĩa | Cách khắc phục |
|---|---|---|---|
| MISSING_REQUIRED_FIELD | 400 | Thiếu trường bắt buộcBody của yêu cầu thiếu một trường bắt buộc. Với các trường thông tin người chơi, details.field cho biết trường bị thiếu. | Đọc tài liệu của endpoint (các trường người chơi xem tại GET /catalog/category/:categoryId/requirements), sau đó gửi đầy đủ mọi trường bắt buộc.action: FIX_INPUT · retryable: false · retry_after: null |
| INVALID_PARAMETER_FORMAT | 400 | Tham số sai định dạngMột trường bắt buộc có định dạng không đúng (ví dụ nhập chữ vào trường chỉ nhận số). details.field cho biết tên trường đó. | Đọc lại yêu cầu của danh mục và gửi trường dữ liệu theo đúng định dạng mà data_type và các quy tắc xác thực yêu cầu.action: FIX_INPUT · retryable: false · retry_after: null |
| INVALID_PARAMETER_VALUE | 400 | Tham số có giá trị không hợp lệGiá trị của một trường thông tin trong danh mục không hợp lệ (nhỏ hơn mức tối thiểu, lớn hơn mức tối đa hoặc không nằm trong select_options). details.field cho biết tên trường đó. | Gửi giá trị hợp lệ cho trường đó theo yêu cầu của danh mục.action: FIX_INPUT · retryable: false · retry_after: null |
| INVALID_PARAMETER_LENGTH | 400 | Độ dài tham số không hợp lệĐộ dài của một trường nằm ngoài giới hạn cho phép. details.field cho biết tên trường đó. | Kiểm tra min_length / max_length trong yêu cầu của danh mục.action: FIX_INPUT · retryable: false · retry_after: null |
| INVALID_UUID_FORMAT | 400 | UUID sai định dạngorder_id không đúng định dạng UUID. | Dùng bất kỳ UUID hợp lệ nào (v1, v4, v7...). Định dạng: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.action: FIX_INPUT · retryable: false · retry_after: null |
| INVALID_QUANTITY | 400 | Số lượng không hợp lệSố lượng phải là số nguyên dương. | Nhập số lượng là số nguyên >= 1.action: FIX_INPUT · retryable: false · retry_after: null |
| INVALID_CATEGORY_ID | 400 | ID danh mục không hợp lệcategoryId bạn gửi không phải là số hợp lệ. | Tìm ID danh mục hợp lệ bằng Catalog Explorer hoặc GET /catalog/categories.action: FIX_INPUT · retryable: false · retry_after: null |
| INVALID_BIG_CATEGORY_ID | 400 | ID danh mục lớn không hợp lệGiá trị bigCategoryId không phải là số hợp lệ. | Tra ID danh mục lớn hợp lệ qua Catalog Explorer hoặc GET /catalog/big-categories.action: FIX_INPUT · retryable: false · retry_after: null |
| INVALID_ITEM_ID | 400 | ID mặt hàng không hợp lệID mặt hàng bạn gửi không hợp lệ. | Dùng Catalog Explorer hoặc GET /catalog/subcategories để tìm ID mặt hàng hợp lệ.action: FIX_INPUT · retryable: false · retry_after: null |
| INVALID_SUBCATEGORY | 400 | Danh mục con không hợp lệID danh mục con không tồn tại. | Kiểm tra sub_category_id qua các endpoint API danh mục.action: FIX_INPUT · retryable: false · retry_after: null |
| INVALID_PRODUCT_CONFIG | 400 | Cấu hình sản phẩm không hợp lệMã này không còn được trả về. Khi thiếu trường bắt buộc, API trả về MISSING_REQUIRED_FIELD; nếu sản phẩm hiện không thể bán, API trả về PRODUCT_UNAVAILABLE. | Chuyển sang xử lý MISSING_REQUIRED_FIELD và PRODUCT_UNAVAILABLE.Không còn được trả về, đã thay bằng MISSING_REQUIRED_FIELD |
| INVALID_PAGINATION | 400 | Tham số phân trang không hợp lệGiá trị page hoặc limit nằm ngoài phạm vi cho phép. | Dùng page >= 1 và limit trong khoảng từ 1 đến 100.action: FIX_INPUT · retryable: false · retry_after: null |
| INVALID_DATE_FORMAT | 400 | Định dạng ngày không hợp lệTham số created_after hoặc created_before không phải ngày hợp lệ theo chuẩn ISO 8601. | Dùng định dạng ISO 8601: 2024-01-01T00:00:00Z.action: FIX_INPUT · retryable: false · retry_after: null |
Kiểm tra người chơi (400 / 429 / 503)
| Mã | HTTP status | Ý nghĩa | Cách khắc phục |
|---|---|---|---|
| PLAYER_NOT_FOUND | 400 | Không tìm thấy người chơiGame đã xác nhận ID người chơi này không tồn tại. Mã này chỉ được trả về khi có xác nhận rõ ràng. Nếu không kiểm tra được ID, bạn sẽ nhận PLAYER_CHECK_UNAVAILABLE. | Kiểm tra lại ID người chơi. Xem game này có yêu cầu zone_id hay không.action: FIX_INPUT · retryable: false · retry_after: null |
| PLAYER_CHECK_UNAVAILABLE | 503 | Hiện chưa thể kiểm tra ID người chơi của game nàyLúc này hệ thống không kiểm tra được ID người chơi của game này. ID người chơi KHÔNG bị từ chối. | Gửi lại đúng yêu cầu đó sau retry_after giây. Đừng báo với khách rằng ID bị sai.action: RETRY_LATER · retryable: true · retry_after: 60 |
| PLAYER_BUSY | 429 | ID người chơi này đang được kiểm traMột yêu cầu khác với cùng ID người chơi vẫn đang được kiểm tra. | Gửi lại yêu cầu sau retry_after giây.action: RETRY_SOON · retryable: true · retry_after: 5 |
| PLAYER_VALIDATION_FAILED | 400 | Xác minh người chơi không thành côngMã này không còn được trả về. Khi chưa kiểm tra được ID người chơi, hệ thống trả về PLAYER_CHECK_UNAVAILABLE (HTTP 503). | Chuyển sang xử lý PLAYER_CHECK_UNAVAILABLE.Không còn được trả về, đã thay bằng PLAYER_CHECK_UNAVAILABLE |
| REGION_MISMATCH | 400 | Sản phẩm này không hỗ trợ khu vực của người chơi.Không thể giao sản phẩm này đến khu vực của người chơi. Thông tin lỗi bao gồm player_region và player_name. | Chọn sản phẩm dành cho khu vực của người chơi.action: CHOOSE_OTHER · retryable: false · retry_after: null |
Quy tắc nghiệp vụ (400 / 409)
| Mã | HTTP status | Ý nghĩa | Cách khắc phục |
|---|---|---|---|
| INSUFFICIENT_BALANCE | 400 | Số dư ví không đủVí của bạn không đủ tiền để hoàn tất đơn hàng này. | Nạp tiền vào ví tại trang Reload trước khi đặt hàng.action: TOP_UP · retryable: false · retry_after: null |
| OUT_OF_STOCK | 400 | Sản phẩm đã hết hàngSản phẩm bạn yêu cầu hiện đang hết hàng. | Thử lại sau hoặc chọn sản phẩm khác.action: RETRY_LATER · retryable: true · retry_after: null |
| INSUFFICIENT_STOCK | 400 | Số lượng còn lại ít hơn số bạn yêu cầuSố lượng còn lại không đủ cho đơn hàng của bạn. Khác với OUT_OF_STOCK, bạn vẫn có thể đặt tối đa số lượng ghi trong error.max_quantity tại thời điểm này. Bạn chưa bị trừ tiền. | Gửi lại đơn hàng với số lượng bằng hoặc nhỏ hơn error.max_quantity.action: FIX_INPUT · retryable: false · retry_after: null |
| PRODUCT_UNAVAILABLE | 409 | Sản phẩm này hiện tạm ngừng bánSản phẩm vẫn tồn tại nhưng hiện chưa thể bán. | Vui lòng thử lại sau, hoặc chọn sản phẩm khác.action: RETRY_LATER · retryable: true · retry_after: null |
| PRICING_UPDATING | 409 | Giá sản phẩm đang được cập nhậtGiá sản phẩm này đang được cập nhật. | Gửi lại đúng yêu cầu đó sau retry_after giây, rồi kiểm tra lại giá.action: RETRY_SOON · retryable: true · retry_after: 30 |
| OFFER_NOT_FOUND | 400 | Ưu đãi này không áp dụng cho tài khoản người chơi nàyƯu đãi dùng một lần (ví dụ thưởng nạp lần đầu) không áp dụng cho tài khoản người chơi này. Có thể ưu đãi đã được sử dụng. | Chọn sản phẩm khác cho người chơi này.action: CHOOSE_OTHER · retryable: false · retry_after: null |
| DUPLICATE_ORDER | 409 | Trùng ID đơn hàngĐã có đơn hàng dùng UUID này. Đây là cơ chế chống trùng lặp (idempotency). | Tạo UUID mới cho mỗi đơn hàng mới. Nếu gặp lỗi này khi gửi lại, nghĩa là lần gửi đầu đã được ghi nhận: hãy xem đơn đó bằng GET /orders/{orderId} thay vì tạo đơn khác.action: CHECK_ORDER · retryable: false · retry_after: null |
| PRICE_INCREASED | 400 | Giá đã vượt mức dự kiếnĐơn giá hiện tại cao hơn expected_unit_price bạn đã gửi. | Lấy giá mới nhất bằng GET /catalog/subcategory/:id/price và cập nhật expected_unit_price.action: FIX_INPUT · retryable: false · retry_after: null |
| SUBCATEGORY_DISABLED | 400 | Danh mục con đã bị vô hiệu hóaMã này hiện không còn dùng. Với sản phẩm chưa thể bán lúc này, hệ thống trả về PRODUCT_UNAVAILABLE (HTTP 409). | Chuyển sang xử lý PRODUCT_UNAVAILABLE.Không còn được trả về, đã thay bằng PRODUCT_UNAVAILABLE |
Không tìm thấy (404)
| Mã | HTTP status | Ý nghĩa | Cách khắc phục |
|---|---|---|---|
| ORDER_NOT_FOUND | 404 | Không tìm thấy đơn hàngKhông có đơn hàng nào khớp với ID đơn hàng đã cung cấp. | Kiểm tra lại ID đơn hàng.action: FIX_INPUT · retryable: false · retry_after: null |
| ITEM_NOT_FOUND | 404 | Không tìm thấy mặt hàngMặt hàng bạn yêu cầu không tồn tại trong danh mục sản phẩm. | Dùng các endpoint catalog để tìm ID mặt hàng hợp lệ.action: FIX_INPUT · retryable: false · retry_after: null |
| NO_REQUIREMENTS_FOUND | 404 | Không tìm thấy thông tin người chơi cần cung cấp cho danh mục nàyLúc này danh mục không có yêu cầu thông tin người chơi nào để trả về. | Thử lại sau, hoặc chọn danh mục khác.action: RETRY_LATER · retryable: true · retry_after: null |
| ITEM_NOT_AVAILABLE | 404 | Mặt hàng không có sẵnMã này không còn được trả về. Nếu mặt hàng vẫn tồn tại nhưng hiện không thể bán, API sẽ trả về PRODUCT_UNAVAILABLE (HTTP 409). | Xử lý PRODUCT_UNAVAILABLE thay cho mã này.Không còn được trả về, đã thay bằng PRODUCT_UNAVAILABLE |
Kiểm tra yêu cầu hàng loạt (400)
| Mã | HTTP status | Ý nghĩa | Cách khắc phục |
|---|---|---|---|
| INVALID_ORDER_IDS_FORMAT | 400 | Định dạng order_ids không hợp lệTrường order_ids phải là một mảng chuỗi. | Truyền order_ids theo dạng: { "order_ids": ["uuid1", "uuid2"] }.action: FIX_INPUT · retryable: false · retry_after: null |
| EMPTY_ORDER_IDS | 400 | Mảng order_ids trốngMảng order_ids không được để trống. | Thêm ít nhất một ID đơn hàng vào mảng.action: FIX_INPUT · retryable: false · retry_after: null |
| TOO_MANY_ORDER_IDS | 400 | Quá nhiều ID đơn hàngMỗi lần chỉ tra cứu được tối đa 50 ID đơn hàng. | Chia yêu cầu thành nhiều lô, mỗi lô không quá 50 ID.action: FIX_INPUT · retryable: false · retry_after: null |
Giới hạn tần suất (429)
| Mã | HTTP status | Ý nghĩa | Cách khắc phục |
|---|---|---|---|
| RATE_LIMIT_EXCEEDED | 429 | Vượt quá giới hạn yêu cầuBạn đã vượt giới hạn của endpoint này. Các nhóm giới hạn theo phút (catalog, orders, account) trả về X-RateLimit-Limit, X-RateLimit-Remaining và X-RateLimit-Reset trong mọi phản hồi, còn details lặp lại limit, remaining (0), retry_after và window_seconds. Riêng POST /player/validate được tính theo hạn mức kiểm tra người chơi hằng ngày của bạn: endpoint này không gửi header X-RateLimit, và phản hồi 429 của nó chứa limit, current, remaining, reset_at và reset_in_seconds bên trong error. Ở cả hai trường hợp, error.retry_after và header Retry-After đều cho biết số giây cần chờ. | Chờ đủ số giây trong retry_after hoặc header Retry-After rồi mới gửi lại. Với các endpoint giới hạn theo phút, hãy theo dõi X-RateLimit-Remaining để không chạm giới hạn.action: RETRY_LATER · retryable: true · retry_after: giây nữa sẽ đặt lại |
Phía server (5xx)
| Mã | HTTP status | Ý nghĩa | Cách khắc phục |
|---|---|---|---|
| INTERNAL_ERROR | 500 | Lỗi máy chủ nội bộMáy chủ gặp lỗi không mong muốn. | Gửi lại yêu cầu sau retry_after giây. Với POST /orders/create, hãy dùng lại đúng order_id cũ để đơn hàng không bao giờ bị tạo hai lần. Nếu lỗi vẫn còn, hãy liên hệ bộ phận hỗ trợ.action: RETRY_LATER · retryable: true · retry_after: 30 |
| SERVICE_UNAVAILABLE | 503 | Dịch vụ tạm thời không khả dụngMã này không còn được trả về. Lỗi phía server sẽ trả về INTERNAL_ERROR (HTTP 500); chỉ PLAYER_CHECK_UNAVAILABLE dùng mã 503, khi hiện không thể kiểm tra ID người chơi. | Hãy xử lý INTERNAL_ERROR và PLAYER_CHECK_UNAVAILABLE thay cho mã này.Không còn được trả về, đã thay bằng INTERNAL_ERROR |
Nếu bạn mới dùng nền tảng, hãy bắt đầu với trang tổng quan API nạp game dành cho đại lý, hoặc đọc tổng quan chương trình đại lý SHOP2TOPUP để biết tài khoản đối tác hoạt động ra sao.