Kode error dan status HTTP
Request yang gagal selalu mengembalikan kode stabil yang bisa dibaca mesin, bersama status HTTP-nya. Jadikan kode sebagai acuan logika, jangan teks pesannya: pesan ditulis untuk manusia dan kata-katanya bisa diubah, sedangkan kode adalah bagian dari kontrak.
Semua 42 kode error yang bisa dikembalikan API reseller, dikelompokkan berdasarkan jenis masalahnya. Tiap entri menyebutkan status HTTP yang menyertainya dan perubahan yang bisa menyelesaikannya.
Autentikasi (401)
| Kode | Status HTTP | Artinya | Cara mengatasinya |
|---|---|---|---|
| MISSING_API_KEY | 401 | API key wajib disertakanHeader Authorization tidak dikirim, atau formatnya salah. | Tambahkan header: Authorization: Bearer <keyId>.<secret>action: FIX_INPUT · retryable: false · retry_after: null |
| INVALID_API_KEY | 401 | API key tidak validAPI key yang dikirim tidak cocok dengan key aktif mana pun di sistem. | Pastikan key ID dan secret kamu sudah benar. Kalau perlu, buat ulang key lewat panel API Access.action: FIX_INPUT · retryable: false · retry_after: null |
Otorisasi (403)
| Kode | Status HTTP | Artinya | Cara mengatasinya |
|---|---|---|---|
| ACCOUNT_DISABLED | 403 | Akun dinonaktifkanError ini sudah tidak dikembalikan lagi. Akun yang tidak bisa membuat pesanan akan menerima ACCOUNT_FROZEN (HTTP 403). | Tangani ACCOUNT_FROZEN sebagai gantinya.Tidak lagi dikembalikan, diganti ACCOUNT_FROZEN |
| ACCOUNT_FROZEN | 403 | Akun dibekukanAkun kamu sedang dibekukan sementara, biasanya karena ada aktivitas mencurigakan. | Hubungi support supaya pembekuan akunmu dicabut.action: CONTACT_SUPPORT · retryable: false · retry_after: null |
| IP_NOT_ALLOWED | 403 | Alamat IP tidak ada di allowlistRequest dikirim dari alamat IP yang tidak terdaftar di allowlist API key kamu. | Tambahkan IP server kamu ke allowlist di panel API Access, atau hapus pembatasan IP.action: FIX_INPUT · retryable: false · retry_after: null |
Validasi request (400)
| Kode | Status HTTP | Artinya | Cara mengatasinya |
|---|---|---|---|
| MISSING_REQUIRED_FIELD | 400 | Field wajib belum diisiAda field wajib yang tidak ada di body request. Untuk data pemain yang dibutuhkan, details.field menyebutkan field yang hilang. | Cek dokumentasi endpoint (untuk field pemain, cek juga GET /catalog/category/:categoryId/requirements), lalu kirim semua field wajib.action: FIX_INPUT · retryable: false · retry_after: null |
| INVALID_PARAMETER_FORMAT | 400 | Format parameter tidak validAda field requirement yang formatnya salah (misalnya teks di field angka). Nama field-nya ada di details.field. | Baca lagi requirement kategori, lalu kirim field sesuai format yang diminta data_type dan aturan validasinya.action: FIX_INPUT · retryable: false · retry_after: null |
| INVALID_PARAMETER_VALUE | 400 | Nilai parameter tidak validNilai salah satu field persyaratan berada di luar batas yang diizinkan (di bawah minimum, di atas maksimum, atau tidak ada di select_options). Field yang bermasalah tercantum di details.field. | Kirim nilai yang sesuai dengan ketentuan kategori untuk kolom tersebut.action: FIX_INPUT · retryable: false · retry_after: null |
| INVALID_PARAMETER_LENGTH | 400 | Panjang parameter tidak validSalah satu field yang wajib diisi terlalu pendek atau terlalu panjang. Nama field tercantum di details.field. | Cek min_length / max_length di requirement kategori.action: FIX_INPUT · retryable: false · retry_after: null |
| INVALID_UUID_FORMAT | 400 | Format UUID tidak validorder_id bukan format UUID yang valid. | Pakai UUID dengan format yang valid (v1, v4, v7, dan lainnya), yaitu xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.action: FIX_INPUT · retryable: false · retry_after: null |
| INVALID_QUANTITY | 400 | Jumlah tidak validJumlah harus berupa bilangan bulat positif. | Isi quantity dengan bilangan bulat >= 1.action: FIX_INPUT · retryable: false · retry_after: null |
| INVALID_CATEGORY_ID | 400 | ID kategori tidak validcategoryId yang dikirim bukan angka yang valid. | Cari ID kategori yang valid lewat Catalog Explorer atau GET /catalog/categories.action: FIX_INPUT · retryable: false · retry_after: null |
| INVALID_BIG_CATEGORY_ID | 400 | ID big category tidak validbigCategoryId yang dikirim bukan angka yang valid. | Pakai Catalog Explorer atau GET /catalog/big-categories untuk menemukan ID big category yang valid.action: FIX_INPUT · retryable: false · retry_after: null |
| INVALID_ITEM_ID | 400 | ID item tidak validID item yang dikirim tidak valid. | ID item yang valid bisa kamu temukan lewat Catalog Explorer atau GET /catalog/subcategories.action: FIX_INPUT · retryable: false · retry_after: null |
| INVALID_SUBCATEGORY | 400 | Subkategori tidak validID subkategori tidak ditemukan. | Cek sub_category_id lewat endpoint katalog.action: FIX_INPUT · retryable: false · retry_after: null |
| INVALID_PRODUCT_CONFIG | 400 | Konfigurasi produk tidak validError ini sudah tidak dikembalikan lagi. Field requirement yang hilang sekarang menghasilkan MISSING_REQUIRED_FIELD, sedangkan produk yang sedang tidak bisa dijual menghasilkan PRODUCT_UNAVAILABLE. | Tangani MISSING_REQUIRED_FIELD dan PRODUCT_UNAVAILABLE sebagai gantinya.Tidak lagi dikembalikan, diganti MISSING_REQUIRED_FIELD |
| INVALID_PAGINATION | 400 | Parameter paginasi tidak validNilai page atau limit di luar rentang. | Gunakan page >= 1 dan limit antara 1 sampai 100.action: FIX_INPUT · retryable: false · retry_after: null |
| INVALID_DATE_FORMAT | 400 | Format tanggal tidak validParameter created_after atau created_before bukan tanggal ISO 8601 yang valid. | Pakai format ISO 8601: 2024-01-01T00:00:00Z.action: FIX_INPUT · retryable: false · retry_after: null |
Validasi pemain (400 / 429 / 503)
| Kode | Status HTTP | Artinya | Cara mengatasinya |
|---|---|---|---|
| PLAYER_NOT_FOUND | 400 | Pemain tidak ditemukanPihak game sudah memastikan bahwa ID pemain ini tidak ada. Kode ini hanya dikirim kalau jawabannya sudah pasti. Kalau ID tidak bisa dicek, yang kamu terima adalah PLAYER_CHECK_UNAVAILABLE. | Pastikan ID pemain sudah benar. Cek juga apakah game ini butuh zone_id.action: FIX_INPUT · retryable: false · retry_after: null |
| PLAYER_CHECK_UNAVAILABLE | 503 | ID pemain untuk game ini belum bisa dicek sekarangUntuk saat ini, ID pemain di game ini tidak bisa dicek. ID pemain tersebut TIDAK ditolak. | Coba lagi request yang sama setelah retry_after detik. Jangan bilang ke pelanggan bahwa ID-nya salah.action: RETRY_LATER · retryable: true · retry_after: 60 |
| PLAYER_BUSY | 429 | ID pemain ini sedang dicekPermintaan lain untuk ID pemain yang sama masih diperiksa. | Kirim ulang request setelah retry_after detik.action: RETRY_SOON · retryable: true · retry_after: 5 |
| PLAYER_VALIDATION_FAILED | 400 | Validasi pemain gagalSudah tidak dikembalikan lagi. ID pemain yang belum bisa dicek saat ini akan mendapat jawaban PLAYER_CHECK_UNAVAILABLE (HTTP 503). | Tangani PLAYER_CHECK_UNAVAILABLE sebagai gantinya.Tidak lagi dikembalikan, diganti PLAYER_CHECK_UNAVAILABLE |
| REGION_MISMATCH | 400 | Produk ini tidak bisa dikirim ke pemain di region tersebutPemain berada di region yang tidak bisa dikirimi produk ini. Error ini menyertakan player_region dan player_name. | Pilih produk yang sesuai dengan region pemain.action: CHOOSE_OTHER · retryable: false · retry_after: null |
Aturan bisnis (400 / 409)
| Kode | Status HTTP | Artinya | Cara mengatasinya |
|---|---|---|---|
| INSUFFICIENT_BALANCE | 400 | Saldo dompet tidak cukupDana di dompet kamu kurang untuk menyelesaikan pesanan ini. | Top up dompet kamu dulu lewat halaman Isi Ulang Dompet sebelum membuat pesanan.action: TOP_UP · retryable: false · retry_after: null |
| OUT_OF_STOCK | 400 | Stok produk habisStok produk yang kamu minta sedang habis. | Coba lagi nanti atau pilih produk lain.action: RETRY_LATER · retryable: true · retry_after: null |
| INSUFFICIENT_STOCK | 400 | Unit yang tersedia lebih sedikit dari yang dimintaJumlah unit yang tersedia lebih sedikit dari jumlah di pesanan kamu. Beda dengan OUT_OF_STOCK, error ini bisa kamu tindak lanjuti: error.max_quantity menunjukkan berapa unit yang bisa dipesan saat ini. Tidak ada biaya yang dikenakan. | Kirim ulang pesanan dengan jumlah tidak lebih dari error.max_quantity.action: FIX_INPUT · retryable: false · retry_after: null |
| PRODUCT_UNAVAILABLE | 409 | Produk ini untuk sementara tidak tersediaProduknya ada, tapi belum bisa dijual saat ini. | Coba lagi nanti, atau ganti ke produk lain.action: RETRY_LATER · retryable: true · retry_after: null |
| PRICING_UPDATING | 409 | Harga produk sedang diperbaruiSistem sedang memperbarui harga produk ini. | Kirim request yang sama lagi setelah retry_after detik, lalu cek ulang harganya.action: RETRY_SOON · retryable: true · retry_after: 30 |
| OFFER_NOT_FOUND | 400 | Penawaran ini tidak tersedia untuk akun pemain iniPenawaran sekali pakai (misalnya bonus top up pertama) tidak tersedia untuk akun pemain ini. Bisa jadi sudah pernah dipakai. | Pilih produk lain untuk pemain ini.action: CHOOSE_OTHER · retryable: false · retry_after: null |
| DUPLICATE_ORDER | 409 | ID pesanan duplikatPesanan dengan UUID ini sudah ada. Pemeriksaan ini mencegah pesanan yang sama dibuat lebih dari sekali. | Buat UUID baru untuk pesanan baru. Kalau error ini muncul saat retry, artinya percobaan pertama sudah masuk: cek pesanan itu lewat GET /orders/{orderId}, jangan buat pesanan baru.action: CHECK_ORDER · retryable: false · retry_after: null |
| PRICE_INCREASED | 400 | Harga naik melebihi perkiraanHarga satuan saat ini lebih tinggi dari expected_unit_price yang kamu kirim. | Ambil harga terbaru lewat GET /catalog/subcategory/:id/price, lalu perbarui expected_unit_price.action: FIX_INPUT · retryable: false · retry_after: null |
| SUBCATEGORY_DISABLED | 400 | Subkategori dinonaktifkanKode ini tidak lagi dipakai. Produk yang belum bisa dijual saat ini akan mendapat jawaban PRODUCT_UNAVAILABLE (HTTP 409). | Tangani PRODUCT_UNAVAILABLE sebagai gantinya.Tidak lagi dikembalikan, diganti PRODUCT_UNAVAILABLE |
Tidak ditemukan (404)
| Kode | Status HTTP | Artinya | Cara mengatasinya |
|---|---|---|---|
| ORDER_NOT_FOUND | 404 | Pesanan tidak ditemukanTidak ada pesanan dengan ID pesanan tersebut. | Pastikan ID pesanan sudah benar.action: FIX_INPUT · retryable: false · retry_after: null |
| ITEM_NOT_FOUND | 404 | Item tidak ditemukanItem katalog yang diminta tidak ada. | Pakai endpoint katalog untuk mencari ID item yang valid.action: FIX_INPUT · retryable: false · retry_after: null |
| NO_REQUIREMENTS_FOUND | 404 | Tidak ada persyaratan untuk kategori iniSaat ini tidak ada persyaratan pemain untuk kategori ini. | Coba lagi nanti, atau pilih kategori lain.action: RETRY_LATER · retryable: true · retry_after: null |
| ITEM_NOT_AVAILABLE | 404 | Item tidak tersediaAPI tidak lagi mengembalikan error ini. Untuk item yang ada tetapi saat ini tidak bisa dijual, API mengembalikan PRODUCT_UNAVAILABLE (HTTP 409). | Sebagai gantinya, tangani PRODUCT_UNAVAILABLE.Tidak lagi dikembalikan, diganti PRODUCT_UNAVAILABLE |
Validasi request batch (400)
| Kode | Status HTTP | Artinya | Cara mengatasinya |
|---|---|---|---|
| INVALID_ORDER_IDS_FORMAT | 400 | Format order_ids tidak validField order_ids harus berupa array string. | Kirim order_ids dengan format: { "order_ids": ["uuid1", "uuid2"] }.action: FIX_INPUT · retryable: false · retry_after: null |
| EMPTY_ORDER_IDS | 400 | Array order_ids kosongArray order_ids tidak boleh kosong. | Isi array dengan minimal satu ID pesanan.action: FIX_INPUT · retryable: false · retry_after: null |
| TOO_MANY_ORDER_IDS | 400 | Terlalu banyak ID pesananMaksimal 50 ID pesanan bisa dicek sekaligus. | Bagi request kamu jadi beberapa batch, masing-masing maksimal 50.action: FIX_INPUT · retryable: false · retry_after: null |
Batas request (429)
| Kode | Status HTTP | Artinya | Cara mengatasinya |
|---|---|---|---|
| RATE_LIMIT_EXCEEDED | 429 | Rate limit terlampauiKamu sudah melewati batas untuk endpoint ini. Untuk bucket per menit (catalog, orders, account), setiap respons menyertakan header X-RateLimit-Limit, X-RateLimit-Remaining dan X-RateLimit-Reset. Bagian details juga memuat limit, remaining (0), retry_after dan window_seconds. Khusus POST /player/validate, batas penggunaan mengikuti kuota cek pemain harian kamu. Endpoint ini tidak mengirim header X-RateLimit. Respons 429-nya memuat limit, current, remaining, reset_at dan reset_in_seconds di dalam error. Pada kedua jenis batas ini, error.retry_after dan header Retry-After berisi waktu tunggu dalam detik. | Tunggu selama jumlah detik yang tercantum di retry_after atau header Retry-After sebelum mencoba lagi. Untuk endpoint dengan batas per menit, pantau X-RateLimit-Remaining agar tidak melebihi batas.action: RETRY_LATER · retryable: true · retry_after: detik lagi sampai reset |
Kesalahan server (5xx)
| Kode | Status HTTP | Artinya | Cara mengatasinya |
|---|---|---|---|
| INTERNAL_ERROR | 500 | Kesalahan server internalTerjadi kesalahan tak terduga di server. | Kirim ulang request setelah retry_after detik. Untuk POST /orders/create, pakai order_id yang sama supaya pesanan tidak pernah dibuat dua kali. Kalau error masih muncul, hubungi tim support.action: RETRY_LATER · retryable: true · retry_after: 30 |
| SERVICE_UNAVAILABLE | 503 | Layanan sedang tidak tersediaKode ini tidak lagi dikembalikan. Jika terjadi gangguan di sisi server, API mengembalikan INTERNAL_ERROR (HTTP 500). Status 503 hanya digunakan untuk PLAYER_CHECK_UNAVAILABLE, saat ID pemain belum bisa diperiksa. | Tangani INTERNAL_ERROR dan PLAYER_CHECK_UNAVAILABLE sebagai gantinya.Tidak lagi dikembalikan, diganti INTERNAL_ERROR |
Kalau baru pertama kali pakai platform ini, mulai dari ringkasan API top up game untuk reseller, atau baca ringkasan program reseller SHOP2TOPUP untuk tahu cara kerja akun partner.