Yenitrend

Satıcı API v1

Entegratör yazılımlar, satıcının verdiği anahtarla onun adına ürün, fiyat, stok, sipariş, kargo ve iade işlemlerini yönetir.

Genel bakış

Satıcı API, Yenitrend'de satış yapan mağazaların kendi stok, muhasebe ya da sipariş yazılımlarını bağlaması için tasarlanmış bir REST API'dir. Tüm istekler HTTPS üzerinden, JSON gövdeyle yapılır.

Temel adres: https://yenitrend.com/api/seller/v1

Başarılı her yanıtın gövdesi tek bir data alanı taşır:

{
  "data": { … }
}
  • Her anahtar tek bir mağazaya aittir; mağaza kimliği yalnız anahtardan alınır. İstekte mağaza kimliği gönderilmez.
  • Siparişler sipariş numarasıyla çağrılır (ör. YT7K3M9QX2BD). Ürün, paket, iptal talebi ve iade kimlikleri sayıdır.
  • Başka bir mağazanın kaydı her zaman "bulunamadı" (404) döner.
  • Bilinmeyen alan ya da sorgu parametresi içeren istek reddedilir (400 invalid_input).
  • Teslim bilgisi yalnız okunur; teslim durumu kargodan gelir.
  • Entegratör, müşteri kişisel verilerini satıcı adına işleyen taraftır (veri işleyen). Bu verileri yalnız siparişin yerine getirilmesi için kullanabilir. Sipariş listesinde alıcı adı, telefonu ve adresi yoktur (yalnız il/ilçe); detayda iletişim bilgisi teslimden ya da iptalden sonra maskelenir.

Kimlik doğrulama

Her istekte Authorization başlığına anahtarı ekle:

Authorization: Bearer yt_live_<keyId>_<secret>
  • Anahtarı satıcı, Satıcı Paneli → API Erişimi sayfasında şifresini tekrar girerek oluşturur ve sana iletir. Anahtar yalnız oluşturulduğu anda bir kez gösterilir.
  • Kapsam: Tam (okuma + yazma) ya da Salt okunur. Salt okunur anahtarla yazma isteği 403 insufficient_scope döner.
  • Bir mağazanın en fazla 3 aktif anahtarı olabilir. İptal edilen anahtar anında geçersiz olur.
  • Anahtarı loglara, hata raporlarına ya da istemci tarafı (tarayıcı, mobil uygulama) koda koyma.
  • Askıdaki mağaza sipariş ve iadeleri okuyabilir, askıdan önceki siparişleri kargolayabilir; ürün, iptal ve iade yazma işlemleri 403 seller_not_allowed döner.

Hata biçimi

Hatalı her yanıt aynı zarfla döner. details isteğe bağlıdır ve düzeltmeye yarayan yapısal bilgi taşır (ör. field, reason, alan yolu + mesaj içeren issues).

HTTP/1.1 403 Forbidden
Content-Type: application/json

{
  "error": {
    "code": "insufficient_scope",
    "message": "Bu API anahtarı yalnız okuma yetkili; yazma işlemi yapılamaz."
  }
}
KodHTTPAnlamı
invalid_input400Geçersiz istek.
unauthenticated401Anahtar yok, hatalı ya da iptal edilmiş; mağaza onaylı değil.
forbidden403Bu işlem için yetkin yok.
insufficient_scope403Salt okunur anahtarla yazma isteği.
seller_not_allowed403Mağaza askıda: ürün, iptal ve iade yazma kapalı.
fulfillment_blocked403Kargolama yetkin yönetici tarafından kapatıldı.
not_found404Kayıt yok ya da başka bir mağazaya ait.
invalid_state409Kayıt bu işlem için uygun durumda değil; neden details.reason alanında. Örn. payment_fraud_review: ödeme güvenlik incelemesinde, kargo ve iptal inceleme bitince yeniden denenmeli.
conflict409İstek mevcut kayıtla çakışıyor.
stale409Kayıt sen okuduktan sonra değişti. Güncel hâlini okuyup tekrar dene.
idempotency_in_progress409Aynı Idempotency-Key ile bir istek hâlâ işleniyor. Biraz sonra tekrar dene.
idempotency_key_reused422Bu Idempotency-Key farklı bir istek için kullanıldı.
payload_too_large413İstek gövdesi 256 KB'tan büyük.
unsupported_media_type415İstek gövdesi application/json olmalı.
rate_limited429Retry-After başlığındaki saniye kadar bekle.
internal500Beklenmeyen bir hata oluştu. Lütfen tekrar dene.

İstek limitleri

Limitler mağaza başınadır; mağazanın tüm anahtarları aynı kotayı paylaşır.

