İçeriğe geç

Site API'si

Kendi araçlarını siteye bağlamak: API anahtarı, izinler, uç noktalar, kredi ekleme ve hata kodları.

Site API'si, kendi yazdığın araçların (Discord botu, muhasebe tablosu, başka bir site) sitendeki oyuncu, sipariş, mağaza ve destek bilgilerini okumasını ve oyunculara kredi eklemesini sağlar. Yanıtlar JSON biçimindedir. Oyun sunucundaki BorCube Connect eklentisi bu API'yi kullanmaz; o kendi sunucu anahtarıyla konuşur (Connect kurulumu).

Anahtar oluşturma#

  1. Yönetim paneli → Ayarlar → API sayfasını aç. Bu sayfa Site API anahtarlarını oluşturma ve iptal etme iznini ister. Bu izin para hareketine yol açabildiği için hesabında iki adımlı doğrulama (2FA) açık olmalıdır.
  2. Sağdaki Yeni anahtar formunu doldur:
    • Ad: anahtarı tanıman için bir ad, ör. "Discord botu" (en çok 60 karakter).
    • İzinler: anahtarın yapabileceği işler. En az birini seç; yalnız aracının gerçekten kullanacaklarını işaretle.
    • İzinli IP adresleri (isteğe bağlı): her satıra bir adres, en çok 20 adres. Doluysa anahtar yalnız bu adreslerden gelen istekleri kabul eder.
  3. Anahtar oluştur düğmesine bas. Anahtar bck_ ile başlar ve yalnız bu sefer gösterilir. Anahtarı kopyala ile alıp güvenli bir yere kaydet; sayfadan çıkınca bir daha göremezsin.

Aynı anda en çok 25 etkin anahtar olabilir. Bir anahtarın izinleri ve IP listesi sonradan değiştirilemez; farklı izinler gerekiyorsa yeni bir anahtar oluşturup eskisini iptal et.

İzinler

İzinNe verir
users:readOyuncu bilgisi: ad, roller, kayıt tarihi, oyun doğrulaması
orders:readOyuncunun siparişleri
credits:readOyuncunun kredi bakiyesi
credits:writeOyuncuya kredi ekleme ve çıkarma
store:readMağaza kategorileri ve ürünleri
tickets:readDestek taleplerinin listesi
votes:readOy siteleri

IP kısıtlaması nasıl çalışır?

Site, isteği yapanın adresini Yönetim paneli → Ayarlar → Sistem ve güvenlik sayfasındaki Gerçek IP başlığı ayarından okur. Bu ayar sitenin önündeki sisteme uygun olmalıdır (Cloudflare kullanıyorsan CF-Connecting-IP, Nginx ya da Caddy arkasındaysan X-Forwarded-For).

Anahtarı iptal etmek

Listedeki anahtarın yanındaki İptal et düğmesine bas ve onayla. İptal geri alınamaz; anahtar o andan sonra 401 alır ve listede "iptal edildi" olarak kalır. Anahtarın ele geçtiğinden şüpheleniyorsan hemen iptal et ve yenisini oluştur.

Listede her anahtarın son dört karakteri, kimin ne zaman oluşturduğu, son kullanım zamanı ve adresi görünür. Anahtar oluşturma, iptal ve API'den yapılan her kredi değişikliği Yönetim paneli → Kayıtlar → Panel kayıtları sayfasına yazılır; anahtarın kendisi hiçbir kayıtta tutulmaz.

İstek gönderme#

Bütün adresler sitenin adresinden sonra /api/v1 ile başlar. Anahtarı her istekte Authorization başlığında gönder:

Komut
curl -H "Authorization: Bearer bck_ANAHTARIN" https://sitem.com/api/v1

Bu ilk adres anahtarı denemek içindir; anahtarın adını ve izinlerini döndürür:

JSON
{ "key": { "id": 3, "name": "Discord botu" }, "scopes": ["store:read", "users:read"] }

