İçereği Atla
Türkiye'nin çok satıcılı pazaryeri Mağaza Aç Yardım
Türkiye'nin çok satıcılı pazaryeri

Toptandepo Mağaza API'si (v1)

Her mağaza, kendi yazılımını (muhasebe / ERP / özel panel) Toptandepo'ya bağlamak için bir REST API kullanır: ürünleri çek, stok güncelle, siparişleri çek ve kargo bilgisi yaz. Kimlik bilgilerini (Merchant ID / API Key / API Secret) mağaza panelindeki API Erişimi sayfasından alırsın.

Kimlik Doğrulama

Her istek üç başlık taşır (HTTPS zorunlu):

X-Merchant-Id: TPD000123
X-Api-Key:     tpk_xxxxxxxxxxxxxxxxxxxx
X-Api-Secret:  
  • Taban adres: https://register.ixirbilisim.com/api/v1
  • Yanıtlar JSON; veriler yalnız senin mağazanın kayıtlarıyla sınırlıdır.
  • Hatalı/eksik kimlik → 401; bulunamayan kayıt → 404; geçersiz girdi → 400; istek sınırı aşımı → 429.
  • Listelerde sayfalama: ?page=1&size=50 (size en çok 200).
  • since tarih biçimi: YYYY-AA-GG veya YYYY-AA-GG SS:DD:SS (geçersizse 400).

Uçlar

Bağlantı testi — GET /api/v1/ping

curl https://register.ixirbilisim.com/api/v1/ping \
  -H "X-Merchant-Id: ..." -H "X-Api-Key: ..." -H "X-Api-Secret: ..."
→ { "ok": true, "merchant_id": "TPD000123", "store": "Mağaza Adı", "server_time": "..." }

Ürünleri listele — GET /api/v1/products

GET /api/v1/products?page=1&size=50
→ { "ok": true, "page": 1, "size": 50, "total": 320, "items": [
     { "id": 12, "name": "...", "sku": "ABC-1", "barcode": "869...",
       "price": 199.90, "currency": "TRY", "stock": 25.0, "published": true } ] }

Ürün detayı — GET /api/v1/products/

→ { "ok": true, "product": { ..., "description": "...", "category": "...", "vat": 20,
     "variants": [ { "id": 34, "sku": "...", "barcode": "...",
                     "attributes": {"Renk":"Kırmızı","Beden":"L"}, "stock": 5.0 } ] } }

Stok güncelle — POST /api/v1/stock

POST /api/v1/stock
{ "items": [ { "sku": "ABC-1", "qty": 17 }, { "barcode": "869...", "qty": 4 } ] }
→ { "ok": true, "updated": 2, "errors": [] }

Siparişleri listele — GET /api/v1/orders

GET /api/v1/orders?page=1&size=50&since=2026-05-01
→ { "ok": true, "total": 12, "items": [
     { "id": 88, "name": "S00088", "external_ref": "TY-123", "channel": "trendyol",
       "date": "...", "state": "sale", "total": 549.80, "currency": "TRY",
       "customer": "Ad Soyad", "tracking": "" } ] }

Sipariş detayı — GET /api/v1/orders/

→ { "ok": true, "order": { ..., "customer_detail": {"name","phone","email","address"},
     "lines": [ { "sku", "barcode", "name", "qty", "price", "subtotal" } ] } }

Kargo bilgisi yaz — POST /api/v1/orders//shipment

POST /api/v1/orders/88/shipment
{ "carrier": "Yurtiçi Kargo", "tracking": "1234567890" }
→ { "ok": true, "order": "S00088", "tracking": "1234567890" }

Sipariş durumu güncelle — POST /api/v1/orders//status

Mağaza durumunu bildirir (bilgilendirme; Odoo sipariş akışını etkilemez). Durum: new · preparing · shipped · delivered · cancelled. Sipariş yanıtlarında status alanında döner.

POST /api/v1/orders/88/status
{ "status": "shipped" }
→ { "ok": true, "order": "S00088", "status": "shipped", "status_label": "Kargolandı" }

İstek Sınırı (Rate-Limit)

Her kimlik için dakika başına sınırlı sayıda istek kabul edilir (varsayılan 120/dk). Her yanıt güncel durumu başlıklarda bildirir:

X-RateLimit-Limit:     120     # dakikalık üst sınır
X-RateLimit-Remaining: 118     # bu pencerede kalan hak
X-RateLimit-Reset:     1780868100   # pencerenin sıfırlanma anı (unix ts)