TürUçlarLimit
OkumaGET uçları60 / dk
YazmaPOST, PUT, DELETE uçları30 / dk
TopluPOST /stock-price10 / dk

Limit aşılınca 429 rate_limited döner; Retry-After başlığı kaç saniye beklemen gerektiğini söyler. Geçersiz anahtarla yapılan tekrarlı istekler IP adresi başına ayrıca sınırlanır. Sipariş iptali ve iptal talebi kabulü, satıcı panelindeki satış sonrası işlemlerle ortak bir limiti paylaşır (tekrar denemeler de bu limitten düşer).

Idempotency-Key

Tüm yazma uçlarında (POST, PUT, DELETE) Idempotency-Key başlığı zorunludur ve UUID biçiminde olmalıdır (dry_run=true isteklerinde isteğe bağlı). Ağ hatasında aynı isteği aynı anahtarla güvenle tekrar gönderebilirsin; işlem bir kez yapılır.

  • Aynı anahtar + aynı gövde: ilk isteğin sonucu aynen döner, yanıtta Idempotent-Replayed: true başlığı olur. Sipariş, kargo, iptal ve iade komutlarında gövdede replayed: true da gelir.
  • Ürün ve fiyat/stok uçlarında aynı anahtar + farklı gövde: 422 idempotency_key_reused.
  • Sipariş iptali, iptal talebi kabulü ve kargo uçlarında aynı anahtar + farklı içerik (ör. farklı takip no): 409 conflict. İade kararlarında tekrar koruması iadenin durumuna bağlıdır; aynı kararı iki kez vermek çift etki doğurmaz.
  • POST /stock-price tekrar yanıtı kısa özettir: kalem sonuçları ve kodları döner, önceki/yeni fiyat ve stok ayrıntısı dönmez.
  • İlk istek hâlâ işleniyorsa: 409 idempotency_in_progress (+ Retry-After).
  • Kayıtlar 7 gün saklanır. Her yeni işlem için yeni bir UUID üret.

dry_run (deneme)

POST /products, PUT /products/{id} ve POST /stock-price uçları ?dry_run=true parametresini kabul eder. İstek gerçek istekle birebir aynı kurallarla doğrulanır, ama hiçbir şey kaydedilmez. Yanıtta dryRun: true olur; ürün oluşturmada durum kodu 201 yerine 200'dür.

  • Görseller indirilmez; yalnız adreslerin geçerliliği denetlenir.
  • Idempotency-Key isteğe bağlıdır; deneme için kayıt tutulmaz.
  • Deneme istekleri de istek limitine sayılır. Ayrı bir test ortamı yoktur.
  • POST /products/{id}/status ve sipariş uçları dry_run desteklemez.