Bilmen gereken kurallar:

  • Tarihler ISO 8601 biçiminde ve UTC saatindedir, ör. 2026-10-09T18:30:00.000Z.
  • Kredi ve fiyatlar tam sayıdır ve kuruş cinsindendir: 1250, 12,50 kredi demektir.
  • Oyuncu adı adresin içinde yazılır: 3–16 karakter, harf, rakam ve alt çizgi. Büyük/küçük harf fark etmez.
  • Anahtar başına dakikada en çok 120 istek gönderebilirsin. Hatalı anahtarla aynı adresten dakikada 30 denemeden sonra istekler geri çevrilir.
  • E-posta adresi, IP adresi, şifre ve iki adımlı doğrulama bilgisi, oturumlar ve ödeme sağlayıcısı verileri API'den hiçbir zaman verilmez.

Uç noktalar#

YöntemAdresİzin
GET/api/v1—
GET/api/v1/users/{oyuncu}users:read
GET/api/v1/users/{oyuncu}/ordersorders:read
GET/api/v1/users/{oyuncu}/creditscredits:read
POST/api/v1/users/{oyuncu}/creditscredits:write
GET/api/v1/store/categoriesstore:read
GET/api/v1/store/productsstore:read
GET/api/v1/vote-sitesvotes:read
GET/api/v1/ticketstickets:read

Oyuncu bilgisi

GET /api/v1/users/Steve

JSON
{
  "user": {
    "id": "…",
    "username": "Steve",
    "created_at": "2026-03-01T12:00:00.000Z",
    "last_login_at": "2026-10-09T18:30:00.000Z",
    "banned": false,
    "minecraft": { "uuid": "…", "verified_at": "2026-03-01T12:05:00.000Z" },
    "roles": [{ "name": "VIP", "expires_at": "2026-11-01T00:00:00.000Z" }],
    "credits": 1250
  }
}
  • minecraft, oyuncu oyun hesabını doğrulamadıysa null gelir.
  • roles yalnız süresi geçmemiş rolleri içerir, önceliği yüksek olan önce gelir. Süresiz rollerde expires_at null'dır.
  • credits alanı yalnız anahtarda credits:read izni de varsa gelir.

Siparişler

GET /api/v1/users/Steve/orders?limit=20

Oyuncunun siparişleri en yeniden eskiye doğru gelir. limit 1 ile 50 arasındadır, yazmazsan 20 kabul edilir.

JSON
{
  "orders": [
    {
      "id": 42,
      "status": "completed",
      "subtotal": 5000,
      "discount": 500,
      "total": 4500,
      "created_at": "2026-10-09T18:30:00.000Z",
      "refunded_at": null,
      "items": [{ "product_id": 7, "name": "VIP (30 gün)", "quantity": 1, "unit_price": 5000, "total": 5000 }]
    }
  ]
}
  • status: completed (tamamlandı) ya da refunded (iade edildi).
  • Tutarlar kredi cinsindendir. discount, kupon ve içerik üretici kodu indirimlerinin toplamıdır.

Kredi bakiyesi

GET /api/v1/users/Steve/credits → { "credits": 1250 }

Mağaza

GET /api/v1/store/categories etkin kategorileri döndürür (üst kategorisi kapalı olanlar gelmez):

JSON
{ "categories": [{ "id": 1, "name": "Rütbeler", "slug": "rutbeler", "parent_id": null, "url": "/magaza/rutbeler" }] }

GET /api/v1/store/products satışta olan ürünleri döndürür (en çok 500). Tek bir kategorinin ürünleri için ?category=1 ekle.

JSON
{
  "products": [
    {
      "id": 7,
      "name": "VIP (30 gün)",
      "slug": "vip-30-gun",
      "category_id": 1,
      "url": "/urun/vip-30-gun",
      "image": null,
      "price": 5000,
      "discount_percent": 10,
      "discount_ends_at": null,
      "kind": "timed",
      "duration_days": 30,
      "stock": null
    }
  ]
}

kind ürün türüdür: consumable (tekrar tekrar alınabilen), permanent (bir kez alınıp kalıcı), timed (süreli). Ürün türleri için: Mağaza yapısı.

Oy siteleri

GET /api/v1/vote-sites etkin oy sitelerini döndürür:

JSON
{ "vote_sites": [{ "id": 1, "name": "Örnek Liste", "image": null, "host": "ornekliste.com", "cooldown_hours": 24, "url": "/oy-ver/1" }] }