Sınır aşılırsa 429 Too Many Requests döner ve Retry-After (saniye) başlığı kadar beklemelisin:

HTTP/1.1 429 Too Many Requests
Retry-After: 12
{ "ok": false, "error": "İstek sınırı aşıldı (120/dk). Lütfen bekleyip tekrar deneyin." }

Idempotency (Çift İşlem Önleme)

Yazma uçlarında (POST /stock, /orders//shipment, /orders//status) ağ kesintisinde aynı isteği güvenle tekrar edebilmek için opsiyonel bir anahtar başlığı gönder:

X-Idempotency-Key: siparis-88-kargo-2026-06-07
  • Aynı anahtarla gelen TEKRAR istek işlemi yeniden ÇALIŞTIRMAZ; ilk yanıtın aynısını döndürür ve X-Idempotency-Replayed: true başlığını ekler.
  • Böylece zaman aşımı sonrası tekrar denemelerde çift stok/çift kayıt oluşmaz.
  • Anahtar gönderilmezse uç eskisi gibi çalışır (geriye dönük uyumlu). Kayıt 24 saat saklanır.
  • Her POST isteği için BENZERSİZ bir anahtar üret (örn. işlem türü + sipariş no + zaman).

Örnek Kod

Python (requests)

import requests

BASE = "https://register.ixirbilisim.com/api/v1"
HEADERS = {
    "X-Merchant-Id": "TPD000123",
    "X-Api-Key": "tpk_xxxxxxxxxxxxxxxxxxxx",
    "X-Api-Secret": "GIZLI_SECRET",
    "Content-Type": "application/json",
}

# 1) Bağlantı testi
r = requests.get(f"{BASE}/ping", headers=HEADERS, timeout=30)
print(r.json())

# 2) Ürünleri çek (sayfalı)
r = requests.get(f"{BASE}/products", headers=HEADERS, params={"page": 1, "size": 50})
for p in r.json()["items"]:
    print(p["sku"], p["name"], "stok:", p["stock"])

# 3) Stok güncelle (idempotency anahtarıyla — zaman aşımında güvenle tekrar et)
import uuid
r = requests.post(f"{BASE}/stock",
                  headers={**HEADERS, "X-Idempotency-Key": str(uuid.uuid4())},
                  json={"items": [{"sku": "ABC-1", "qty": 17},
                                  {"barcode": "8690000000017", "qty": 4}]})
print(r.json())   # {"ok": true, "updated": 2, "errors": []}
print(r.headers.get("X-RateLimit-Remaining"))   # kalan istek hakkı

# 4) Siparişleri çek + kargo + durum güncelle
orders = requests.get(f"{BASE}/orders", headers=HEADERS, params={"size": 50}).json()
for o in orders["items"]:
    print(o["name"], o["customer"], o["total"], "durum:", o["status"])
    oid = o["id"]
    # Kargo bilgisi
    requests.post(f"{BASE}/orders/{oid}/shipment", headers=HEADERS,
                  json={"carrier": "Yurtiçi Kargo", "tracking": "1234567890"})
    # Sipariş durumu (new/preparing/shipped/delivered/cancelled)
    r = requests.post(f"{BASE}/orders/{oid}/status", headers=HEADERS,
                      json={"status": "shipped"})
    print(r.json()["status_label"])

PHP (cURL)

 [ ["sku" => "ABC-1", "qty" => 17] ]
]);
print_r($res);

// 4) Sipariş + kargo bilgisi + durum güncelleme
$orders = tpd_request("GET", "$BASE/orders?size=50", $HEADERS);
foreach ($orders["items"] as $o) {
    $id = $o["id"];
    // Kargo bilgisini yaz
    tpd_request("POST", "$BASE/orders/$id/shipment", $HEADERS, [
        "carrier" => "Yurtiçi Kargo", "tracking" => "1234567890"
    ]);
    // Sipariş durumunu "kargolandı" yap
    // (new / preparing / shipped / delivered / cancelled)
    $res = tpd_request("POST", "$BASE/orders/$id/status", $HEADERS, [
        "status" => "shipped"
    ]);
    echo $o["name"] . " → " . $res["status_label"] . "\n";
}

Güvenlik

  • API Secret gizlidir; yalnız kendi sunucunda sakla, tarayıcıda/istemcide ifşa etme.
  • Sızarsa panelden Anahtarları Yenile ile döndür (eski anahtar anında geçersiz olur).
  • Tüm trafik TLS (HTTPS) üzerinden olmalıdır.

Panelde Kimlik Bilgilerimi Gör