Para, tarih ve sayfalama

  • Para her zaman kuruş cinsinden tam sayıdır ve yanıtlarda "currency": "TRY" ile gelir. Örnek: 129,90 TL = 12990. Ondalıklı sayı gönderme. Fiyatlar KDV dahildir.
  • Tarihler ISO-8601 biçiminde ve UTC'dir. Örnek: 2026-10-01T09:30:00Z.
  • Sayfalama: liste uçları page (1'den başlar) ve size (varsayılan 50, en fazla 100) alır. Yanıt { data: { items, page, size, hasMore } } biçimindedir; hasMore false olana kadar sonraki sayfayı iste. Ürün listesi ayrıca toplam kayıt sayısını (total) da döner.
  • Gövde application/json olmalıdır (aksi 415); 256 KB'tan büyük gövde 413 döner.

Uç listesi

Yollar temel adrese göredir (https://yenitrend.com/api/seller/v1). Alanların tam şeması OpenAPI dosyasındadır.

Kategoriler

MetotYolAçıklama
GET/categoriesKategori listesi ve her kategoride sana uygulanan komisyon oranı (commissionBps; 1500 = %15).

Ürünler

MetotYolAçıklama
GET/productsÜrün listesi. status (active, draft, archived) ile süz; barcode ya da stockCode ile bul.
POST/productsTek ürün oluşturur: seçenekler, barkod/stok kodları, en fazla 8 görsel adresi. dry_run destekler.
GET/products/{id}Ürün detayı: seçenekler, barkod/stok kodları ve satılabilir stok.
PUT/products/{id}Ürünü günceller. images ve variants zorunlu ve tam liste: listede olmayan mevcut seçenek pasife alınır. Mevcut seçeneğin stoğu bu uçtan değişmez. dry_run destekler.
POST/products/{id}/statusYayınla ya da taslağa al: {"status":"active"} / {"status":"draft"}. Yayın için en az bir görsel ve bir aktif seçenek gerekir.

Katalog eşleştirme (ana katalog açıldığında)

MetotYolAçıklama
GET/catalog/lookupYenitrend ana kataloğunda ara: ?gtin= (barkod) ya da ?q= (2–100 karakter metin), tam olarak biri. Yalnız onaylı katalog kayıtları döner (incelemedeki ya da başka mağazanın önerisi görünmez); her kayıtta varyantlar (catalogItemId), komisyon oranın ve bu kayda mevcut teklifin. Ana katalog açılmadan önce 404 döner (details.reason: catalog_disabled).

Fiyat & Stok

MetotYolAçıklama
POST/stock-priceToplu fiyat ve stok güncelleme (en fazla 500 kalem). Her kalem variantId, stockCode ya da barcode alanlarından tam olarak biriyle seçilir; price (KDV dahil kuruş) ve/veya stock (satılabilir adet) mutlak değerdir. Kalem başına sonuç döner. Fiyatı yarıdan fazla düşüren kalem price_drop_confirm_required ile uygulanmaz; bilerek yapıyorsan kaleme confirmLargeDrop: true ekle. dry_run destekler.

Siparişler

MetotYolAçıklama
GET/ordersSipariş listesi (yeniden eskiye). status, createdFrom / createdTo ile süz. Yanıtta durum başına sayılar (counts) da gelir.
GET/orders/{orderNumber}Sipariş detayı: kalemler, teslimat bilgisi, paketler, iptal/iade bilgisi. Teslim tarihi yalnız okunur.
POST/orders/{orderNumber}/preparingSiparişi hazırlamaya başlar. Gövde yok.
POST/orders/{orderNumber}/invoice-issuedFaturanın kesildiğini işaretler (bir kez, geri alınamaz). Gövde yok.
POST/orders/{orderNumber}/cancelTedarik edemediğin adetleri iptal eder. reasonCode zorunlu; items verilmezse kargolanmamış tüm adetler iptal edilir. Müşteriye para iadesi otomatik başlar.

Kargo

MetotYolAçıklama
GET/carriersKargo firması kodları.
POST/orders/{orderNumber}/shipmentsPaket açar. Gövde: {"items":[{"orderItemId":…,"qty":…}]}.
POST/orders/{orderNumber}/shipments/{shipmentId}/shipPaketi kargoya verir (carrier + trackingNo). Teslim bilgisi kargo tarafından gelir; satıcı yazamaz.
PUT/orders/{orderNumber}/shipments/{shipmentId}/trackingKargo firmasını ya da takip numarasını düzeltir (sınırlı süre ve sayıda).
DELETE/orders/{orderNumber}/shipments/{shipmentId}Henüz kargoya verilmemiş paketi iptal eder.

İptal talepleri

MetotYolAçıklama
GET/cancel-requestsMüşterilerin iptal talepleri. status (open, active, all) ve orderNumber ile süz.
POST/cancel-requests/{cancelRequestId}/acceptİptal talebini kabul eder; müşteriye para iadesi başlar. Gövde yok.

İadeler

MetotYolAçıklama
GET/returnsİade listesi. filter: action (senin adımını bekleyenler), open, closed, all.
GET/returns/{returnId}İade detayı.
POST/returns/{returnId}/approveİadeyi onaylar. Gövde yok.
POST/returns/{returnId}/objectİadeye itiraz eder; kararı Yenitrend verir. note zorunlu.
POST/returns/{returnId}/receiveİade paketini teslim aldığını işaretler; inceleme panelde yapılır. Gövde isteğe bağlı: müşteri kargoya verdiğini bildirmeden ulaşan anlaşmalı kodlu iadede trackingNo zorunlu.

Ürün yazma kuralları

  • Stok yalnız POST /stock-price ile değişir. PUT /products/{id} mevcut seçeneğin stoğunu değiştirmez; yalnız yeni eklenen seçeneğin (id'siz) başlangıç stoğu verilir.
  • stock değeri satılabilir adettir: Yenitrend'de ödemesi beklenen sepet ayırmaları bu değerden otomatik düşülür (yanıtta reserved alanı). Elindeki stoktan, API'den çektiğin ama henüz kargolamadığın siparişleri düşüp gönder.
  • Satıcı hesabı işlem sırasında askıya alınırsa kalan kalemler seller_not_allowed sonucuyla döner.
  • PUT isteğinde images ve variants zorunlu ve tam listedir. Mevcut seçenekleri id ile gönder; listede olmayan mevcut seçenek pasife alınır. Gönderilmeyen isteğe bağlı ürün alanları mevcut değerini korur. Dikkat: seçenek içinde priceOverride gönderilmezse o seçeneğin özel fiyatı silinir ve ürün fiyatına döner; özel fiyatı korumak için her PUT'ta yeniden gönder.
  • Görseller: en fazla 8 adres. Herkese açık https adresleri sunucu indirir; ürünün mevcut /uploads/… yolları olduğu gibi korunur.
  • Seçenek boyutunun adı (ör. Beden, Renk) ürünün variantLabel alanıdır; ayrıca kategori özelliği tablosu yoktur.
  • Ana katalog açıldığında her ürün bir katalog kaydına bağlanır. POST /products seçeneklerinde catalogItemId (GET /catalog/lookup yanıtından) ya da geçerli bir barcode (GTIN) ver: eşleşen onaylı kayda bağlanır, içerik katalogdan gelir (content_ignored). Katalogda eşleşme yoksa ürün yeni katalog önerisi olarak incelemeye gider; bunun için gövdede contentConsent: true (içeriğin sana ait olduğu ve katalogda diğer satıcıların teklifleriyle kullanılmasına izin verdiğin beyanı), catalogCategoryId (en alt katalog kategorisi) ve birden çok seçenekte her seçenek için axisValues (ör. {"renk":"Siyah"}) gerekir. İzin yoksa 409 invalid_state (details.reason: consent_required), kategori yoksa 400 (details.field: catalogCategoryId); bu durumlarda ürün oluşturulmaz. Yanıttaki catalog alanı bağ durumunu (linked / proposed) ve yayın engelini gösterir. Bu alanlar katalog açılmadan önce bilinmeyen alan sayılır (400).

Ürün oluşturma ve güncelleme yanıtında warnings dizisi şu kodları taşıyabilir:

KodAnlamı
relist_reviewÜrün, daha önce kaldırılmış bir ürününe benziyor; taslak olarak kaydedildi ve incelemeye alındı.
missing_imageYayın istendi ama görsel yok; ürün taslak olarak kaydedildi.
image_failedBazı görseller indirilemedi; ürün yine kaydedildi. İstekteki sıra numaraları (0'dan) failedImages alanında.
content_ignoredAna katalog açıkken: ürün katalogdaki bir kayda bağlı; başlık, marka, açıklama, görseller ve kategori katalogdan gelir, gönderdiğin içerik yok sayıldı (fiyat, stok, stok kodu senin).
catalog_blockedAna katalog açıkken: yayın istendi ama katalog kaydı henüz onaylı değil ya da teklif bilgisi eksik; ürün taslak kaydedildi (neden catalog.blockedReason).

Örnekler

Kargolanacak siparişleri listele

curl -s "https://yenitrend.com/api/seller/v1/orders?status=open&page=1&size=50" \
  -H "Authorization: Bearer yt_live_<keyId>_<secret>"
{
  "data": {
    "items": [ … ],
    "page": 1,
    "size": 50,
    "hasMore": true,
    "counts": { "open": 4, "new": 2, "preparing": 2, "shipped": 9, "delivered": 31, "cancelled": 1 }
  }
}

Stok ve fiyat güncelle

Önce dry_run=true ile dene; kalem sonuçlarını (ok ya da hata code) kontrol et.

curl -s -X POST "https://yenitrend.com/api/seller/v1/stock-price?dry_run=true" \
  -H "Authorization: Bearer yt_live_<keyId>_<secret>" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 5d2a7f30-1c6e-4b8a-9f04-7e3b2c1a0d96" \
  -d '{
    "items": [
      { "stockCode": "KLM-001-S", "stock": 25 },
      { "barcode": "8690000000017", "price": 12990 },
      { "variantId": 4182, "price": 24900, "stock": 3 }
    ]
  }'

Sonuç doğruysa aynı gövdeyi dry_run olmadan, yeni bir Idempotency-Key ile gönder:

curl -s -X POST "https://yenitrend.com/api/seller/v1/stock-price" \
  -H "Authorization: Bearer yt_live_<keyId>_<secret>" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 3f1c2b9e-8a47-4d0e-9a51-6c2f7e4b1d20" \
  -d '{ "items": [ … ] }'

Paketi kargoya ver

Paket kimliğini sipariş detayından ya da paket açma yanıtından al. Firma kodları GET /carriers ucunda.

curl -s -X POST "https://yenitrend.com/api/seller/v1/orders/YT7K3M9QX2BD/shipments/918/ship" \
  -H "Authorization: Bearer yt_live_<keyId>_<secret>" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 9b0e4c11-52d3-4f7a-8e6b-0c1d2a3b4c5d" \
  -d '{ "carrier": "yurtici", "trackingNo": "123456789012" }'

OpenAPI ve destek

Makinece okunabilir şema (OpenAPI 3.1): /api/seller/v1/openapi.json (anahtar gerekmez).

Sorun ya da öneri için iletişim sayfasından bize yaz. Mesajına anahtarını ekleme; yalnız anahtarın başındaki yt_live_<keyId> kısmı yeterli.

Satıcıysan anahtarını Satıcı Paneli → API Erişimi sayfasından yönetebilirsin.