url, oyuncuyu oy sitesine yönlendiren site içi adrestir. Oylama için: Oylama.

Destek talepleri

GET /api/v1/tickets?status=open&limit=50

Talepler son yanıt zamanına göre en yeniden eskiye gelir. status isteğe bağlıdır: open (açık), answered (yanıtlandı), user_reply (oyuncu yanıtı), closed (kapalı). limit 1 ile 100 arasındadır, yazmazsan 50 kabul edilir.

JSON
{
  "tickets": [
    { "id": 12, "subject": "Ürün gelmedi", "status": "open", "category": "Mağaza", "username": "Steve", "created_at": "…", "last_reply_at": "…" }
  ]
}

Talebin içeriği ve yanıtlar API'den verilmez; yalnız liste bilgisi gelir.

Kredi ekleme ve çıkarma#

POST /api/v1/users/{oyuncu}/credits ile oyuncunun bakiyesini değiştirirsin. Örneğin bir etkinlik ödülü olarak 5 kredi eklemek:

Komut
curl -X POST https://sitem.com/api/v1/users/Steve/credits \
  -H "Authorization: Bearer bck_ANAHTARIN" \
  -H "Idempotency-Key: etkinlik-2026-10-09-steve" \
  -H "Content-Type: application/json" \
  -d '{"amount": 500, "note": "Etkinlik ödülü"}'

Yanıt: { "credits": 1750, "duplicate": false } (oyuncunun yeni bakiyesi).

  • amount: kuruş cinsinden, sıfır olmayan tam sayı. Eksi değer krediyi düşer (-500 = 5 kredi çıkar).
  • note: isteğe bağlı açıklama, en çok 200 karakter.
  • Idempotency-Key başlığı zorunludur: her işlem için benzersiz bir değer üret (8–64 karakter; harf, rakam ve _ . : -). Bağlantı koparsa aynı isteği aynı değerle yeniden gönder; kredi ikinci kez değişmez, yanıtta "duplicate": true gelir. Aynı değeri başka bir oyuncu ya da tutarla kullanırsan 409 idempotency_key_reused alırsın.

Bakiye eksiye düşemez ve sitenin üst sınırını aşamaz. Hareket, oyuncunun kredi geçmişine "API" türünde, API (anahtar adı): not açıklamasıyla yazılır; Yönetim paneli → Oyuncular → Bakiye düzenle sayfasında görünür. Kredi sistemi için: Kredi sistemi.

Hata kodları#

Hatalarda yanıt { "error": "kod" } biçimindedir.

DurumKodAnlamı
400bad_requestGövde geçersiz (ör. amount sayı değil)
400invalid_amountTutar sıfır ya da izin verilen sınırın dışında
400idempotency_key_requiredIdempotency-Key başlığı yok ya da biçimi yanlış
401unauthorizedAnahtar yok, yanlış, iptal edilmiş ya da istek izinli bir adresten gelmiyor
403forbiddenAnahtarda bu iş için izin yok; eksik izin scope alanında yazar
403license_requiredSitenin lisans paketi Site API'yi içermiyor (Ultimate gerekir)
404user_not_foundBu adda bir oyuncu yok
409insufficient_creditsOyuncunun bakiyesi bu çıkarma için yetmiyor
409balance_capEkleme bakiyeyi üst sınırın üstüne çıkarıyor
409idempotency_key_reusedAynı Idempotency-Key başka bir istekte kullanılmış
413too_largeİstek gövdesi çok büyük
429rate_limitedÇok fazla istek; bir dakika bekle

Güvenlik önerileri#

  • Anahtarı tarayıcıda çalışan koda, herkese açık depolara ya da Discord mesajlarına koyma. Yalnız sunucu tarafındaki kodda, ortam değişkeninde tut.
  • Her araç için ayrı anahtar oluştur. Böylece bir anahtarı iptal ettiğinde öbür araçların çalışmaya devam eder.
  • Anahtara yalnız gereken izinleri ver; okumak yetiyorsa credits:write verme.
  • Panel kayıtlarında beklemediğin bir kredi değişikliği görürsen anahtarı hemen iptal et.

Bir yanlış ya da eksik mi gördün? Discord’dan haber ver, hemen düzeltelim.