Pazaryeri API

v1.0 Dokümantasyonu

Başlarken

Önemli

Bu dokümantasyon geliştirme ortamı için hazırlanmıştır. Production ortamında URL'leri güncelleyiniz.

Temel Bilgiler

Base URL: https://idnsx.com/espazar/api/v1
Production URL: https://api.yourmarketplace.com/v1
Protokol: HTTPS (geliştirme için HTTP)
Authentication: Bearer Token (JWT)
Rate Limit: 1000 istek/saat
Response Format: JSON

Test Ortamı

Test Satıcısı: ID: 156
API Anahtarları: Satıcı panelinden oluşturun
Satıcı Paneli: bayi/

API Endpoint'leri Özeti

Authentication

/auth/token
POST Token alma
/auth/token/verify
GET Token doğrulama
/auth/token/refresh
POST Token yenileme
/auth/token/revoke
POST Token iptal etme

Products

/products
GET POST Ürün listeleme/oluşturma
/products/{id}
GET PUT PATCH DELETE Ürün detay/güncelleme/silme

Orders

/orders
GET POST Sipariş listeleme/oluşturma
/orders/{id}
GET Sipariş detayı
/orders/{id}/status
PATCH Sipariş durumu güncelleme

Kimlik Doğrulama

API Anahtarları

Her satıcının satıcı panelinden API anahtarları oluşturması gerekir:

API Key

Satıcıyı tanımlayan benzersiz anahtar (64 karakter)

API Secret

Token üretimi için kullanılan gizli anahtar (64 karakter)

📋 API Anahtarı Oluşturma

  1. Satıcı paneline giriş yapın: Satıcı Paneli
  2. "Genel İşlemler" → "API Ayarları" menüsüne gidin
  3. "API Anahtarları Oluştur" butonuna tıklayın
  4. Oluşturulan anahtarları güvenli bir yerde saklayın

Token Alımı

POST /api/v1/auth/token
Content-Type: application/json
{
  "api_key": "67036b7e7a5cca8ec6e6352aaee72f55e5df5d37afe96a26f6f951fa68dbfe28",
  "api_secret": "7e8d21afe7b8c9d4e5f63a17b28c94d5e6f7a8b9c1d2e3f4a5b6c7d8e9f1a2b3"
}
JavaScript Örneği (Swagger ile aynı):
// Token al
const tokenResponse = await axios.post('https://idnsx.com/espazar/api/v1/auth/token', {
  api_key: 'YOUR_API_KEY_64_CHARS',
  api_secret: 'YOUR_API_SECRET_64_CHARS'
}, {
  headers: {
    'Content-Type': 'application/json',
    'Accept': 'application/json'
  }
});

// Token'ı kaydet
const accessToken = tokenResponse.data.data.access_token;
const refreshToken = tokenResponse.data.data.refresh_token;

console.log('Token alındı, expires_in:', tokenResponse.data.data.expires_in);
console.log('Satıcı ID:', tokenResponse.data.data.seller.id);
cURL Örneği (Swagger'dan kopyala-yapıştır):
curl -X POST "https://idnsx.com/espazar/api/v1/auth/token" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "api_key": "YOUR_API_KEY",
    "api_secret": "YOUR_API_SECRET"
  }'
Başarılı Yanıt
{
  "success": true,
  "timestamp": "2025-10-06 20:10:58",
  "request_id": "req_68e4063264bb92.17659693",
  "data": {
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
    "token_type": "Bearer",
    "expires_in": 3600,
    "refresh_token": "e5d9e4344564b117f0a6a35e703d67a21470cef5c4a4d61154f05f11488862cd",
    "seller": {
      "id": 156,
      "name": "Mağaza Adı",
      "email": "support@iwebsa.com"
    }
  },
  "message": "Token generated successfully"
}

Token Doğrulama

GET /api/v1/auth/token/verify
Authorization: Bearer your_access_token

⚡ Body Gerekmez - GET request

// Body yok, Bearer token doğrulanır
Response Örneği (Token Geçerli):
{
  "success": true,
  "timestamp": "2025-10-08 12:03:45",
  "request_id": "req_68e6326123456.56789012",
  "data": {
    "seller_id": 156,
    "seller_name": "Mağaza Adı",
    "valid": true
  },
  "message": "Token is valid"
}
JavaScript Örneği:
// Token doğrula - GET request
const verify = await axios.get('https://idnsx.com/espazar/api/v1/auth/token/verify', {
  headers: { 'Authorization': `Bearer ${accessToken}` }
});

if (verify.data.data.valid) {
  console.log('Token geçerli, Satıcı ID:', verify.data.data.seller_id);
}

// VEYA base URL ile (önerilen):
// axios.defaults.baseURL = 'https://pazaryeri.com';
// const verify = await axios.get('/api/v1/auth/token/verify', { ... });
Hata Durumu (Token Geçersiz/Süresi Dolmuş):
{
  "success": false,
  "timestamp": "2025-10-08 12:03:45",
  "request_id": "req_xxx",
  "error": {
    "message": "Token expired",
    "code": "Unauthorized"
  }
}

Token Yenileme

POST /api/v1/auth/token/refresh
Content-Type: application/json
{
  "refresh_token": "e5d9e4344564b117f0a6a35e703d67a21470cef5c4a4d61154f05f11488862cd"
}
Response Örneği:
{
  "success": true,
  "timestamp": "2025-10-08 12:05:30",
  "request_id": "req_68e632ba123456.78901234",
  "data": {
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
    "token_type": "Bearer",
    "expires_in": 3600,
    "refresh_token": "f7e8d5455675c228g1b7b46f814e78b32581def6d5b5e72265g16g22599973de"
  },
  "message": "Token refreshed successfully"
}
JavaScript Örneği:
// Token yenile
const refreshResponse = await axios.post('/api/v1/auth/token/refresh', {
  refresh_token: oldRefreshToken
});

// Yeni token'ları kaydet
const newAccessToken = refreshResponse.data.data.access_token;
const newRefreshToken = refreshResponse.data.data.refresh_token;

console.log('Token yenilendi, expires_in:', refreshResponse.data.data.expires_in);

Token İptal Etme

POST /api/v1/auth/token/revoke
Authorization: Bearer your_access_token

⚡ Body Gerekmez - Sadece Authorization Header

// Body yok, Bearer token kimliği belirler
Response Örneği (204 No Content):
// Başarılı iptal - body döner, ancak HTTP 204 döner
{
  "success": true,
  "timestamp": "2025-10-08 12:00:00",
  "request_id": "req_xxx",
  "message": "Token revoked successfully"
}
JavaScript Örneği:
// Token iptal et - body gerekmez
const revoke = await axios.post('/api/v1/auth/token/revoke', {}, {
  headers: { 'Authorization': `Bearer ${accessToken}` }
});

// Veya daha kısa
await axios.post('/api/v1/auth/token/revoke', null, {
  headers: { 'Authorization': `Bearer ${accessToken}` }
});

⚠️ Önemli Not

Token revoke işlemi refresh token'ı siler ve yeni token almayı engeller. Access token ise süresi dolana kadar geçerli kalır (JWT'nin stateless doğası gereği).

API İsteklerinde Authentication

Authorization: Bearer your_access_token
X-Seller-ID: 156 (opsiyonel)

Ürün Yönetimi

Ürün Listeleme

GET /api/v1/products?page=1&per_page=50&status=active
Authorization: Bearer your_token

Query Parameters:

page

Sayfa numarası (varsayılan: 1)

per_page

Sayfa başına öğe sayısı (varsayılan: 50, max: 100)

status

Ürün durumu (active, passive, deleted)

category_id

Kategori ID'si (Ana kategori ID otomatik olarak kategori hiyerarşisinde recursive olarak tespit edilir - parent_id = 0 olana kadar yukarı çıkılır)

updated_after

Belirtilen tarihten sonra güncellenenler

JavaScript Örneği (Swagger ile aynı):
// Ürünleri listele (temel bilgiler)
const products = await axios.get('https://idnsx.com/espazar/api/v1/products', {
  params: {
    page: 1,
    per_page: 50,
    status: 'active'
  },
  headers: {
    'Authorization': `Bearer ${accessToken}`,
    'Accept': 'application/json'
  }
});

// Ürünleri detaylı listele (varyant, stok, özellikler, resimler dahil)
const detailedProducts = await axios.get('https://idnsx.com/espazar/api/v1/products', {
  params: {
    page: 1,
    per_page: 50,
    include: 'variants,stock,features,images'  // Ek bilgileri dahil et
  },
  headers: {
    'Authorization': `Bearer ${accessToken}`,
    'Accept': 'application/json'
  }
});

console.log('Toplam ürün:', products.data.data.pagination.total);
console.log('İlk ürün:', products.data.data.products[0]);
cURL Örneği (Swagger'dan kopyala-yapıştır):
# Temel listeleme
curl -X GET "https://idnsx.com/espazar/api/v1/products?page=1&per_page=50&status=active" \
  -H "Accept: application/json" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

# Detaylı listeleme (varyant, stok, özellikler, resimler dahil)
curl -X GET "https://idnsx.com/espazar/api/v1/products?include=variants,stock,features,images" \
  -H "Accept: application/json" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Yanıt Örneği
{
  "success": true,
  "data": {
    "products": [
      {
        "id": 20520,
        "sku": "PROD-12345",
        "title": "Samsung Galaxy S24",
        "description": "Detaylı ürün açıklaması",
        "barcode": "8690123456789",
        "price": 25999.99,
        "discount_price": 23999.99,
        "market_price": 27999.99,
        "category_id": 137,
        "category_name": "Cep Telefonu",
        "brand_name": "Samsung",
        "status": "active",
        "image": "https://sandbox.esnafpazar.com/dosya/product-image.webp",
        "stock_quantity": 10,
        "created_at": 1728307200,
        "updated_at": 1728307800
      }
    ],
    "pagination": {
      "page": 1,
      "per_page": 50,
      "total": 150,
      "total_pages": 3
    }
  }
}

Yeni Ürün Oluşturma

POST /api/v1/products
Authorization: Bearer your_token

✅ Zorunlu Alanlar: title, category_id, price

ℹ️ Opsiyonel: description, market_price, sku, barcode, images, variants, stock_quantity, stock_code

{
  // ✅ ZORUNLU ALANLAR
  "title": "Samsung Galaxy S24",
  "category_id": 137,
  "price": 25999.99,

  // ℹ️ OPSİYONEL TEMEL BİLGİLER
  "description": "Detaylı ürün açıklaması",
  "market_price": 27999.99,
  "sku": "PROD-12345",
  "barcode": "8690123456789",

  // ℹ️ OPSİYONEL STOK YÖNETİMİ
  "stock_quantity": 100,
  "stock_code": "SKU-MAIN",

  // ℹ️ OPSİYONEL RESİMLER (array)
  "images": [
    "https://example.com/image1.jpg",
    "https://example.com/image2.jpg"
  ],

  // ℹ️ OPSİYONEL VARYANTLAR (array)
  "variants": [
    {
      "attributes": {
        "1": 5,  // Renk: Mavi
        "2": 8   // Kapasite: 128GB
      },
      "price": 25999.99,
      "market_price": 27999.99,
      "stock_quantity": 50
    }
  ]
}
📋 Parametre Detayları:
Parametre Tip Zorunlu Açıklama
title string ✅ Evet Ürün adı
category_id integer ✅ Evet Kategori ID (Ana kategori ID otomatik olarak kategori hiyerarşisinde recursive olarak tespit edilir - parent_id = 0 olana kadar yukarı çıkılır)
price decimal ✅ Evet Satış fiyatı
description string ❌ Hayır Ürün açıklaması
market_price decimal ❌ Hayır Piyasa fiyatı (indirim göstermek için)
sku string ❌ Hayır Stok kodu / Model kodu
barcode string ❌ Hayır Barkod numarası
stock_quantity integer ❌ Hayır Stok adedi
stock_code string ❌ Hayır Stok tanımlama kodu (varsayılan: DEFAULT)
images array ❌ Hayır Ürün resimleri URL listesi
variants array ❌ Hayır Ürün varyantları (renk, beden vs.)
JavaScript Örneği (Swagger ile aynı):
// Basit ürün oluştur (sadece zorunlu alanlar)
const simpleProduct = await axios.post('https://idnsx.com/espazar/api/v1/products', {
  title: 'Samsung Galaxy S24',
  category_id: 137,
  price: 25999.99
}, {
  headers: {
    'Authorization': `Bearer ${accessToken}`,
    'Content-Type': 'application/json'
  }
});

// Tam detaylı ürün oluştur (tüm alanlar)
const fullProduct = await axios.post('https://idnsx.com/espazar/api/v1/products', {
  title: 'Samsung Galaxy S24',
  description: 'Detaylı ürün açıklaması',
  category_id: 137,
  price: 25999.99,
  market_price: 27999.99,
  sku: 'PROD-12345',
  barcode: '8690123456789',
  stock_quantity: 100,
  stock_code: 'SKU-MAIN',
  images: [
    'https://example.com/image1.jpg',
    'https://example.com/image2.jpg'
  ]
}, {
  headers: {
    'Authorization': `Bearer ${accessToken}`,
    'Content-Type': 'application/json'
  }
});

console.log('Ürün ID:', fullProduct.data.data.product_id);
cURL Örneği (Swagger'dan kopyala-yapıştır):
curl -X POST "https://idnsx.com/espazar/api/v1/products" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "title": "Samsung Galaxy S24",
    "category_id": 137,
    "price": 25999.99,
    "description": "Detaylı ürün açıklaması",
    "market_price": 27999.99,
    "sku": "PROD-12345",
    "barcode": "8690123456789",
    "stock_quantity": 100
  }'
Response Örneği:
{
  "success": true,
  "timestamp": "2025-10-07 09:15:30",
  "request_id": "req_68e4bcd1234567.89012345",
  "data": {
    "product_id": 12345,
    "message": "Product created successfully"
  }
}

Ürün Güncelleme

PUT veya PATCH /api/v1/products/{product_id}
Authorization: Bearer your_token

ℹ️ PUT: Tüm alanları gönder | PATCH: Sadece değiştirmek istediğin alanları gönder

✅ Güncellenebilir Alanlar: title, description, price, discount_price, market_price, sku, barcode, category_id, images, variants, stock_quantity, stock_code

{
  // 📝 TEMEL BİLGİLER (hepsi opsiyonel)
  "title": "Samsung Galaxy S24 Ultra",
  "description": "Güncellenmiş açıklama",
  "category_id": 138,

  // 💰 FİYATLANDIRMA
  "price": 29999.99,
  "market_price": 31999.99,
  "discount_price": 27999.99,  // İndirimli fiyat

  // 📦 ÜRÜN KODLARI
  "sku": "PROD-12345-V2",
  "barcode": "8690123456789",

  // 📊 STOK YÖNETİMİ
  "stock_quantity": 150,
  "stock_code": "SKU-UPDATED",

  // 🖼️ RESİMLERİ YENİLE (mevcut resimleri siler, yenilerini ekler)
  "images": [
    "https://example.com/new-image1.jpg",
    "https://example.com/new-image2.jpg"
  ],

  // 🎨 VARYANTLARI YENİLE (mevcut varyantları siler, yenilerini ekler)
  "variants": [
    {
      "attributes": {
        "1": 6,  // Renk: Siyah
        "2": 9   // Kapasite: 256GB
      },
      "price": 32999.99,
      "market_price": 34999.99,
      "stock_quantity": 75
    }
  ]
}
🔄 PUT vs PATCH Farkı:
PUT (Tam Güncelleme)

Tüm alanları göndermen gerekir. Gönderilmeyen alanlar sıfırlanmaz ama tam güncelleme anlamına gelir.

{
  "title": "Yeni Başlık",
  "price": 29999.99,
  "market_price": 31999.99
  // Diğer alanlar değişmez
}
PATCH (Kısmi Güncelleme)

Sadece değiştirmek istediğin alanları gönder. Diğer alanlar olduğu gibi kalır.

{
  "price": 29999.99
  // Sadece fiyat güncellenir
}
📋 Güncellenebilir Parametreler:
Parametre Tip Açıklama
title string Ürün adı
description string Ürün açıklaması
price decimal Satış fiyatı
discount_price decimal İndirimli fiyat
market_price decimal Piyasa fiyatı
sku string Stok kodu / Model kodu
barcode string Barkod numarası
category_id integer Kategori ID (Ana kategori ID otomatik olarak kategori hiyerarşisinde recursive olarak tespit edilir - parent_id = 0 olana kadar yukarı çıkılır)
stock_quantity integer Stok adedi
stock_code string Stok tanımlama kodu
images array ⚠️ Tüm mevcut resimleri siler ve yenilerini ekler
variants array ⚠️ Tüm mevcut varyantları siler ve yenilerini ekler
JavaScript Örnekleri (Swagger ile aynı):
📝 PATCH - Sadece fiyat güncelle:
// Sadece değiştirmek istediğin alanları gönder
const updatePrice = await axios.patch(`https://idnsx.com/espazar/api/v1/products/12345`, {
  price: 29999.99,
  market_price: 31999.99
}, {
  headers: {
    'Authorization': `Bearer ${accessToken}`,
    'Content-Type': 'application/json'
  }
});

console.log('Ürün güncellendi:', updatePrice.data.data.product_id);
📝 PUT - Tam güncelleme:
// Tüm alanları güncelle
const fullUpdate = await axios.put(`https://idnsx.com/espazar/api/v1/products/12345`, {
  title: 'Samsung Galaxy S24 Ultra',
  description: 'Güncellenmiş açıklama',
  category_id: 138,
  price: 29999.99,
  market_price: 31999.99,
  discount_price: 27999.99,
  sku: 'PROD-12345-V2',
  barcode: '8690123456789',
  stock_quantity: 150
}, {
  headers: {
    'Authorization': `Bearer ${accessToken}`,
    'Content-Type': 'application/json'
  }
});

console.log('Tam güncelleme tamamlandı');
cURL Örnekleri (Swagger'dan kopyala-yapıştır):
PATCH - Kısmi güncelleme:
curl -X PATCH "https://idnsx.com/espazar/api/v1/products/12345" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "price": 29999.99,
    "market_price": 31999.99
  }'
PUT - Tam güncelleme:
curl -X PUT "https://idnsx.com/espazar/api/v1/products/12345" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Samsung Galaxy S24 Ultra",
    "price": 29999.99,
    "market_price": 31999.99,
    "description": "Güncellenmiş açıklama"
  }'
Response Örneği:
{
  "success": true,
  "timestamp": "2025-10-08 12:15:45",
  "request_id": "req_68e634a1234567.89012345",
  "data": {
    "product_id": 12345,
    "message": "Product updated successfully"
  }
}
⚠️ Önemli Uyarılar
  • images array'i gönderirsen: Tüm mevcut resimler silinir, sadece yeni gönderdiğin resimler eklenir
  • variants array'i gönderirsen: Tüm mevcut varyantlar silinir, sadece yeni gönderdiğin varyantlar eklenir
  • • Tek bir resim veya varyant eklemek için POST /products/{id}/images veya POST /products/{id}/variants kullan

Ürün Silme (Hard Delete)

DELETE /api/v1/products/{product_id}
Authorization: Bearer your_token

⚡ Body Gerekmez - Sadece URL'de product_id

🔥 Hard Delete: Ürün ve tüm ilişkili veriler kalıcı olarak silinir!

🗑️ Silinecek Veriler:

Ürün Kaydı

Ürün bilgileri tamamen silinir

Tüm Resimler

Galeri resimleri ve dosyalar silinir

Tüm Varyantlar

Renk, beden vs. tüm varyantlar silinir

Stok Kayıtları

Tüm stok bilgileri silinir

Filtre Ayarları

Ürüne özel filtreler silinir

Resim Dosyaları

Sunucudaki fiziksel dosyalar silinir

🔄 Silme Süreci (Transaction ile):
  1. 1. Ürün sahipliği doğrulanır (sadece kendi ürününü silebilirsin)
  2. 2. Ürün resim dosyaları sunucudan fiziksel olarak silinir
  3. 3. Galeri resimleri veritabanından ve sunucudan silinir
  4. 4. Stok kayıtları (stok_urun) silinir
  5. 5. Ürün varyantları (urun_varyant) silinir
  6. 6. Ürün filtreleri (urun_filtre) silinir
  7. 7. Ürün kaydı tamamen silinir (hard delete)
  8. 8. Tüm işlemler başarılıysa commit, hata varsa rollback yapılır
JavaScript Örneği (Swagger ile aynı):
// Ürün sil (onay sonrası)
const deleteProduct = async (productId) => {
  // Kullanıcıdan onay al
  const confirmed = confirm('Bu ürünü kalıcı olarak silmek istediğinize emin misiniz? Bu işlem geri alınamaz!');

  if (!confirmed) {
    console.log('Silme işlemi iptal edildi');
    return;
  }

  try {
    const response = await axios.delete(`https://idnsx.com/espazar/api/v1/products/${productId}`, {
      headers: {
        'Authorization': `Bearer ${accessToken}`
      }
    });

    if (response.data.success) {
      console.log('Ürün başarıyla silindi:', response.data.data);
      // UI'dan ürünü kaldır
    }
  } catch (error) {
    console.error('Silme hatası:', error.response?.data?.error?.message);
  }
};

// Kullanım
deleteProduct(12345);
cURL Örneği (Swagger'dan kopyala-yapıştır):
curl -X DELETE "https://idnsx.com/espazar/api/v1/products/12345" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Accept: application/json"
Response Örneği (Başarılı):
{
  "success": true,
  "timestamp": "2025-10-08 12:30:15",
  "request_id": "req_68e636f7123456.78901234",
  "data": {
    "message": "Product deleted successfully",
    "product_id": 12345
  }
}
❌ Olası Hata Durumları:
404 - Ürün Bulunamadı:
{
  "success": false,
  "error": {
    "message": "Product not found or access denied",
    "code": "Not Found"
  }
}

Sebepler: Ürün mevcut değil veya başka satıcıya ait

403 - Yetkisiz Erişim:
{
  "success": false,
  "error": {
    "message": "You don't have permission to delete this product",
    "code": "Forbidden"
  }
}

Sebep: Başka satıcının ürününü silmeye çalışıyorsun

🔥 KRİTİK UYARILAR

  • ⚠️ GERİ ALINAMAZ: Bu işlem kalıcıdır, geri alma özelliği yoktur!
  • ⚠️ TÜM VERİLER: Ürün, resimler, varyantlar, stok - her şey silinir!
  • ⚠️ FİZİKSEL DOSYALAR: Sunucudaki resim dosyaları da kalıcı olarak silinir!
  • ⚠️ TRANSACTION: Herhangi bir hata durumunda tüm işlem geri alınır (rollback)
  • 💡 ALTERNATİF: Kalıcı silmek yerine ürün durumunu "passive" yaparak devre dışı bırakabilirsin
💡 Alternatif: Soft Delete (Önerilen)

Ürünü kalıcı silmek yerine durumunu passive yaparak devre dışı bırakabilirsin:

// Soft delete (ürün gizlenir ama kalır)
await axios.patch(`https://idnsx.com/espazar/api/v1/products/12345`, {
  status: 0  // passive
}, {
  headers: { 'Authorization': `Bearer ${accessToken}` }
});

// Gerekirse tekrar aktif edebilirsin
await axios.patch(`https://idnsx.com/espazar/api/v1/products/12345`, {
  status: 1  // active
});

Ürün Varyant Yönetimi

📌 Varyant Nedir?

Varyantlar, aynı ürünün farklı özelliklerini temsil eder. Örnek: Bir tişört için farklı renkler ve bedenler.

📦 Örnek Varyantlar:

• Renk: Mavi, Kırmızı, Siyah

• Beden: S, M, L, XL

• Kapasite: 64GB, 128GB, 256GB

💰 Fiyat ve Stok:

Her varyantın kendi fiyatı ve stok miktarı olabilir

🔑 Stok Kodu:

Her varyant için otomatik benzersiz stok kodu oluşturulur

1 Varyantları Listele

GET /api/v1/products/{product_id}/variants
Authorization: Bearer your_token

⚡ Body Gerekmez - Sadece product_id yeterli

JavaScript Örneği:
// Ürünün tüm varyantlarını listele
const getVariants = async (productId) => {
  try {
    const response = await axios.get(
      `https://idnsx.com/espazar/api/v1/products/${productId}/variants`,
      {
        headers: { 'Authorization': `Bearer ${accessToken}` }
      }
    );

    console.log('Varyantlar:', response.data.data.variants);

    // Her varyantın detayları
    response.data.data.variants.forEach(variant => {
      console.log(`SKU: ${variant.stock_code}`);
      console.log(`Fiyat: ${variant.price} TL`);
      console.log(`Stok: ${variant.stock_quantity} adet`);
      console.log(`Özellikler:`, variant.attributes);
    });
  } catch (error) {
    console.error('Hata:', error.response?.data?.error?.message);
  }
};

// Kullanım
getVariants(12345);
cURL Örneği (Swagger'dan):
curl -X GET "https://idnsx.com/espazar/api/v1/products/12345/variants" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Accept: application/json"
Response Örneği:
{
  "success": true,
  "timestamp": "2025-10-08 13:15:22",
  "request_id": "req_68e6456a123456.78901234",
  "data": {
    "variants": [
      {
        "variant_id": 1,
        "stock_code": "SKU-12345-abc123",
        "variant_name": "Samsung Galaxy S24 - Mavi, 128GB",
        "price": 25999.99,
        "market_price": 27999.99,
        "stock_quantity": 50,
        "attributes": {
          "Renk": "Mavi",
          "Kapasite": "128GB"
        }
      },
      {
        "variant_id": 2,
        "stock_code": "SKU-12345-def456",
        "variant_name": "Samsung Galaxy S24 - Siyah, 256GB",
        "price": 29999.99,
        "market_price": 31999.99,
        "stock_quantity": 30,
        "attributes": {
          "Renk": "Siyah",
          "Kapasite": "256GB"
        }
      }
    ]
  }
}

2 Varyant Sözlüğü (ID & İsim Eşleştirme)

Entegrasyon yaparken, attributes içinde gönderdiğiniz sayısal ID'lerin (örn. 37 ve 1137) hangi varyant ve alt varyanta karşılık geldiğini API üzerinden görebilmeniz için bir lookup endpoint sağlanır.

Bu endpoint sadece okuma amaçlıdır; ürün/varyant oluştururken kullanacağınız tüm varyant_id ve alt_varyant_id değerlerini buradan çekip kendi sisteminizde cache'leyebilirsiniz.

GET /api/v1/variants
Authorization: Bearer your_token

⚡ Body Gerekmez - Sistemdeki tüm varyant başlıklarını ve alt varyantları döner

Response Örneği:
{
  "success": true,
  "timestamp": "2025-10-22 10:00:00",
  "request_id": "req_68f88abcd12345.67890123",
  "data": {
    "variants": [
      {
        "id": 37,
        "name": "Renk",
        "system_name": "Ana Renk",
        "sort_order": 1,
        "is_color": true,
        "is_active": true,
        "options": [
          { "id": 1137, "name": "Sarı", "sort_order": 0 },
          { "id": 1138, "name": "Kırmızı", "sort_order": 1 }
        ]
      },
      {
        "id": 44,
        "name": "Boyut / Ebat",
        "system_name": "Takı Boyut ebat",
        "sort_order": 2,
        "is_color": false,
        "is_active": true,
        "options": [
          { "id": 2001, "name": "S", "sort_order": 0 },
          { "id": 2002, "name": "M", "sort_order": 1 }
        ]
      }
    ]
  }
}
🔁 Önerilen Entegrasyon Akışı
  • 1. Önce GET /api/v1/variants çağrısı yapın ve tüm varyant ID'lerini kendi sisteminize alın.
  • 2. Kendi panelinizde kullanıcıya "Renk", "Sarı" gibi gösterin.
  • 3. Kullanıcı seçim yaptığında arka planda ilgili varyant_id ve alt_varyant_id değerlerini attributes alanında gönderin.
  • 4. Böylece hem insan-okunur arayüz, hem de API'nin beklediği numeric ID'ler otomatik eşleşmiş olur.

3 Varyant Oluştur

POST /api/v1/products/{product_id}/variants
Authorization: Bearer your_token
📋 Kullanılabilir Parametreler:
Parametre Tip Zorunlu Açıklama
attributes object Evet Varyant özellikleri (varyant_id: ozellik_id formatında)
price float Evet Satış fiyatı (TL)
stock_quantity integer Evet Stok miktarı (adet)
market_price float Hayır Piyasa fiyatı (indirim göstermek için)
💡 attributes Nasıl Çalışır?

attributes parametresi varyant_id: ozellik_id formatında gönderilir:

{
  "attributes": {
    "1": 5,   // 1 = Renk varyantı, 5 = Mavi özelliği
    "2": 8    // 2 = Kapasite varyantı, 8 = 128GB özelliği
  }
}

⚠️ Bu ID'ler sistemdeki varyant ve alt_varyant tablolarından alınmalıdır.

Request Body Örneği:
{
  "attributes": {
    "1": 5,     // Renk: Mavi
    "2": 8      // Kapasite: 128GB
  },
  "price": 25999.99,
  "market_price": 27999.99,
  "stock_quantity": 50
}
JavaScript Örneği:
// Yeni varyant oluştur
const createVariant = async (productId) => {
  try {
    const response = await axios.post(
      `https://idnsx.com/espazar/api/v1/products/${productId}/variants`,
      {
        attributes: {
          "1": 5,    // Renk: Mavi
          "2": 8     // Kapasite: 128GB
        },
        price: 25999.99,
        market_price: 27999.99,
        stock_quantity: 50
      },
      {
        headers: {
          'Authorization': `Bearer ${accessToken}`,
          'Content-Type': 'application/json'
        }
      }
    );

    console.log('Varyant oluşturuldu!');
    console.log('Stok Kodu:', response.data.data.stock_code);
    console.log('Varyant ID:', response.data.data.variant_id);
  } catch (error) {
    console.error('Hata:', error.response?.data?.error?.message);
  }
};

// Kullanım
createVariant(12345);
cURL Örneği (Swagger'dan):
curl -X POST "https://idnsx.com/espazar/api/v1/products/12345/variants" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "attributes": {"1": 5, "2": 8},
    "price": 25999.99,
    "market_price": 27999.99,
    "stock_quantity": 50
  }'
Response Örneği:
{
  "success": true,
  "timestamp": "2025-10-08 13:28:33",
  "request_id": "req_68e64891234567.89012345",
  "data": {
    "variant_id": 3,
    "stock_code": "SKU-12345-1a2b3c4d",
    "message": "Product variant created successfully"
  }
}

Otomatik oluşturulur: stock_code benzersiz şekilde sisteminiz tarafından oluşturulur

3 Varyant Güncelle

PUT /api/v1/products/{product_id}/variants/{variant_id}
Authorization: Bearer your_token

💡 Sadece güncellemek istediğin alanları gönder (PATCH mantığı)

🔄 Güncellenebilir Alanlar:

💰 price

Satış fiyatını güncelle

🏷️ market_price

Piyasa fiyatını güncelle

📦 stock_quantity

Stok miktarını güncelle

⚠️ NOT: attributes güncellenemez! Varyant özelliklerini değiştirmek için önce sil, sonra yenisini oluştur.

Request Body Örneği (Sadece fiyat güncellemesi):
{
  "price": 26999.99,
  "market_price": 28999.99
}
JavaScript Örneği:
// Varyant fiyat ve stok güncelle
const updateVariant = async (productId, variantId) => {
  try {
    const response = await axios.put(
      `https://idnsx.com/espazar/api/v1/products/${productId}/variants/${variantId}`,
      {
        price: 26999.99,
        market_price: 28999.99,
        stock_quantity: 75
      },
      {
        headers: {
          'Authorization': `Bearer ${accessToken}`,
          'Content-Type': 'application/json'
        }
      }
    );

    console.log('Varyant güncellendi:', response.data.data);
  } catch (error) {
    console.error('Hata:', error.response?.data?.error?.message);
  }
};

// Kullanım
updateVariant(12345, 3);
cURL Örneği (Swagger'dan):
curl -X PUT "https://idnsx.com/espazar/api/v1/products/12345/variants/3" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "price": 26999.99,
    "market_price": 28999.99,
    "stock_quantity": 75
  }'
Response Örneği:
{
  "success": true,
  "timestamp": "2025-10-08 13:35:18",
  "request_id": "req_68e64a36123456.78901234",
  "data": {
    "variant_id": 3,
    "stock_code": "SKU-12345-1a2b3c4d",
    "message": "Product variant updated successfully"
  }
}

4 Varyant Sil

DELETE /api/v1/products/{product_id}/variants/{variant_id}
Authorization: Bearer your_token

⚡ Body Gerekmez - product_id ve variant_id yeterli

🔥 Varyant ve stok kayıtları kalıcı olarak silinir!

🗑️ Silme İşlemi:

Varyant Kaydı

urun_varyant tablosundan silinir

Stok Kaydı

stok_urun tablosundan silinir

Transaction ile korunur: Hata durumunda tüm işlem geri alınır

JavaScript Örneği:
// Varyant sil (onay ile)
const deleteVariant = async (productId, variantId) => {
  const confirmed = confirm('Bu varyantı silmek istediğinize emin misiniz?');

  if (!confirmed) {
    console.log('Silme işlemi iptal edildi');
    return;
  }

  try {
    const response = await axios.delete(
      `https://idnsx.com/espazar/api/v1/products/${productId}/variants/${variantId}`,
      {
        headers: { 'Authorization': `Bearer ${accessToken}` }
      }
    );

    console.log('Varyant silindi:', response.data.data.message);
  } catch (error) {
    console.error('Hata:', error.response?.data?.error?.message);
  }
};

// Kullanım
deleteVariant(12345, 3);
cURL Örneği (Swagger'dan):
curl -X DELETE "https://idnsx.com/espazar/api/v1/products/12345/variants/3" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Accept: application/json"
Response Örneği:
{
  "success": true,
  "timestamp": "2025-10-08 13:42:15",
  "request_id": "req_68e64be7123456.78901234",
  "data": {
    "message": "Product variant deleted successfully"
  }
}

📝 Önemli Notlar

Otomatik Stok Kodu

Her varyant için benzersiz stock_code otomatik oluşturulur

Varyant ID'leri

attributes parametresindeki ID'ler sistemdeki varyant ve alt_varyant tablolarından alınmalı

Transaction Güvenliği

Tüm işlemler transaction ile korunur - hata durumunda rollback yapılır

Sahiplik Kontrolü

Sadece kendi ürünlerinin varyantlarını yönetebilirsin

Özellik Güncelleme

attributes güncellenemez! Değiştirmek için önce sil, sonra yeni oluştur

Fiyat ve Stok

Her varyant için bağımsız price, market_price ve stock_quantity tanımlanabilir

Ürün Stok Yönetimi

📦 Stok Yönetimi Nedir?

Ürünlerinizin ve varyantlarının stok miktarlarını takip edin, güncelleyin ve stok uyarıları alın.

🔄 Anlık Güncelleme:

Stokları anında güncelleyin (set, add, subtract)

📊 Varyant Bazlı:

Her varyantın ayrı stok takibi

⚠️ Otomatik Uyarılar:

Düşük stok ve tükenen ürünler için bildirim

1 Stok Bilgilerini Getir

GET /api/v1/products/{product_id}/stock
Authorization: Bearer your_token

⚡ Body Gerekmez - Tüm varyantların stok bilgilerini döner

📊 Dönen Bilgiler:

📦 Ana Ürün Bilgileri:

• Toplam stok miktarı

• Varyant sayısı

• Ürün adı, SKU, fiyat

🔢 Varyant Stokları:

• Her varyantın stok miktarı

• Stok kodu, fiyat bilgileri

• Oluşturulma/güncelleme tarihleri

⚠️ Stok Uyarıları:

• Tükenen varyantlar (stock = 0)

• Düşük stoklu varyantlar (≤10)

• Stoktaki varyantlar (>10)

📈 İstatistikler:

• Toplam varyant sayısı

• Stoktaki varyant sayısı

• Tükenen/düşük stok sayısı

JavaScript Örneği:
// Ürün stok bilgilerini getir
const getProductStock = async (productId) => {
  try {
    const response = await axios.get(
      `https://idnsx.com/espazar/api/v1/products/${productId}/stock`,
      {
        headers: { 'Authorization': `Bearer ${accessToken}` }
      }
    );

    const stock = response.data.data;

    console.log('Toplam Stok:', stock.product.total_stock);
    console.log('Varyant Sayısı:', stock.product.variant_count);

    // Varyant stokları
    stock.variants.forEach(variant => {
      console.log(`${variant.variant_name}: ${variant.stock_quantity} adet`);
    });

    // Uyarılar
    console.log('Tükenen:', stock.alerts.out_of_stock.length);
    console.log('Düşük Stok:', stock.alerts.low_stock.length);
  } catch (error) {
    console.error('Hata:', error.response?.data?.error?.message);
  }
};

// Kullanım
getProductStock(12345);
cURL Örneği (Swagger'dan):
curl -X GET "https://idnsx.com/espazar/api/v1/products/12345/stock" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Accept: application/json"
Response Örneği:
{
  "success": true,
  "timestamp": "2025-10-08 14:10:25",
  "request_id": "req_68e65321123456.78901234",
  "data": {
    "product": {
      "product_id": 12345,
      "product_name": "Samsung Galaxy S24",
      "sku": "PROD-12345",
      "barcode": "8690123456789",
      "price": 25999.99,
      "market_price": 27999.99,
      "total_stock": 130,
      "variant_count": 3
    },
    "variants": [
      {
        "stock_code": "SKU-12345-abc123",
        "variant_name": "Samsung Galaxy S24 - Mavi, 128GB",
        "price": 25999.99,
        "market_price": 27999.99,
        "stock_quantity": 50,
        "attributes": {
          "Renk": "Mavi",
          "Kapasite": "128GB"
        },
        "created_at": 1727784000,
        "updated_at": 1728385800
      },
      {
        "stock_code": "SKU-12345-def456",
        "variant_name": "Samsung Galaxy S24 - Siyah, 256GB",
        "price": 29999.99,
        "market_price": 31999.99,
        "stock_quantity": 5,
        "attributes": {
          "Renk": "Siyah",
          "Kapasite": "256GB"
        },
        "created_at": 1727784300,
        "updated_at": 1728381600
      },
      {
        "stock_code": "SKU-12345-ghi789",
        "variant_name": "Samsung Galaxy S24 - Beyaz, 512GB",
        "price": 34999.99,
        "market_price": 36999.99,
        "stock_quantity": 0,
        "attributes": {
          "Renk": "Beyaz",
          "Kapasite": "512GB"
        },
        "created_at": 1727784600,
        "updated_at": 1728312300
      }
    ],
    "alerts": {
      "out_of_stock": [
        {
          "stock_code": "SKU-12345-ghi789",
          "variant_name": "Samsung Galaxy S24 - Beyaz, 512GB",
          "stock_quantity": 0
        }
      ],
      "low_stock": [
        {
          "stock_code": "SKU-12345-def456",
          "variant_name": "Samsung Galaxy S24 - Siyah, 256GB",
          "stock_quantity": 5
        }
      ]
    },
    "stats": {
      "total_variants": 3,
      "in_stock_variants": 1,
      "out_of_stock_variants": 1,
      "low_stock_variants": 1
    }
  }
}

2 Stok Güncelle

POST /api/v1/products/{product_id}/stock
Authorization: Bearer your_token

💡 Ana stok veya varyant stokları tek istekte güncellenebilir

📋 Kullanılabilir Parametreler:
Parametre Tip Zorunlu Açıklama
main_stock integer Hayır Ana ürün stoğu (varyantı olmayan ürünler için)
variants array Hayır Varyant stok güncellemeleri (stock_code + stock_quantity)
bulk_update array Hayır Toplu güncelleme (operation: set/add/subtract)
🔄 operation Tipleri:

📌 set (varsayılan):

Stoğu direkt belirtilen değere ayarla

// Stok = 50 yap
"operation": "set"
"stock_quantity": 50

add:

Mevcut stoğa ekle (stok girişi)

// Stok += 20
"operation": "add"
"stock_quantity": 20

subtract:

Mevcut stoktan çıkar (satış)

// Stok -= 10
"operation": "subtract"
"stock_quantity": 10

⚠️ Stok negatif olamaz! Subtract işleminde stok 0'dan küçükse 0 olarak ayarlanır.

Örnek 1: Ana Stok Güncelleme (Varyantı olmayan ürün):
{
  "main_stock": 100
}
Örnek 2: Varyant Stok Güncelleme (Fiyatla birlikte):
{
  "variants": [
    {
      "stock_code": "SKU-12345-abc123",
      "stock_quantity": 50,
      "price": 25999.99,
      "market_price": 27999.99
    },
    {
      "stock_code": "SKU-12345-def456",
      "stock_quantity": 30
    }
  ]
}
Örnek 3: Toplu Güncelleme (Operation ile):
{
  "bulk_update": [
    {
      "stock_code": "SKU-12345-abc123",
      "stock_quantity": 20,
      "operation": "add"         // 20 adet ekle
    },
    {
      "stock_code": "SKU-12345-def456",
      "stock_quantity": 5,
      "operation": "subtract"    // 5 adet çıkar
    },
    {
      "stock_code": "SKU-12345-ghi789",
      "stock_quantity": 75,
      "operation": "set"         // 75'e ayarla
    }
  ]
}
JavaScript Örneği:
// Stok güncelleme - Varyant bazlı
const updateStock = async (productId) => {
  try {
    const response = await axios.post(
      `https://idnsx.com/espazar/api/v1/products/${productId}/stock`,
      {
        variants: [
          {
            stock_code: "SKU-12345-abc123",
            stock_quantity: 50,
            price: 25999.99
          }
        ],
        bulk_update: [
          {
            stock_code: "SKU-12345-def456",
            stock_quantity: 10,
            operation: "add"  // Stoğa 10 ekle
          }
        ]
      },
      {
        headers: {
          'Authorization': `Bearer ${accessToken}`,
          'Content-Type': 'application/json'
        }
      }
    );

    console.log('Stok güncellendi:', response.data.data);
  } catch (error) {
    console.error('Hata:', error.response?.data?.error?.message);
  }
};

// Kullanım
updateStock(12345);
cURL Örneği (Swagger'dan):
curl -X POST "https://idnsx.com/espazar/api/v1/products/12345/stock" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "variants": [
      {
        "stock_code": "SKU-12345-abc123",
        "stock_quantity": 50
      }
    ]
  }'
Response Örneği:
{
  "success": true,
  "timestamp": "2025-10-08 14:25:10",
  "request_id": "req_68e65656123456.78901234",
  "data": {
    "message": "Stock updated successfully",
    "product_id": 12345,
    "updated_at": 1728391510
  }
}

3 Stok Uyarıları

GET /api/v1/products/stock-alerts
Authorization: Bearer your_token

⚠️ Tüm ürünlerinizden düşük stok ve tükenen varyantları getirir

🔍 Query Parameters:
Parametre Tip Varsayılan Açıklama
type string all Uyarı tipi: all, low, out
threshold integer 10 Düşük stok eşik değeri (≤ threshold = düşük stok)
📊 type Parametresi:

🔵 all (varsayılan):

Tüm uyarılar (düşük stok + tükenenler)

⚠️ low:

Sadece düşük stok (0 < stok ≤ threshold)

🔴 out:

Sadece tükenler (stok = 0)

JavaScript Örneği:
// Tüm stok uyarılarını getir
const getStockAlerts = async (type = 'all', threshold = 10) => {
  try {
    const response = await axios.get(
      `https://idnsx.com/espazar/api/v1/products/stock-alerts`,
      {
        params: { type, threshold },
        headers: { 'Authorization': `Bearer ${accessToken}` }
      }
    );

    const alerts = response.data.data.alerts;

    console.log(`Toplam ${alerts.length} uyarı var`);

    alerts.forEach(alert => {
      console.log(`⚠️ ${alert.product_name}`);
      console.log(`   Varyant: ${alert.variant_name}`);
      console.log(`   Stok: ${alert.stock_quantity}`);
      console.log(`   Durum: ${alert.alert_type}`);
    });
  } catch (error) {
    console.error('Hata:', error.response?.data?.error?.message);
  }
};

// Kullanım örnekleri
getStockAlerts('all', 10);      // Tüm uyarılar (≤10)
getStockAlerts('low', 5);       // Sadece düşük stok (0 < stok ≤5)
getStockAlerts('out');          // Sadece tükenler (stok = 0)
cURL Örnekleri (Swagger'dan):

1. Tüm uyarılar:

curl -X GET "https://idnsx.com/espazar/api/v1/products/stock-alerts?type=all&threshold=10" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

2. Sadece tükenler:

curl -X GET "https://idnsx.com/espazar/api/v1/products/stock-alerts?type=out" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Response Örneği:
{
  "success": true,
  "timestamp": "2025-10-08 14:35:45",
  "request_id": "req_68e658d1123456.78901234",
  "data": {
    "alerts": [
      {
        "product_id": 12345,
        "product_name": "Samsung Galaxy S24",
        "sku": "PROD-12345",
        "stock_code": "SKU-12345-ghi789",
        "variant_name": "Samsung Galaxy S24 - Beyaz, 512GB",
        "price": 34999.99,
        "stock_quantity": 0,
        "last_updated": "2025-10-07 16:45:00",
        "alert_type": "out_of_stock"
      },
      {
        "product_id": 12345,
        "product_name": "Samsung Galaxy S24",
        "sku": "PROD-12345",
        "stock_code": "SKU-12345-def456",
        "variant_name": "Samsung Galaxy S24 - Siyah, 256GB",
        "price": 29999.99,
        "stock_quantity": 5,
        "last_updated": "2025-10-08 11:00:00",
        "alert_type": "low_stock"
      }
    ],
    "stats": {
      "total_alerts": 2,
      "out_of_stock_count": 1,
      "low_stock_count": 1
    },
    "filters": {
      "type": "all",
      "threshold": 10
    }
  }
}

📝 Önemli Notlar

Anlık Güncelleme

Stok değişiklikleri anında veritabanına yansır ve hemen sorgulanabilir

Transaction Güvenliği

Tüm stok işlemleri transaction ile korunur - hata durumunda rollback yapılır

Negatif Stok Koruması

Stok miktarı asla negatif olamaz - 0'ın altına düşerse otomatik olarak 0'a ayarlanır

Otomatik Uyarılar

Sistem düşük stok (≤ threshold) ve tükenen (= 0) varyantları otomatik algılar

Varyant Bazlı Takip

Her varyant için ayrı stok tutulur - stock_code ile benzersiz tanımlama

Toplu Güncelleme

bulk_update ile çoklu varyantları tek request'te güncelleyebilirsin

İşlem Tipleri

set (direkt ayarla), add (ekle), subtract (çıkar) - 3 farklı güncelleme yöntemi

Ürün Resim Yönetimi

🖼️ Resim Yönetimi Nedir?

Ürünlerinize resim yükleyin, düzenleyin, sıralayın ve ana resim belirleyin.

📤 Dosya Yükleme:

JPEG, PNG, GIF, WebP - Maksimum 5MB

⭐ Ana Resim:

Bir resmi ana resim olarak belirle

🔢 Sıralama:

Resimlerin görünüm sırasını ayarla

1 Resimleri Listele

GET /api/v1/products/{product_id}/images
Authorization: Bearer your_token

⚡ Body Gerekmez - Ürünün tüm resimlerini getirir

📊 Dönen Bilgiler:

🖼️ Resim Detayları:

• Resim ID ve URL

• Ana resim durumu (is_main)

• Sıra numarası (sort_order)

📅 Tarih Bilgileri:

• Resim yüklenme tarihi

• Son güncelleme tarihi

• Toplam resim sayısı

JavaScript Örneği:
// Ürün resimlerini getir
const getProductImages = async (productId) => {
  try {
    const response = await axios.get(
      `https://idnsx.com/espazar/api/v1/products/${productId}/images`,
      {
        headers: { 'Authorization': `Bearer ${accessToken}` }
      }
    );

    const images = response.data.data.images;

    console.log(`Toplam ${response.data.data.total_count} resim`);

    // Ana resmi bul
    const mainImage = images.find(img => img.is_main);
    if (mainImage) {
      console.log('Ana Resim:', mainImage.image_url);
    }

    // Tüm resimleri listele
    images.forEach(img => {
      console.log(`${img.is_main ? '⭐' : '📷'} ${img.image_url} (Sıra: ${img.sort_order})`);
    });
  } catch (error) {
    console.error('Hata:', error.response?.data?.error?.message);
  }
};

// Kullanım
getProductImages(12345);
cURL Örneği (Swagger'dan):
curl -X GET "https://idnsx.com/espazar/api/v1/products/12345/images" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Accept: application/json"
Response Örneği:
{
  "success": true,
  "timestamp": "2025-10-08 15:10:30",
  "request_id": "req_68e66786123456.78901234",
  "data": {
    "images": [
      {
        "image_id": 1,
        "image_url": "product_12345_abc123.jpg",
        "is_main": true,
        "sort_order": 0,
        "created_at": 1727784000
      },
      {
        "image_id": 2,
        "image_url": "product_12345_def456.jpg",
        "is_main": false,
        "sort_order": 1,
        "created_at": 1727784300
      },
      {
        "image_id": 3,
        "image_url": "product_12345_ghi789.jpg",
        "is_main": false,
        "sort_order": 2,
        "created_at": 1727784600
      }
    ],
    "total_count": 3
  }
}

2 Resim Yükle

POST /api/v1/products/{product_id}/images
Authorization: Bearer your_token

📤 Content-Type: multipart/form-data

🔥 Dosya yükleme işlemi - Form Data kullanılmalı

📋 Form Data Parametreleri:
Parametre Tip Zorunlu Açıklama
image file Evet Resim dosyası (JPEG, PNG, GIF, WebP - Max 5MB)
is_main boolean Hayır Ana resim olarak ayarla (true/false, varsayılan: false)
sort_order integer Hayır Sıra numarası (0, 1, 2, ... - varsayılan: 0)
📏 Dosya Kuralları:

📂 Kabul Edilen Formatlar:

• JPEG / JPG

• PNG

• GIF

• WebP

⚖️ Boyut Limitleri:

Maksimum: 5 MB

Önerilen: 1-2 MB

Çözünürlük: 1200x1200px

JavaScript Örneği (FormData ile):
// Resim yükle (HTML input'tan)
const uploadImage = async (productId, fileInput) => {
  try {
    // FormData oluştur
    const formData = new FormData();
    formData.append('image', fileInput.files[0]);
    formData.append('is_main', 'false');
    formData.append('sort_order', '0');

    const response = await axios.post(
      `https://idnsx.com/espazar/api/v1/products/${productId}/images`,
      formData,
      {
        headers: {
          'Authorization': `Bearer ${accessToken}`,
          'Content-Type': 'multipart/form-data'
        }
      }
    );

    console.log('Resim yüklendi:', response.data.data);
    console.log('Resim URL:', response.data.data.image_url);
    console.log('Resim ID:', response.data.data.image_id);
  } catch (error) {
    console.error('Hata:', error.response?.data?.error?.message);
  }
};

// HTML'den kullanım
// 
const fileInput = document.getElementById('imageInput');
uploadImage(12345, fileInput);
cURL Örneği (Swagger'dan):
curl -X POST "https://idnsx.com/espazar/api/v1/products/12345/images" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -F "image=@/path/to/your/image.jpg" \
  -F "is_main=true" \
  -F "sort_order=0"
Response Örneği:
{
  "success": true,
  "timestamp": "2025-10-08 15:20:45",
  "request_id": "req_68e669ed123456.78901234",
  "data": {
    "image_id": 4,
    "image_url": "product_12345_xyz123.jpg",
    "is_main": true,
    "sort_order": 0,
    "message": "Image uploaded successfully"
  }
}

3 Resim Güncelle

PUT /api/v1/products/{product_id}/images/{image_id}
Authorization: Bearer your_token

💡 Ana resim durumu ve sıra numarasını güncelleyebilirsin

⚠️ Resim dosyası değiştirilemez - Silip yeni yüklemen gerekir

🔄 Güncellenebilir Alanlar:

is_main

Resmi ana resim yap (true) veya ana resim olmaktan çıkar (false)

🔢 sort_order

Resmin sıra numarasını değiştir (0, 1, 2, ...)

Request Body Örneği:
{
  "is_main": true,
  "sort_order": 0
}
JavaScript Örneği:
// Resim güncelle (ana resim ve sıra)
const updateImage = async (productId, imageId) => {
  try {
    const response = await axios.put(
      `https://idnsx.com/espazar/api/v1/products/${productId}/images/${imageId}`,
      {
        is_main: true,     // Ana resim yap
        sort_order: 0      // İlk sıraya al
      },
      {
        headers: {
          'Authorization': `Bearer ${accessToken}`,
          'Content-Type': 'application/json'
        }
      }
    );

    console.log('Resim güncellendi:', response.data.data);
  } catch (error) {
    console.error('Hata:', error.response?.data?.error?.message);
  }
};

// Kullanım
updateImage(12345, 4);
cURL Örneği (Swagger'dan):
curl -X PUT "https://idnsx.com/espazar/api/v1/products/12345/images/4" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "is_main": true,
    "sort_order": 0
  }'
Response Örneği:
{
  "success": true,
  "timestamp": "2025-10-08 15:30:10",
  "request_id": "req_68e66c52123456.78901234",
  "data": {
    "image_id": 4,
    "message": "Image updated successfully"
  }
}

4 Resim Sil

DELETE /api/v1/products/{product_id}/images/{image_id}
Authorization: Bearer your_token

⚡ Body Gerekmez - product_id ve image_id yeterli

🔥 Resim veritabanından ve sunucudan kalıcı olarak silinir!

🗑️ Silme İşlemi:

Veritabanı Kaydı

urun_resim tablosundan silinir

Fiziksel Dosya

Sunucudaki resim dosyası silinir

Transaction ile korunur: Hata durumunda tüm işlem geri alınır

JavaScript Örneği:
// Resim sil (onay ile)
const deleteImage = async (productId, imageId) => {
  const confirmed = confirm('Bu resmi silmek istediğinize emin misiniz?');

  if (!confirmed) {
    console.log('Silme işlemi iptal edildi');
    return;
  }

  try {
    const response = await axios.delete(
      `https://idnsx.com/espazar/api/v1/products/${productId}/images/${imageId}`,
      {
        headers: { 'Authorization': `Bearer ${accessToken}` }
      }
    );

    console.log('Resim silindi:', response.data.data.message);
  } catch (error) {
    console.error('Hata:', error.response?.data?.error?.message);
  }
};

// Kullanım
deleteImage(12345, 4);
cURL Örneği (Swagger'dan):
curl -X DELETE "https://idnsx.com/espazar/api/v1/products/12345/images/4" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Accept: application/json"
Response Örneği:
{
  "success": true,
  "timestamp": "2025-10-08 15:40:25",
  "request_id": "req_68e66ed9123456.78901234",
  "data": {
    "image_id": 4,
    "message": "Image deleted successfully"
  }
}

5 Ana Resim Belirle (Kısa Yol)

POST /api/v1/products/{product_id}/images/{image_id}/set-main
Authorization: Bearer your_token

⚡ Body Gerekmez - Direkt ana resim yapar

💡 PUT ile güncelleme yerine bu kısa yolu kullanabilirsin

🔄 Nasıl Çalışır?
  1. 1. Ürünün tüm resimlerinin is_main değeri false yapılır
  2. 2. Belirtilen resmin is_main değeri true yapılır
  3. 3. Transaction ile korunur - hata durumunda rollback
JavaScript Örneği:
// Ana resim belirle (kısa yol)
const setMainImage = async (productId, imageId) => {
  try {
    const response = await axios.post(
      `https://idnsx.com/espazar/api/v1/products/${productId}/images/${imageId}/set-main`,
      {},  // Body gerekmez
      {
        headers: { 'Authorization': `Bearer ${accessToken}` }
      }
    );

    console.log('Ana resim belirlendi:', response.data.data.message);
  } catch (error) {
    console.error('Hata:', error.response?.data?.error?.message);
  }
};

// Kullanım
setMainImage(12345, 2);
cURL Örneği (Swagger'dan):
curl -X POST "https://idnsx.com/espazar/api/v1/products/12345/images/2/set-main" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Accept: application/json"
Response Örneği:
{
  "success": true,
  "timestamp": "2025-10-08 15:50:40",
  "request_id": "req_68e67140123456.78901234",
  "data": {
    "image_id": 2,
    "message": "Main image set successfully"
  }
}

📝 Önemli Notlar

Desteklenen Formatlar

JPEG, PNG, GIF, WebP formatları desteklenir - Maksimum dosya boyutu 5MB

Form Data Kullanımı

Resim yüklerken multipart/form-data Content-Type kullanılmalıdır

Tek Ana Resim

Bir resim ana resim yapıldığında, diğer tüm resimlerin ana resim durumu otomatik kaldırılır

Sıralama

sort_order ile resimlerin görünüm sırası belirlenir (0 = ilk, 1 = ikinci, ...)

Transaction Güvenliği

Tüm işlemler transaction ile korunur - hata durumunda rollback yapılır

Fiziksel Dosya Silme

Resim silindiğinde hem veritabanından hem de sunucudan fiziksel olarak silinir

Dosya Değiştirilemez

Mevcut resim dosyası değiştirilemez - Değiştirmek için önce sil, sonra yeni yükle

Otomatik Dosya Adı

Yüklenen dosyalara otomatik benzersiz ad verilir (örn: product_12345_xyz123.jpg)

Toplu İşlemler

⚡ Toplu İşlemler Nedir?

Çok sayıda ürünü tek bir istekte güncelleyin, silin veya içe aktarın. Büyük veri setleriyle çalışırken zaman kazanın.

📊 Excel/CSV:

Dosya ile toplu ürün içe aktar

✏️ Toplu Güncelleme:

Çoklu ürünleri aynı anda güncelle

🗑️ Toplu Silme:

Birden fazla ürünü bir anda sil

📦 Toplu Stok:

Stokları toplu olarak güncelle

1 JSON ile Toplu Ürün Oluşturma (Upsert)

POST /api/v1/products/bulk
Authorization: Bearer your_token

📤 Content-Type: application/json

📊 JSON body ile toplu ürün oluşturma/güncelleme (Maksimum 100 ürün)

🔄 Upsert Mantığı (Insert or Update):

Bu endpoint SKU bazlı çalışır:

  • SKU sistemde varsa: Mevcut ürün güncellenir
  • SKU sistemde yoksa: Yeni ürün oluşturulur
📋 Alan Listesi:
Alan Tip Zorunlu Açıklama
sku string ✅ Evet Benzersiz ürün kodu (Upsert anahtarı)
title string ✅ Evet Ürün adı
price number ✅ Evet Satış fiyatı
category_id integer ⚠️ Yeni ürün Kategori ID (yeni ürünler için zorunlu)
description string Hayır Ürün açıklaması (HTML destekler)
market_price number Hayır Piyasa fiyatı
barcode string Hayır Barkod numarası (maks. 20 karakter)
stock_quantity integer Hayır Stok miktarı
estimated_shipping_days integer Hayır Tahmini kargoya teslim süresi (gün)
shipping_type integer Hayır Kargo tipi: 1=Alıcı ödemeli, 2=Satıcı ödemeli
shipping_cost number Hayır Kargo ücreti (shipping_type=1 için)
shipping_company_id integer Hayır Kargo firması ID
images array Hayır Resim dizisi: [{url, is_main}]
variants array Hayır Varyant dizisi: [{sku, name}]
filters array Hayır Filtre dizisi (marka, renk vb.): [{filter_id, option_id}]
📋 Request Body:
{
  "products": [
    {
      "sku": "PROD-001",              // Zorunlu - Benzersiz ürün kodu
      "title": "iPhone 15 Pro",        // Zorunlu - Ürün adı
      "description": "Apple...",       // Opsiyonel - Açıklama
      "price": 25999.99,               // Zorunlu - Satış fiyatı
      "market_price": 27999.99,        // Opsiyonel - Piyasa fiyatı
      "category_id": 137,              // Yeni ürünler için zorunlu
      "barcode": "8690000000001",      // Opsiyonel - Barkod
      "stock_quantity": 50,            // Opsiyonel - Stok miktarı
      
      // Kargo Bilgileri
      "estimated_shipping_days": 3,    // Opsiyonel - Kargoya teslim süresi (gün)
      "shipping_type": 2,              // Opsiyonel - 1: Alıcı ödemeli, 2: Satıcı ödemeli
      "shipping_cost": 49.99,          // Opsiyonel - Kargo ücreti (shipping_type=1 için)
      "shipping_company_id": 1,        // Opsiyonel - Kargo firması ID
      
      // Resimler
      "images": [
        {"url": "https://...", "is_main": true},
        {"url": "https://..."}
      ],
      
      // Varyantlar
      "variants": [
        {"sku": "PROD-001-BLK", "name": "Siyah"}
      ],
      
      // Filtreler (Marka, Renk, vb.)
      "filters": [
        {"filter_id": 402, "option_id": 3321}  // Örn: Marka filtresi
      ]
    }
  ]
}
JavaScript Örneği:
// JSON ile toplu ürün oluşturma (Upsert)
const bulkCreate = async (products) => {
  try {
    const response = await axios.post(
      'https://sandbox.esnafpazar.com/api/v1/products/bulk',
      { products },
      {
        headers: {
          'Authorization': `Bearer ${accessToken}`,
          'Content-Type': 'application/json'
        }
      }
    );

    const results = response.data.data.results;

    console.log(`Toplam: ${results.total}`);
    console.log(`Oluşturulan: ${results.created}`);
    console.log(`Güncellenen: ${results.updated}`);
    console.log(`Hatalı: ${results.errors}`);

    return results;
  } catch (error) {
    console.error('Hata:', error.response?.data?.error?.message);
  }
};

// Kullanım örneği
bulkCreate([
  { sku: 'PROD-001', title: 'Ürün 1', price: 100, category_id: 137 },
  { sku: 'PROD-002', title: 'Ürün 2', price: 200, category_id: 137 }
]);

2 Excel/CSV İle Toplu İçe Aktarma

POST /api/v1/products/bulk-import
Authorization: Bearer your_token

📤 Content-Type: multipart/form-data

📊 Excel veya CSV dosyası ile toplu ürün içe aktarma

🔄 Upsert Mantığı (Insert or Update):

Bu endpoint SKU bazlı çalışır:

  • SKU sistemde varsa: Mevcut ürün güncellenir
  • SKU sistemde yoksa: Yeni ürün oluşturulur
📋 Excel/CSV Formatı:
Sütun Alan Adı Zorunlu Açıklama Örnek
A sku ✅ Evet Benzersiz ürün kodu (Upsert anahtarı) PROD-001
B title ✅ Evet Ürün adı iPhone 15 Pro
C description Hayır Ürün açıklaması Detaylı açıklama...
D price ✅ Evet Satış fiyatı 25999.99
E market_price Hayır Piyasa fiyatı 27999.99
F stock Hayır Stok miktarı 50
G category_id ⚠️ Yeni ürün Kategori ID (yeni ürünler için zorunlu) 137
H image_urls Hayır Virgülle ayrılmış resim URL'leri (ilk resim kapak) https://...,https://...
📏 Dosya Kuralları:

📂 Format:

• Excel (.xlsx, .xls)

• CSV (.csv)

📊 Boyut:

Maksimum: 10 MB

Önerilen: ~1000 satır

✅ İlk Satır:

İlk satır başlık satırıdır

(A, B, C... sütun adları)

JavaScript Örneği (FormData ile):
// Excel dosyası ile toplu içe aktarma (Upsert)
const bulkImport = async (fileInput) => {
  try {
    const formData = new FormData();
    formData.append('file', fileInput.files[0]);

    const response = await axios.post(
      'https://sandbox.esnafpazar.com/api/v1/products/bulk-import',
      formData,
      {
        headers: {
          'Authorization': `Bearer ${accessToken}`,
          'Content-Type': 'multipart/form-data'
        }
      }
    );

    const results = response.data.data.results;

    console.log(`Toplam: ${results.total}`);
    console.log(`Oluşturulan: ${results.created}`);
    console.log(`Güncellenen: ${results.updated}`);
    console.log(`Hatalı: ${results.errors}`);

    // Detayları göster
    results.details.forEach(detail => {
      if (detail.status === 'success') {
        console.log(`✅ Satır ${detail.row} [${detail.action}]: ${detail.sku}`);
      } else {
        console.log(`❌ Satır ${detail.row}: ${detail.message}`);
      }
    });
  } catch (error) {
    console.error('Hata:', error.response?.data?.error?.message);
  }
};

// HTML'den kullanım
// 
const fileInput = document.getElementById('excelInput');
bulkImport(fileInput);
Response Örneği:
{
  "success": true,
  "timestamp": "2025-10-08 16:10:30",
  "request_id": "req_68e67ab6123456.78901234",
  "data": {
    "message": "Bulk import completed",
    "results": {
      "total": 5,
      "success": 4,
      "errors": 1,
      "details": [
        {
          "row": 2,
          "product_id": 12345,
          "sku": "PROD-001",
          "status": "updated",
          "message": "Product updated successfully"
        },
        {
          "row": 3,
          "product_id": null,
          "sku": "PROD-002",
          "status": "created",
          "message": "Product created successfully"
        },
        {
          "row": 4,
          "product_id": null,
          "sku": "PROD-003",
          "status": "error",
          "message": "Invalid category ID"
        }
      ]
    }
  }
}

2 Toplu Ürün Güncelleme (JSON)

POST /api/v1/products/bulk-update
Authorization: Bearer your_token

💡 Birden fazla ürünü aynı anda güncelleyin

🎯 update_fields ile hangi alanların güncelleneceğini belirtin

🔄 Güncellenebilir Alanlar:
product_name
price
market_price
discount_price
description
category_id
brand_id
status
Request Body Örneği:
{
  "update_fields": ["product_name", "price", "market_price"],
  "products": [
    {
      "product_id": 12345,
      "product_name": "Güncellenmiş Ürün Adı",
      "price": 299.99,
      "market_price": 399.99
    },
    {
      "product_id": 12346,
      "product_name": "Başka Ürün",
      "price": 199.99,
      "market_price": 249.99
    },
    {
      "product_id": 12347,
      "price": 599.99
    }
  ]
}
JavaScript Örneği:
// Toplu ürün güncelleme
const bulkUpdate = async (products, fieldsToUpdate) => {
  try {
    const response = await axios.post(
      'https://idnsx.com/espazar/api/v1/products/bulk-update',
      {
        update_fields: fieldsToUpdate,
        products: products
      },
      {
        headers: {
          'Authorization': `Bearer ${accessToken}`,
          'Content-Type': 'application/json'
        }
      }
    );

    const results = response.data.data.results;

    console.log(`Toplam: ${results.total}`);
    console.log(`Başarılı: ${results.success}`);
    console.log(`Hatalı: ${results.errors}`);
  } catch (error) {
    console.error('Hata:', error.response?.data?.error?.message);
  }
};

// Kullanım
bulkUpdate([
  { product_id: 12345, price: 299.99, market_price: 399.99 },
  { product_id: 12346, price: 199.99 }
], ['price', 'market_price']);
Response Örneği:
{
  "success": true,
  "timestamp": "2025-10-08 16:20:15",
  "request_id": "req_68e67d0f123456.78901234",
  "data": {
    "message": "Bulk update completed",
    "results": {
      "total": 3,
      "success": 3,
      "errors": 0,
      "details": [
        {
          "index": 0,
          "product_id": 12345,
          "status": "success",
          "message": "Product updated successfully"
        },
        {
          "index": 1,
          "product_id": 12346,
          "status": "success",
          "message": "Product updated successfully"
        }
      ]
    }
  }
}

3 Toplu Ürün Silme

POST /api/v1/products/bulk-delete
Authorization: Bearer your_token

🗑️ Birden fazla ürünü aynı anda silin

⚠️ confirm: true parametresi zorunludur!

🗑️ Silme İşlemi (Hard Delete):

Veritabanı

Ürün ve tüm ilişkili veriler silinir

Fiziksel Dosyalar

Resim dosyaları sunucudan silinir

Request Body Örneği:
{
  "product_ids": [12345, 12346, 12347, 12348, 12349],
  "confirm": true
}
JavaScript Örneği:
// Toplu ürün silme (onay ile)
const bulkDelete = async (productIds) => {
  const confirmed = confirm(
    `${productIds.length} ürünü silmek istediğinize emin misiniz? Bu işlem geri alınamaz!`
  );

  if (!confirmed) {
    console.log('Silme işlemi iptal edildi');
    return;
  }

  try {
    const response = await axios.post(
      'https://idnsx.com/espazar/api/v1/products/bulk-delete',
      {
        product_ids: productIds,
        confirm: true
      },
      {
        headers: {
          'Authorization': `Bearer ${accessToken}`,
          'Content-Type': 'application/json'
        }
      }
    );

    const results = response.data.data.results;

    console.log(`Toplam: ${results.total}`);
    console.log(`Başarılı: ${results.success}`);
    console.log(`Hatalı: ${results.errors}`);
  } catch (error) {
    console.error('Hata:', error.response?.data?.error?.message);
  }
};

// Kullanım
bulkDelete([12345, 12346, 12347]);
Response Örneği:
{
  "success": true,
  "timestamp": "2025-10-08 16:30:45",
  "request_id": "req_68e67f75123456.78901234",
  "data": {
    "message": "Bulk delete completed",
    "results": {
      "total": 3,
      "success": 3,
      "errors": 0,
      "details": [
        {
          "index": 0,
          "product_id": 12345,
          "status": "success",
          "message": "Product deleted successfully"
        },
        {
          "index": 1,
          "product_id": 12346,
          "status": "success",
          "message": "Product deleted successfully"
        }
      ]
    }
  }
}

4 Toplu Stok Güncelleme

POST /api/v1/products/bulk-stock-update
Authorization: Bearer your_token

📦 Birden fazla varyantın stoğunu aynı anda güncelleyin

🔄 operation: set, add, subtract

🔄 operation Tipleri:

📌 set (varsayılan):

Stoğu direkt belirtilen değere ayarla

add:

Mevcut stoğa ekle (stok girişi)

subtract:

Mevcut stoktan çıkar (satış)

Request Body Örneği:
{
  "operation": "set",
  "stock_updates": [
    {
      "product_id": 12345,
      "stock_code": "SKU-12345-abc123",
      "quantity": 100
    },
    {
      "product_id": 12345,
      "stock_code": "SKU-12345-def456",
      "quantity": 50
    },
    {
      "product_id": 12346,
      "stock_code": "SKU-12346-ghi789",
      "quantity": 25
    }
  ]
}
JavaScript Örneği:
// Toplu stok güncelleme
const bulkStockUpdate = async (stockUpdates, operation = 'set') => {
  try {
    const response = await axios.post(
      'https://idnsx.com/espazar/api/v1/products/bulk-stock-update',
      {
        operation: operation,
        stock_updates: stockUpdates
      },
      {
        headers: {
          'Authorization': `Bearer ${accessToken}`,
          'Content-Type': 'application/json'
        }
      }
    );

    const results = response.data.data.results;

    console.log(`İşlem: ${response.data.data.operation}`);
    console.log(`Toplam: ${results.total}`);
    console.log(`Başarılı: ${results.success}`);
    console.log(`Hatalı: ${results.errors}`);

    // Detayları göster
    results.details.forEach(detail => {
      if (detail.status === 'success') {
        console.log(`✅ ${detail.stock_code}: ${detail.old_quantity} → ${detail.new_quantity}`);
      }
    });
  } catch (error) {
    console.error('Hata:', error.response?.data?.error?.message);
  }
};

// Kullanım örnekleri
// 1. Stokları direkt ayarla
bulkStockUpdate([
  { product_id: 12345, stock_code: 'SKU-123', quantity: 100 },
  { product_id: 12346, stock_code: 'SKU-456', quantity: 50 }
], 'set');

// 2. Stoklara ekle
bulkStockUpdate([
  { product_id: 12345, stock_code: 'SKU-123', quantity: 20 }
], 'add');

// 3. Stoklardan çıkar
bulkStockUpdate([
  { product_id: 12345, stock_code: 'SKU-123', quantity: 10 }
], 'subtract');
Response Örneği:
{
  "success": true,
  "timestamp": "2025-10-08 16:40:20",
  "request_id": "req_68e681d4123456.78901234",
  "data": {
    "message": "Bulk stock update completed",
    "operation": "set",
    "results": {
      "total": 3,
      "success": 3,
      "errors": 0,
      "details": [
        {
          "index": 0,
          "product_id": 12345,
          "stock_code": "SKU-12345-abc123",
          "old_quantity": 75,
          "new_quantity": 100,
          "operation": "set",
          "status": "success",
          "message": "Stock updated successfully"
        },
        {
          "index": 1,
          "product_id": 12345,
          "stock_code": "SKU-12345-def456",
          "old_quantity": 30,
          "new_quantity": 50,
          "operation": "set",
          "status": "success",
          "message": "Stock updated successfully"
        }
      ]
    }
  }
}

📝 Önemli Notlar

Performans

Her işlem ayrı transaction ile korunur - hata durumunda sadece o işlem geri alınır

Sonuç Detayları

Her işlem için başarı/hata durumu ayrı ayrı raporlanır - details dizisinde

Excel Formatı

İlk satır başlık satırıdır ve atlanır - Veri 2. satırdan başlar

Sahiplik Kontrolü

Sadece size ait ürünler güncellenebilir/silinebilir - Her işlem öncesi kontrol yapılır

Toplu Silme Onayı

confirm: true parametresi zorunludur - Kazara silmeleri önler

Stok İşlemleri

product_id + stock_code kombinasyonu benzersiz olmalıdır

Sipariş Yönetimi

Sipariş Listeleme

📋 Sipariş Listeleme Nedir?

Satıcınıza ait tüm siparişleri listeleyebilir, filtreleyebilir ve sayfalama yapabilirsiniz. Bu endpoint, sipariş yönetim sisteminiz için temel veri kaynağıdır.

📊 Filtreleme

Durum, tarih ve sayfalama filtreleri

🔄 Gerçek Zamanlı

Anlık sipariş bilgileri

📦 Detaylı

Müşteri, ürün ve ödeme bilgileri

GET /api/v1/orders
Authorization: Bearer your_token

Query Parametreleri

Parametre Tip Zorunlu Açıklama
page integer Hayır Sayfa numarası (varsayılan: 1)
per_page integer Hayır Sayfa başına kayıt (varsayılan: 50, max: 100)
status string Hayır Sipariş durumu (pending, approved, shipped, vb.)
created_after timestamp Hayır Bu tarihten sonraki siparişler (UNIX timestamp)
created_before timestamp Hayır Bu tarihten önceki siparişler (UNIX timestamp)
updated_after timestamp Hayır Bu tarihten sonra güncellenen siparişler (UNIX timestamp)

JavaScript Örneği

const axios = require('axios');

const listOrders = async () => {
  try {
    const response = await axios.get('https://idnsx.com/espazar/api/v1/orders', {
      headers: {
        'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
      },
      params: {
        page: 1,
        per_page: 50,
        status: 'pending',
        created_after: Math.floor(Date.now() / 1000) - (7 * 24 * 60 * 60) // Son 7 gün
      }
    });

    console.log('Toplam Sipariş:', response.data.data.meta.total_items);
    console.log('Siparişler:', response.data.data.orders);
  } catch (error) {
    console.error('Hata:', error.response.data);
  }
};

listOrders();

cURL Örneği

curl -X 'GET' \
  'https://idnsx.com/espazar/api/v1/orders?page=1&per_page=50&status=pending' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
  -H 'Accept: application/json'

Response Örneği

{
  "success": true,
  "timestamp": "2025-10-08 14:30:45",
  "request_id": "req_68e7a1b5c4d3e2f1",
  "data": {
    "orders": [
      {
        "order_id": "ORD-2025-68e5001492c13",
        "order_number": "ORD-2025-68e5001492c13",
        "status": "pending",
        "customer": {
          "name": "Ahmet Yılmaz",
          "email": "ahmet@example.com",
          "phone": "5551234567",
          "tc_no": "12345678901",
          "tax_office": null,
          "tax_number": null,
          "company_name": null
        },
        "shipping_address": {
          "address": "Atatürk Mah. No:123",
          "district": "Kadıköy",
          "city": "İstanbul",
          "country": "TR"
        },
        "totals": {
          "subtotal": 599.98,
          "shipping": 29.90,
          "discount": 50.00,
          "grand_total": 579.88,
          "currency": "TRY"
        },
        "item_count": 2,
        "created_at": "1728307200",
        "updated_at": "1728307200"
      }
    ],
    "meta": {
      "current_page": 1,
      "total_pages": 5,
      "per_page": 50,
      "total_items": 243,
      "has_next": true,
      "has_prev": false
    }
  }
}

⚠️ Önemli Notlar

  • Sayfalama: Maksimum 100 kayıt/sayfa döndürülür. Daha fazla kayıt için sayfalama kullanın.
  • Tarih Filtreleri: UNIX timestamp formatında gönderilmelidir (saniye cinsinden).
  • Durum Filtreleme: Sadece tek bir durum filtresi kullanabilirsiniz.
  • Performans: Büyük veri setleri için tarih filtrelerini kullanarak sorgu süresini optimize edin.

Sipariş Oluşturma (Entegratörler İçin)

🛍️ Sipariş Oluşturma Nedir?

Entegratör sistemler için marketplace'e yeni sipariş oluşturma endpoint'i. Kendi platformunuzdan gelen siparişleri otomatik olarak pazaryeri sistemine aktarabilirsiniz.

🔄 Otomatik Stok

Stoklar otomatik güncellenir

✅ Doğrulama

Ürün ve stok kontrolü yapılır

📦 Transaction

Güvenli işlem yönetimi

POST /api/v1/orders
Authorization: Bearer your_token

Request Body Parametreleri

customer (object) - Zorunlu
Alan Tip Zorunlu Açıklama
name string Evet Müşteri adı soyadı
email string Evet Email adresi
phone string Hayır Telefon (max 10 karakter, son 10 hane alınır)
products (array) - Zorunlu
Alan Tip Zorunlu Açıklama
product_id integer Evet Ürün ID (satıcıya ait olmalı)
quantity integer Evet Sipariş adedi (stok kontrolü yapılır)
price float Hayır Birim fiyat (boş bırakılırsa ürün fiyatı kullanılır)
shipping_address (object) - Opsiyonel
Alan Tip Zorunlu Açıklama
address string Hayır Teslimat adresi
city string Hayır Şehir
district string Hayır İlçe
postal_code string Hayır Posta kodu
Diğer Parametreler
Alan Tip Zorunlu Açıklama
payment_method string Hayır Ödeme yöntemi (varsayılan: credit_card)
notes string Hayır Sipariş notu

Request Body Örneği

{
  "customer": {
    "name": "Ahmet Yılmaz",
    "email": "ahmet@example.com",
    "phone": "05551234567"
  },
  "products": [
    {
      "product_id": 20528,
      "quantity": 2,
      "price": 299.99
    },
    {
      "product_id": 20529,
      "quantity": 1
    }
  ],
  "shipping_address": {
    "address": "Atatürk Mah. Cumhuriyet Cad. No:123 Daire:5",
    "city": "İstanbul",
    "district": "Kadıköy",
    "postal_code": "34710"
  },
  "payment_method": "credit_card",
  "notes": "Entegratör sisteminden gelen sipariş - Hızlı teslimat"
}

JavaScript Örneği

const axios = require('axios');

const createOrder = async () => {
  try {
    const orderData = {
      customer: {
        name: "Ahmet Yılmaz",
        email: "ahmet@example.com",
        phone: "05551234567"
      },
      products: [
        {
          product_id: 20528,
          quantity: 2,
          price: 299.99
        }
      ],
      shipping_address: {
        address: "Atatürk Mah. No:123",
        city: "İstanbul",
        district: "Kadıköy",
        postal_code: "34710"
      },
      payment_method: "credit_card",
      notes: "Entegratör sisteminden gelen sipariş"
    };

    const response = await axios.post(
      'https://idnsx.com/espazar/api/v1/orders',
      orderData,
      {
        headers: {
          'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
          'Content-Type': 'application/json'
        }
      }
    );

    console.log('Sipariş Oluşturuldu:', response.data.data.order_id);
    console.log('Toplam Tutar:', response.data.data.total);
  } catch (error) {
    console.error('Hata:', error.response.data);
  }
};

createOrder();

cURL Örneği

curl -X 'POST' \
  'https://idnsx.com/espazar/api/v1/orders' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "customer": {
      "name": "Ahmet Yılmaz",
      "email": "ahmet@example.com",
      "phone": "05551234567"
    },
    "products": [
      {
        "product_id": 20528,
        "quantity": 2,
        "price": 299.99
      }
    ],
    "shipping_address": {
      "address": "Atatürk Mah. No:123",
      "city": "İstanbul",
      "district": "Kadıköy",
      "postal_code": "34710"
    },
    "payment_method": "credit_card",
    "notes": "Entegratör sisteminden gelen sipariş"
  }'

Response Örneği (Başarılı)

{
  "success": true,
  "timestamp": "2025-10-08 15:30:45",
  "request_id": "req_68e5001492c13.12345678",
  "data": {
    "order_id": "ORD-2025-68e5001492c13",
    "order_number": "ORD-2025-68e5001492c13",
    "status": "pending",
    "total": 624.98,
    "subtotal": 599.98,
    "shipping_cost": 25,
    "customer": {
      "name": "Ahmet Yılmaz",
      "email": "ahmet@example.com",
      "phone": "05551234567"
    },
    "products": [
      {
        "product_id": 20528,
        "product_name": "Debug Test",
        "quantity": 2,
        "price": 299.99,
        "line_total": 599.98
      }
    ],
    "message": "Order created successfully"
  }
}

Hata Response Örnekleri

❌ Stok Yetersiz:

{
  "success": false,
  "timestamp": "2025-10-08 15:32:10",
  "request_id": "req_68e500a7b4c3d2e1",
  "error": {
    "message": "Insufficient stock for product: Debug Test",
    "code": "Bad Request",
    "details": null
  }
}

❌ Ürün Bulunamadı:

{
  "success": false,
  "timestamp": "2025-10-08 15:33:15",
  "request_id": "req_68e500e3c5d4f3a2",
  "error": {
    "message": "Product ID 99999 not found or access denied",
    "code": "Bad Request",
    "details": null
  }
}

❌ Eksik Parametre:

{
  "success": false,
  "timestamp": "2025-10-08 15:34:20",
  "request_id": "req_68e5011f6d7e8b9c",
  "error": {
    "message": "Customer name and email are required",
    "code": "Bad Request",
    "details": null
  }
}

🔄 Sipariş Oluşturma Süreci

  1. 1. Validasyon: Customer ve products parametreleri kontrol edilir
  2. 2. Ürün Kontrolü: Her ürün için satıcıya ait olup olmadığı kontrol edilir
  3. 3. Stok Kontrolü: Ürün stokları kontrol edilir (yetersizse hata döner)
  4. 4. Fiyat Hesaplama: Eğer fiyat gönderilmemişse ürün fiyatı kullanılır
  5. 5. Kargo Ücreti: 500 TL altı siparişler için 25 TL kargo ücreti eklenir
  6. 6. Sipariş Oluşturma: siparis, satici_siparis ve siparis_urun tablolarına kayıt yapılır
  7. 7. Stok Güncelleme: Ürün stokları otomatik olarak azaltılır
  8. 8. Transaction: Tüm işlemler transaction içinde yapılır (hata durumunda rollback)

⚠️ Önemli Notlar

  • Ürün Sahipliği: Sadece satıcınıza ait ürünler için sipariş oluşturabilirsiniz.
  • Stok Kontrolü: Yetersiz stok durumunda hata döner ve işlem yapılmaz.
  • Telefon Formatı: Telefon numarası 10 karakterden uzunsa son 10 hane kullanılır.
  • Otomatik Stok: Sipariş oluşturulunca stoklar otomatik düşer (geri alınamaz).
  • Misafir Üye: API'den gelen siparişler otomatik olarak misafir üye (siparis_turu=2) olarak kaydedilir.
  • Kargo Ücreti: 500 TL ve üzeri siparişlerde ücretsiz kargo, altında 25 TL kargo ücreti eklenir.
  • Transaction Güvenliği: Herhangi bir hata durumunda tüm işlemler geri alınır (rollback).

Sipariş Detayı

🔍 Sipariş Detayı Nedir?

Belirli bir siparişin tüm detaylı bilgilerini getiren endpoint. Müşteri bilgileri, sipariş kalemleri, teslimat ve ödeme bilgilerini içerir.

👤 Müşteri

İletişim ve adres bilgileri

📦 Ürünler

Sipariş kalemleri ve fiyatlar

💳 Ödeme

Ödeme yöntemi ve tutarlar

GET /api/v1/orders/{order_id}
Authorization: Bearer your_token

URL Parametreleri

Parametre Tip Zorunlu Açıklama
order_id string Evet Sipariş ID (örn: ORD-2025-68e5001492c13)

JavaScript Örneği

const axios = require('axios');

const getOrderDetails = async (orderId) => {
  try {
    const response = await axios.get(
      `https://idnsx.com/espazar/api/v1/orders/${orderId}`,
      {
        headers: {
          'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
        }
      }
    );

    const order = response.data.data;
    console.log('Sipariş ID:', order.order_id);
    console.log('Durum:', order.status);
    console.log('Müşteri:', order.customer.name);
    console.log('Ürün Sayısı:', order.items.length);
    console.log('Toplam:', order.payment.total);

    return order;
  } catch (error) {
    if (error.response.status === 404) {
      console.error('Sipariş bulunamadı!');
    } else {
      console.error('Hata:', error.response.data);
    }
  }
};

getOrderDetails('ORD-2025-68e5001492c13');

cURL Örneği

curl -X 'GET' \
  'https://idnsx.com/espazar/api/v1/orders/ORD-2025-68e5001492c13' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
  -H 'Accept: application/json'

Response Örneği (Başarılı)

{
  "success": true,
  "timestamp": "2025-10-08 16:15:30",
  "request_id": "req_68e51a2b7c3d4e5f",
  "data": {
    "order_id": "ORD-2025-68e5001492c13",
    "order_number": "ORD-2025-68e5001492c13",
    "status": "approved",
    "created_at": "1728307200",
    "updated_at": "1728310800",
    "customer": {
      "name": "Ahmet Yılmaz",
      "email": "ahmet@example.com",
      "phone": "5551234567",
      "tc_no": "12345678901",
      "tax_office": null,
      "tax_number": null,
      "company_name": null
    },
    "shipping_address": {
      "name": "Ahmet Yılmaz",
      "address": "Atatürk Mah. Cumhuriyet Cad. No:123 Daire:5",
      "district": "Kadıköy",
      "city": "İstanbul",
      "country": "TR",
      "phone": "5551234567"
    },
    "billing_address": {
      "name": "Ahmet Yılmaz",
      "address": "Atatürk Mah. Cumhuriyet Cad. No:123 Daire:5",
      "district": "Kadıköy",
      "city": "İstanbul",
      "country": "TR",
      "phone": "5551234567"
    },
    "items": [
      {
        "product_id": 20528,
        "sku": "SKU-20528-001",
        "title": "Debug Test",
        "barcode": "",
        "quantity": 2,
        "price": 299.99,
        "discount_price": 0,
        "line_total": 599.98,
        "image": "dosya/urun/product-20528.webp"
      },
      {
        "product_id": 20529,
        "sku": "SKU-20529-002",
        "title": "Test Product 2",
        "barcode": "1234567890123",
        "quantity": 1,
        "price": 150.00,
        "discount_price": 0,
        "line_total": 150.00,
        "image": "dosya/urun/product-20529.webp"
      }
    ],
    "shipping": {
      "method": "Standard Shipping",
      "tracking_number": "YK123456789TR"
    },
    "payment": {
      "status": "paid",
      "method": "credit_card",
      "total": 774.98,
      "currency": "TRY"
    }
  }
}

Hata Response Örneği

❌ Sipariş Bulunamadı (404):

{
  "success": false,
  "timestamp": "2025-10-08 16:18:45",
  "request_id": "req_68e51b056d7e8b9c",
  "error": {
    "message": "Order not found",
    "code": "Not Found",
    "details": null
  }
}

📊 Response Alanları

customer (object)

Müşteri bilgileri: ad, email, telefon

shipping_address (object)

Teslimat adresi: adres, ilçe, şehir, ülke, telefon

billing_address (object)

Fatura adresi (genellikle teslimat adresiyle aynı)

items (array)

Sipariş kalemleri: product_id, sku, title, quantity, price, line_total, image

shipping (object)

Kargo bilgileri: method, tracking_number

payment (object)

Ödeme bilgileri: status, method, total, currency

⚠️ Önemli Notlar

  • Sahiplik Kontrolü: Sadece satıcınıza ait siparişlerin detaylarını görebilirsiniz.
  • 404 Hatası: Sipariş bulunamazsa veya başka bir satıcıya aitse 404 döner.
  • Ürün Resimleri: Resim yolları relative path olarak döner (örn: dosya/urun/product-123.webp).
  • Tarih Formatı: created_at ve updated_at alanları UNIX timestamp formatındadır.
  • Fatura Adresi: Şu an için fatura adresi teslimat adresiyle aynıdır.

Sipariş Durumu Güncelleme

🔄 Sipariş Durumu Güncelleme Nedir?

Siparişin işlem sürecindeki durumunu güncellemenizi sağlar. Sipariş onayından teslimat sonrasına kadar tüm aşamaları takip edebilir ve müşteriyi bilgilendirebilirsiniz.

✏️ Durum Değişimi

7 farklı durum seçeneği

📝 Not Ekleme

İsteğe bağlı açıklama

📊 Loglama

Otomatik değişiklik kaydı

PATCH /api/v1/orders/{order_id}/status
Authorization: Bearer your_token

Request Body Parametreleri

Parametre Tip Zorunlu Açıklama
status string Evet Yeni sipariş durumu (approved, preparing, shipped, vb.)
note string Hayır Durum değişikliği için not/açıklama

Geçerli Durum Değerleri (API'de Güncellenebilir)

approved Durum: 1

✅ Onaylandı - Sipariş onaylandı, işlem başlayabilir

preparing Durum: 2

🔄 Tedarik sürecinde - Ürün tedarik ediliyor

packaging Durum: 3

📦 Hazırlanıyor - Ürün paketleniyor

shipped Durum: 4

🚚 Kargoya verildi - Kargo şirketine teslim edildi

delivered Durum: 5

🚛 Kargoda - Müşteriye doğru yolda

completed Durum: 6

✔️ Teslim edildi - Müşteriye ulaştı

cancelled Durum: 10

❌ İptal edildi - Sipariş iptal edildi

Not: pending durumu sadece görüntüleme içindir, güncellenemez. İade ve kısmi gönderim durumları için ilgili endpoint'leri kullanın.

Request Body Örneği

{
  "status": "shipped",
  "note": "Sipariş Yurtiçi Kargo'ya teslim edildi. Takip No: YK123456789TR"
}

JavaScript Örneği

const axios = require('axios');

const updateOrderStatus = async (orderId, status, note) => {
  try {
    const response = await axios.patch(
      `https://idnsx.com/espazar/api/v1/orders/${orderId}/status`,
      {
        status: status,
        note: note
      },
      {
        headers: {
          'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
          'Content-Type': 'application/json'
        }
      }
    );

    console.log('Durum güncellendi:', response.data.data.status);
    console.log('Mesaj:', response.data.data.message);

    return response.data;
  } catch (error) {
    if (error.response.status === 400) {
      console.error('Geçersiz durum değeri!');
    } else if (error.response.status === 404) {
      console.error('Sipariş bulunamadı!');
    } else {
      console.error('Hata:', error.response.data);
    }
  }
};

// Kullanım örnekleri
updateOrderStatus('ORD-2025-68e5001492c13', 'shipped', 'Kargoya verildi');
updateOrderStatus('ORD-2025-68e5001492c13', 'delivered', 'Müşteriye teslim edildi');

cURL Örneği

curl -X 'PATCH' \
  'https://idnsx.com/espazar/api/v1/orders/ORD-2025-68e5001492c13/status' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "status": "shipped",
    "note": "Sipariş kargoya verildi"
  }'

Response Örneği (Başarılı)

{
  "success": true,
  "timestamp": "2025-10-08 17:45:20",
  "request_id": "req_68e52c7a5d4b6e8f",
  "data": {
    "order_id": "ORD-2025-68e5001492c13",
    "status": "shipped",
    "message": "Order status updated successfully"
  }
}

Hata Response Örnekleri

❌ Geçersiz Durum (400):

{
  "success": false,
  "timestamp": "2025-10-08 17:46:30",
  "request_id": "req_68e52cbe7f8a9b0c",
  "error": {
    "message": "Invalid status",
    "code": "Bad Request",
    "details": null
  }
}

❌ Sipariş Bulunamadı (404):

{
  "success": false,
  "timestamp": "2025-10-08 17:47:15",
  "request_id": "req_68e52cf3a1b2c3d4",
  "error": {
    "message": "Order not found or access denied",
    "code": "Not Found",
    "details": null
  }
}

⚠️ Önemli Notlar

  • Sahiplik Kontrolü: Sadece satıcınıza ait siparişlerin durumunu güncelleyebilirsiniz.
  • Geçerli Durumlar: Sadece 7 durum değeri kabul edilir: approved, preparing, packaging, shipped, delivered, completed, cancelled
  • Not Alanı: note parametresi opsiyoneldir ancak durum değişikliklerini açıklamak için kullanılması önerilir.
  • Otomatik Log: Her durum değişikliği otomatik olarak admin_panel_log tablosuna kaydedilir.
  • İade Durumları: İade durumları (return_pending, return_received, return_completed) için /orders/{id}/returns endpoint'lerini kullanın.
  • Kısmi Gönderim: Kısmi gönderim durumları için /orders/{id}/partial-ship endpoint'ini kullanın.
  • Zaman Damgası: son_islem_tarihi alanı otomatik olarak güncellenir.

Sipariş Gönderme

🚚 Sipariş Gönderme Nedir?

Siparişi kargoya verdiğinizde takip numarası ve kargo firması bilgilerini sisteme kaydetmenizi sağlar. Sipariş durumu otomatik olarak "shipped" (kargoya verildi) olarak güncellenir.

📦 Takip No

Kargo takip numarası kaydı

🏢 Kargo Firması

Hangi kargo ile gönderildi

🔄 Otomatik

Durum otomatik güncellenir

POST /api/v1/orders/{order_id}/ship
Authorization: Bearer your_token

Request Body Parametreleri

Parametre Tip Zorunlu Açıklama
tracking_number string Evet Kargo takip numarası (örn: YK123456789TR)
carrier string Evet Kargo firması adı (örn: Yurtiçi Kargo, MNG Kargo, Aras Kargo)
note string Hayır Gönderim ile ilgili not (opsiyonel)

Request Body Örneği

{
  "tracking_number": "YK123456789TR",
  "carrier": "Yurtiçi Kargo",
  "note": "Standart teslimat, 2-3 iş günü"
}

JavaScript Örneği

const axios = require('axios');

const shipOrder = async (orderId, trackingNumber, carrier, note = '') => {
  try {
    const response = await axios.post(
      `https://idnsx.com/espazar/api/v1/orders/${orderId}/ship`,
      {
        tracking_number: trackingNumber,
        carrier: carrier,
        note: note
      },
      {
        headers: {
          'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
          'Content-Type': 'application/json'
        }
      }
    );

    console.log('Sipariş kargoya verildi!');
    console.log('Takip No:', response.data.data.tracking_number);
    console.log('Kargo:', response.data.data.carrier);

    return response.data;
  } catch (error) {
    if (error.response.status === 400) {
      console.error('Eksik parametre! Takip numarası ve kargo firması zorunludur.');
    } else if (error.response.status === 404) {
      console.error('Sipariş bulunamadı!');
    } else {
      console.error('Hata:', error.response.data);
    }
  }
};

// Kullanım örnekleri
shipOrder('ORD-2025-68e5001492c13', 'YK123456789TR', 'Yurtiçi Kargo', 'Hızlı teslimat');
shipOrder('ORD-2025-68e5001492c13', 'MNG987654321TR', 'MNG Kargo');

cURL Örneği

curl -X 'POST' \
  'https://idnsx.com/espazar/api/v1/orders/ORD-2025-68e5001492c13/ship' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "tracking_number": "YK123456789TR",
    "carrier": "Yurtiçi Kargo",
    "note": "Standart teslimat"
  }'

Response Örneği (Başarılı)

{
  "success": true,
  "timestamp": "2025-10-08 18:15:45",
  "request_id": "req_68e53d4a6b7c8e9f",
  "data": {
    "order_id": "ORD-2025-68e5001492c13",
    "tracking_number": "YK123456789TR",
    "carrier": "Yurtiçi Kargo",
    "message": "Order marked as shipped"
  }
}

Hata Response Örnekleri

❌ Eksik Parametre (400):

{
  "success": false,
  "timestamp": "2025-10-08 18:16:30",
  "request_id": "req_68e53d7e8f9a0b1c",
  "error": {
    "message": "Tracking number and carrier are required",
    "code": "Bad Request",
    "details": null
  }
}

❌ Sipariş Bulunamadı (404):

{
  "success": false,
  "timestamp": "2025-10-08 18:17:10",
  "request_id": "req_68e53da69c1d2e3f",
  "error": {
    "message": "Order not found or access denied",
    "code": "Not Found",
    "details": null
  }
}

🔄 İşleyiş Süreci

1

Sahiplik Kontrolü

Siparişin satıcınıza ait olup olmadığı kontrol edilir

2

Parametre Validasyonu

tracking_number ve carrier alanlarının dolu olduğu kontrol edilir

3

Transaction Başlat

Veritabanı transaction'ı başlatılır

4

Kargo Bilgileri Güncelleme

satici_siparis tablosunda kargo_takip_numarasi kaydedilir

5

Durum Güncelleme

satici_durum otomatik olarak 4 (shipped) yapılır

6

Zaman Damgası

son_islem_tarihi UNIX_TIMESTAMP(NOW()) ile güncellenir (UNIX timestamp)

7

Log Kaydı

İşlem admin_panel_log tablosuna kaydedilir

8

Transaction Commit

Tüm işlemler başarılıysa veritabanına yazılır

⚠️ Önemli Notlar

  • Zorunlu Alanlar: tracking_number ve carrier alanları zorunludur, eksik gönderilirse 400 hatası döner.
  • Otomatik Durum: Sipariş durumu otomatik olarak "shipped" (satici_durum = 4) yapılır.
  • Sahiplik Kontrolü: Sadece satıcınıza ait siparişleri kargoya verebilirsiniz.
  • Transaction Güvenliği: Tüm işlemler transaction içinde gerçekleşir, hata durumunda rollback yapılır.
  • Kargo Firmaları: Yurtiçi Kargo, MNG Kargo, Aras Kargo, PTT Kargo, Sürat Kargo gibi yaygın kargo firmaları kullanılabilir.
  • Takip Numarası: Takip numarası mutlaka doğru ve geçerli olmalıdır, müşteri bu numarayla kargo takibi yapacaktır.
  • Not Alanı: note parametresi opsiyoneldir, ekstra bilgi vermek isterseniz kullanabilirsiniz.
  • Müşteri Bildirimi: Sipariş kargoya verildiğinde müşteriye otomatik bildirim gönderilir (platform tarafından).

Sipariş İptal

❌ Sipariş İptal Nedir?

Siparişi iptal etmenizi sağlar. İptal sebebi ve açıklama ekleyebilirsiniz. Sipariş durumu otomatik olarak "cancelled" olarak güncellenir.

📝 İptal Sebebi

Neden iptal edildiği

💬 Açıklama

Detaylı iptal notu

📊 Log

Otomatik kayıt tutulur

POST /api/v1/orders/{order_id}/cancel
Authorization: Bearer your_token

Request Body Parametreleri

Parametre Tip Zorunlu Açıklama
reason string Hayır İptal sebebi (örn: "Stok yetersiz", "Müşteri talebi")
note string Hayır Detaylı iptal açıklaması (opsiyonel)

Not: Her iki parametre de opsiyoneldir, ancak iptal sebebi belirtmeniz önerilir.

Yaygın İptal Sebepleri

🔴 Stok yetersiz

Ürün stoklarımızda bulunmamaktadır

👤 Müşteri talebi

Müşteri siparişi iptal etmek istedi

💳 Ödeme sorunu

Ödeme işlemi tamamlanamadı

📍 Teslimat adresi

Adres hatalı veya teslimat yapılamıyor

🔧 Teknik sorun

Sistem veya işlem hatası

❓ Diğer

Başka bir sebep

Request Body Örneği

{
  "reason": "Stok yetersiz",
  "note": "Ürün stoklarımızda tükenmiştir. En kısa sürede temin edildiğinde tekrar sipariş verebilirsiniz."
}

JavaScript Örneği

const axios = require('axios');

const cancelOrder = async (orderId, reason, note = '') => {
  try {
    const response = await axios.post(
      `https://idnsx.com/espazar/api/v1/orders/${orderId}/cancel`,
      {
        reason: reason,
        note: note
      },
      {
        headers: {
          'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
          'Content-Type': 'application/json'
        }
      }
    );

    console.log('Sipariş iptal edildi!');
    console.log('Sipariş ID:', response.data.data.order_id);
    console.log('Durum:', response.data.data.status);
    console.log('Mesaj:', response.data.data.message);

    return response.data;
  } catch (error) {
    if (error.response.status === 404) {
      console.error('Sipariş bulunamadı veya erişim reddedildi!');
    } else if (error.response.status === 500) {
      console.error('Sipariş iptal edilemedi!');
    } else {
      console.error('Hata:', error.response.data);
    }
  }
};

// Kullanım örnekleri
cancelOrder('ORD-2025-68e5001492c13', 'Stok yetersiz', 'Ürün tedarik edilemiyor');
cancelOrder('ORD-2025-68e5001492c13', 'Müşteri talebi', 'Müşteri iptal talebinde bulundu');

cURL Örneği

curl -X 'POST' \
  'https://idnsx.com/espazar/api/v1/orders/ORD-2025-68e5001492c13/cancel' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "reason": "Stok yetersiz",
    "note": "Ürün stoklarımızda bulunmamaktadır"
  }'

Response Örneği (Başarılı)

{
  "success": true,
  "timestamp": "2025-10-08 18:45:30",
  "request_id": "req_68e54a5b7c8d9e0f",
  "data": {
    "order_id": "ORD-2025-68e5001492c13",
    "status": "cancelled",
    "message": "Order cancelled successfully"
  }
}

Hata Response Örnekleri

❌ Sipariş Bulunamadı (404):

{
  "success": false,
  "timestamp": "2025-10-08 18:46:15",
  "request_id": "req_68e54a8f9d0e1f2a",
  "error": {
    "message": "Order not found or access denied",
    "code": "Not Found",
    "details": null
  }
}

❌ İptal İşlemi Başarısız (500):

{
  "success": false,
  "timestamp": "2025-10-08 18:47:00",
  "request_id": "req_68e54ab4a1b2c3d4",
  "error": {
    "message": "Failed to cancel order",
    "code": "Internal Server Error",
    "details": null
  }
}

🔄 İşleyiş Süreci

1

Sahiplik Kontrolü

Siparişin satıcınıza ait olup olmadığı kontrol edilir

2

Parametre Okuma

reason ve note parametreleri okunur (opsiyonel)

3

Durum Güncelleme

satici_durum otomatik olarak 9 (cancelled) yapılır

4

İptal Bilgileri Kaydet

satici_iptal_nedeni ve satici_iptal_aciklama alanlarına kaydedilir

5

Zaman Damgası

son_islem_tarihi UNIX_TIMESTAMP(NOW()) ile güncellenir (UNIX timestamp)

6

Log Kaydı

İptal işlemi admin_panel_log tablosuna kaydedilir

7

Başarılı Response

İşlem sonucu müşteriye bildirilir

⚠️ Önemli Notlar

  • Opsiyonel Parametreler: reason ve note parametreleri opsiyoneldir, ancak iptal sebebi belirtmeniz önerilir.
  • Otomatik Durum: Sipariş durumu otomatik olarak "cancelled" (satici_durum = 9) yapılır.
  • Sahiplik Kontrolü: Sadece satıcınıza ait siparişleri iptal edebilirsiniz.
  • Stok İadesi: İptal edilen siparişlerdeki ürünlerin stokları otomatik olarak geri eklenmez, manuel kontrol gerekebilir.
  • Müşteri Bildirimi: Sipariş iptal edildiğinde müşteriye otomatik bildirim gönderilir (platform tarafından).
  • İptal Zamanı: Sipariş kargoya verildikten sonra iptal yerine iade işlemi başlatılmalıdır.
  • Log Tutma: Her iptal işlemi otomatik olarak kaydedilir ve raporlanabilir.
  • Geri Alınamaz: İptal işlemi geri alınamaz, dikkatli kullanılmalıdır.

İade İşlemleri

🔄 İade İşlemleri Nedir?

İade işlemleri, müşterilerin sipariş verdikleri ürünleri iade etme sürecini yönetmenizi sağlar. 5 farklı endpoint ile iade oluşturma, listeleme, güncelleme, onaylama ve reddetme işlemlerini gerçekleştirebilirsiniz.

➕ Oluştur

POST /return

📋 Listele

GET /returns

✏️ Güncelle

PATCH /returns/{id}

✅ Onayla

POST .../approve

❌ Reddet

POST .../reject

1️⃣ İade Talebi Oluşturma

POST /api/v1/orders/{order_id}/return
Authorization: Bearer your_token

Bir siparişin ürünleri için iade talebi oluşturur. Birden fazla ürün için aynı anda iade talebi oluşturabilirsiniz.

Request Body Parametreleri
Parametre Tip Zorunlu Açıklama
items array Evet İade edilecek ürün listesi (en az 1 ürün)
↳ product_id integer Evet Ürün ID
↳ quantity integer Evet İade miktarı
↳ reason string Hayır Ürüne özel iade sebebi
reason string Hayır Genel iade sebebi
description string Hayır Detaylı iade açıklaması
Request Body Örneği
{
  "items": [
    {
      "product_id": 20528,
      "quantity": 2,
      "reason": "Ürün hasarlı geldi"
    },
    {
      "product_id": 20529,
      "quantity": 1,
      "reason": "Yanlış ürün gönderildi"
    }
  ],
  "reason": "Müşteri memnuniyetsizliği",
  "description": "Ürünler hasar görmüş durumda ve müşteri iade talebinde bulundu"
}
JavaScript Örneği
const axios = require('axios');

const createReturn = async (orderId, items, reason, description) => {
  try {
    const response = await axios.post(
      `https://idnsx.com/espazar/api/v1/orders/${orderId}/return`,
      {
        items: items,
        reason: reason,
        description: description
      },
      {
        headers: {
          'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
          'Content-Type': 'application/json'
        }
      }
    );

    console.log('İade talebi oluşturuldu!');
    console.log('Sipariş ID:', response.data.data.order_id);
    console.log('İade edilen ürünler:', response.data.data.returned_items);

    return response.data;
  } catch (error) {
    console.error('Hata:', error.response.data);
  }
};

// Kullanım örneği
createReturn(
  'ORD-2025-68e5001492c13',
  [
    { product_id: 20528, quantity: 2, reason: 'Hasarlı ürün' },
    { product_id: 20529, quantity: 1, reason: 'Yanlış ürün' }
  ],
  'Müşteri memnuniyetsizliği',
  'Detaylı açıklama'
);
cURL Örneği
curl -X 'POST' \
  'https://idnsx.com/espazar/api/v1/orders/ORD-2025-68e5001492c13/return' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "items": [
      {
        "product_id": 20528,
        "quantity": 2,
        "reason": "Ürün hasarlı geldi"
      }
    ],
    "reason": "Müşteri memnuniyetsizliği",
    "description": "Detaylı açıklama"
  }'
Response Örneği (Başarılı)
{
  "success": true,
  "timestamp": "2025-10-08 19:30:15",
  "request_id": "req_68e55b47c8d9e0f1",
  "data": {
    "order_id": "ORD-2025-68e5001492c13",
    "status": "return_pending",
    "returned_items": [
      {
        "product_id": 20528,
        "quantity": 2,
        "reason": "Ürün hasarlı geldi"
      },
      {
        "product_id": 20529,
        "quantity": 1,
        "reason": "Yanlış ürün gönderildi"
      }
    ],
    "message": "Return request created successfully"
  }
}
Hata Response Örnekleri

❌ Ürün listesi eksik (400):

{
  "success": false,
  "error": {
    "message": "Return items are required",
    "code": "Bad Request"
  }
}

❌ İade miktarı fazla (400):

{
  "success": false,
  "error": {
    "message": "Failed to create return request: Return quantity exceeds order quantity for product 20528",
    "code": "Bad Request"
  }
}
⚠️ Önemli Notlar
  • items Zorunlu: En az 1 ürün içeren items array'i gönderilmelidir.
  • Miktar Kontrolü: İade miktarı siparişteki ürün miktarını aşamaz.
  • Durum Güncellemesi: Sipariş durumu otomatik olarak "return_pending" (7) yapılır.
  • Transaction Güvenliği: Tüm işlemler transaction içinde gerçekleşir, hata durumunda rollback yapılır.
  • Stok Güncelleme: İade oluşturulduğunda stok otomatik güncellenmez, onay sonrası güncellenir.

2️⃣ İade Taleplerini Listeleme

GET /api/v1/orders/{order_id}/returns
Authorization: Bearer your_token

Bir siparişe ait tüm iade taleplerini listeler. İade edilmiş ürünleri ve durumlarını gösterir.

JavaScript Örneği
const axios = require('axios');

const getReturns = async (orderId) => {
  try {
    const response = await axios.get(
      `https://idnsx.com/espazar/api/v1/orders/${orderId}/returns`,
      {
        headers: {
          'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
        }
      }
    );

    console.log('İade talepleri:', response.data.data.returns);

    response.data.data.returns.forEach(returnItem => {
      console.log(`Ürün: ${returnItem.product_name}`);
      console.log(`Miktar: ${returnItem.quantity}`);
      console.log(`Durum: ${returnItem.status}`);
      console.log(`Sebep: ${returnItem.reason}`);
      console.log('---');
    });

    return response.data;
  } catch (error) {
    console.error('Hata:', error.response.data);
  }
};

getReturns('ORD-2025-68e5001492c13');
cURL Örneği
curl -X 'GET' \
  'https://idnsx.com/espazar/api/v1/orders/ORD-2025-68e5001492c13/returns' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
  -H 'Accept: application/json'
Response Örneği (Başarılı)
{
  "success": true,
  "timestamp": "2025-10-08 20:00:30",
  "request_id": "req_68e56a1e3f4b5c6d",
  "data": {
    "returns": [
      {
        "item_id": 147,
        "product_id": 20528,
        "product_name": "Debug Test",
        "quantity": 2,
        "return_date": "2025-10-08 19:30:15",
        "status": "return_pending",
        "reason": "Ürün hasarlı geldi",
        "updated_at": 1728401415
      },
      {
        "item_id": 148,
        "product_id": 20529,
        "product_name": "Test Product 2",
        "quantity": 1,
        "return_date": "2025-10-08 19:30:15",
        "status": "return_pending",
        "reason": "Yanlış ürün gönderildi",
        "updated_at": 1728401415
      }
    ]
  }
}
📊 Response Alanları

item_id

Sipariş kalemi ID'si (siparis_urun tablosundan)

product_id

Ürün ID'si

product_name

Ürün adı

quantity

İade edilen miktar

return_date

İade talebi oluşturulma tarihi

status

İade durumu (return_pending, return_received, return_completed)

reason

İade sebebi

updated_at

Son güncelleme tarihi

Hata Response Örneği

❌ Sipariş Bulunamadı (404):

{
  "success": false,
  "error": {
    "message": "Order not found or access denied",
    "code": "Not Found"
  }
}
⚠️ Önemli Notlar
  • Sadece İadeli Ürünler: Yalnızca uye_iade_adet > 0 olan ürünler listelenir.
  • Tarih Sıralama: İadeler en yeni tarihten eskiye doğru sıralanır.
  • Boş Liste: İade talebi yoksa returns array'i boş döner.
  • Durum Takibi: Her ürün kalemi için ayrı durum bilgisi görüntülenir.

3️⃣ İade Durumu Güncelleme

PATCH /api/v1/orders/{order_id}/returns/{return_id}
Authorization: Bearer your_token

İade talebinin durumunu günceller. return_id olarak item_id (siparis_urun tablosundaki id) kullanılır.

Request Body Parametreleri
Parametre Tip Zorunlu Açıklama
status string Evet İade durumu (pending, approved, rejected, completed)
note string Hayır Durum değişikliği ile ilgili not
Geçerli Durum Değerleri
pending Durum: 7

⏳ İade beklemede - return_pending

approved Durum: 8

✅ İade onaylandı - return_received

rejected Durum: 0

❌ İade reddedildi - normal duruma döner

completed Durum: 9

✔️ İade tamamlandı - return_completed

Request Body Örneği
{
  "status": "approved",
  "note": "İade incelendi ve onaylandı. Ürün depoya ulaştı."
}
JavaScript Örneği
const axios = require('axios');

const updateReturn = async (orderId, returnId, status, note) => {
  try {
    const response = await axios.patch(
      `https://idnsx.com/espazar/api/v1/orders/${orderId}/returns/${returnId}`,
      {
        status: status,
        note: note
      },
      {
        headers: {
          'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
          'Content-Type': 'application/json'
        }
      }
    );

    console.log('İade durumu güncellendi!');
    console.log('Yeni durum:', response.data.data.status);

    return response.data;
  } catch (error) {
    console.error('Hata:', error.response.data);
  }
};

// Kullanım örnekleri
updateReturn('ORD-2025-68e5001492c13', '147', 'approved', 'İade onaylandı');
updateReturn('ORD-2025-68e5001492c13', '148', 'rejected', 'İade uygun değil');
cURL Örneği
curl -X 'PATCH' \
  'https://idnsx.com/espazar/api/v1/orders/ORD-2025-68e5001492c13/returns/147' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "status": "approved",
    "note": "İade onaylandı"
  }'
Response Örneği (Başarılı)
{
  "success": true,
  "timestamp": "2025-10-08 20:15:45",
  "request_id": "req_68e56d819a0b1c2d",
  "data": {
    "order_id": "ORD-2025-68e5001492c13",
    "status": "approved",
    "message": "Return status updated successfully"
  }
}
Hata Response Örnekleri

❌ Status eksik (400):

{
  "success": false,
  "error": {
    "message": "Status is required",
    "code": "Bad Request"
  }
}

❌ Geçersiz status (400):

{
  "success": false,
  "error": {
    "message": "Invalid status",
    "code": "Bad Request"
  }
}
⚠️ Önemli Notlar
  • return_id Kullanımı: return_id olarak GET /returns'den dönen item_id kullanılır.
  • Status Zorunlu: status parametresi mutlaka gönderilmelidir.
  • Not Ekleme: note parametresi varsa mevcut açıklamaya eklenir (CONCAT kullanılır).
  • Durum Kodları: pending=7, approved=8, rejected=0, completed=9
  • Sipariş Durumu: satici_siparis tablosundaki tüm sipariş durumu güncellenir.

4️⃣ İade Onaylama

POST /api/v1/orders/{order_id}/returns/{return_id}/approve
Authorization: Bearer your_token

İade talebini hızlıca onaylar. İade durumunu otomatik olarak "return_received" (8) yapar. Body gerektirmez, sadece URL ile çalışır.

JavaScript Örneği
const axios = require('axios');

const approveReturn = async (orderId, returnId) => {
  try {
    const response = await axios.post(
      `https://idnsx.com/espazar/api/v1/orders/${orderId}/returns/${returnId}/approve`,
      {},
      {
        headers: {
          'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
        }
      }
    );

    console.log('İade onaylandı!');
    console.log('Sipariş ID:', response.data.data.order_id);
    console.log('Durum:', response.data.data.status);

    return response.data;
  } catch (error) {
    console.error('Hata:', error.response.data);
  }
};

approveReturn('ORD-2025-68e5001492c13', '147');
cURL Örneği
curl -X 'POST' \
  'https://idnsx.com/espazar/api/v1/orders/ORD-2025-68e5001492c13/returns/147/approve' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
  -H 'Accept: application/json'
Response Örneği (Başarılı)
{
  "success": true,
  "timestamp": "2025-10-08 20:30:20",
  "request_id": "req_68e570bcdef12345",
  "data": {
    "order_id": "ORD-2025-68e5001492c13",
    "status": "approved",
    "message": "Return approved successfully"
  }
}
⚠️ Önemli Notlar
  • Body Gerekmez: Bu endpoint body parametresi gerektirmez, sadece URL yeterlidir.
  • Otomatik Not: "İade satıcı tarafından onaylandı" notu otomatik eklenir.
  • Durum Değişimi: satici_durum otomatik olarak 8 (return_received) yapılır.
  • Hızlı İşlem: PATCH yerine bu endpoint ile daha hızlı onaylama yapılabilir.

5️⃣ İade Reddetme

POST /api/v1/orders/{order_id}/returns/{return_id}/reject
Authorization: Bearer your_token

İade talebini hızlıca reddeder. İade durumunu 0 (normal) yaparak iade talebini iptal eder. Body gerektirmez, sadece URL ile çalışır.

JavaScript Örneği
const axios = require('axios');

const rejectReturn = async (orderId, returnId) => {
  try {
    const response = await axios.post(
      `https://idnsx.com/espazar/api/v1/orders/${orderId}/returns/${returnId}/reject`,
      {},
      {
        headers: {
          'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
        }
      }
    );

    console.log('İade reddedildi!');
    console.log('Sipariş ID:', response.data.data.order_id);
    console.log('Durum:', response.data.data.status);

    return response.data;
  } catch (error) {
    console.error('Hata:', error.response.data);
  }
};

rejectReturn('ORD-2025-68e5001492c13', '148');
cURL Örneği
curl -X 'POST' \
  'https://idnsx.com/espazar/api/v1/orders/ORD-2025-68e5001492c13/returns/148/reject' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
  -H 'Accept: application/json'
Response Örneği (Başarılı)
{
  "success": true,
  "timestamp": "2025-10-08 20:32:45",
  "request_id": "req_68e5712d6a7b8c9d",
  "data": {
    "order_id": "ORD-2025-68e5001492c13",
    "status": "rejected",
    "message": "Return rejected successfully"
  }
}
⚠️ Önemli Notlar
  • Body Gerekmez: Bu endpoint body parametresi gerektirmez, sadece URL yeterlidir.
  • Otomatik Not: "İade satıcı tarafından reddedildi" notu otomatik eklenir.
  • Durum Değişimi: satici_durum otomatik olarak 0 (normal) yapılır, iade iptal olur.
  • Geri Alınamaz: Reddedilen iade talebi için yeniden işlem başlatılması gerekir.
  • Hızlı İşlem: PATCH yerine bu endpoint ile daha hızlı red işlemi yapılabilir.

📊 İade İşlemleri Özeti

1

İade Oluştur

POST /return

Ürünler için iade talebi oluştur

2

İadeleri Listele

GET /returns

Tüm iade taleplerini görüntüle

3

Durum Güncelle

PATCH /returns/{id}

İade durumunu manuel güncelle

4

İade Onayla

POST .../approve

Hızlı onaylama işlemi

5

İade Reddet

POST .../reject

Hızlı red işlemi

💡 Kullanım İpuçları:

  • • İade oluşturduktan sonra GET ile listeleyip item_id'leri alın
  • • Hızlı işlem için approve/reject endpoint'lerini kullanın
  • • Özel durum değişiklikleri için PATCH endpoint'ini tercih edin
  • • Her işlem otomatik olarak loglanır ve takip edilebilir

Kısmi Gönderim İşlemleri

📦 Kısmi Gönderim Nedir?

Siparişin tüm ürünlerini aynı anda göndermek yerine, hazır olan ürünleri önce göndermenizi sağlar. Stok eksikliği veya tedarik süreçlerinde kullanışlıdır.

📋 Oluştur

POST /partial-ship

📊 Listele

GET /partial-shipments

✏️ Güncelle

PATCH /partial-shipments/{id}

📦 Kısmi Gönderim Oluşturma

POST /api/v1/orders/{order_id}/partial-ship
Authorization: Bearer your_token

Bir siparişin sadece belirli ürünlerini gönderir. Sipariş durumu otomatik olarak "partial_shipment" (11) yapılır.

Request Body Parametreleri
Parametre Tip Zorunlu Açıklama
items array Evet Gönderilecek ürün listesi
↳ product_id integer Evet Ürün ID
↳ quantity integer Evet Gönderilecek miktar
tracking_number string Hayır Kargo takip numarası (opsiyonel)
carrier string Hayır Kargo firması adı (opsiyonel)
note string Hayır Kısmi gönderim notu (opsiyonel)
Request Body Örneği
{
  "items": [
    {
      "product_id": 20528,
      "quantity": 2
    }
  ],
  "tracking_number": "YK987654321TR",
  "carrier": "Yurtiçi Kargo",
  "note": "İlk parti ürünler gönderildi, kalan ürünler 3 gün içinde gönderilecek"
}
JavaScript Örneği
const axios = require('axios');

const createPartialShipment = async (orderId, items, trackingNumber, carrier, note) => {
  try {
    const response = await axios.post(
      `https://idnsx.com/espazar/api/v1/orders/${orderId}/partial-ship`,
      {
        items: items,
        tracking_number: trackingNumber,
        carrier: carrier,
        note: note
      },
      {
        headers: {
          'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
          'Content-Type': 'application/json'
        }
      }
    );

    console.log('Kısmi gönderim oluşturuldu!');
    console.log('Takip No:', response.data.data.tracking_number);
    console.log('Kargo:', response.data.data.carrier);

    return response.data;
  } catch (error) {
    console.error('Hata:', error.response.data);
  }
};

// Kullanım örneği
createPartialShipment(
  'ORD-2025-68e5001492c13',
  [{ product_id: 20528, quantity: 2 }],
  'YK987654321TR',
  'Yurtiçi Kargo',
  'İlk parti gönderildi'
);
cURL Örneği
curl -X 'POST' \
  'https://idnsx.com/espazar/api/v1/orders/ORD-2025-68e5001492c13/partial-ship' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "items": [{"product_id": 20528, "quantity": 2}],
    "tracking_number": "YK987654321TR",
    "carrier": "Yurtiçi Kargo",
    "note": "İlk parti gönderildi"
  }'
Response Örneği (Başarılı)
{
  "success": true,
  "timestamp": "2025-10-08 21:00:30",
  "request_id": "req_68e578be9f0a1b2c",
  "data": {
    "order_id": "ORD-2025-68e5001492c13",
    "tracking_number": "YK987654321TR",
    "carrier": "Yurtiçi Kargo",
    "status": "partial_shipment",
    "message": "Partial shipment created successfully"
  },
  "message": "Partial shipment created successfully"
}
⚠️ Önemli Notlar
  • items Zorunlu: En az 1 ürün içeren items array'i gönderilmelidir.
  • Otomatik Durum: Sipariş durumu otomatik olarak 11 (partial_shipment) yapılır.
  • Not Ekleme: note parametresi "[Kısmi Gönderim]" öneki ile satici_durum_aciklama'ya eklenir.
  • Takip Numarası: tracking_number ve carrier opsiyoneldir ancak önerilir.
  • Log Kaydı: İşlem otomatik olarak loglanır ve takip edilebilir.

📊 Kısmi Gönderimleri Listeleme

GET /api/v1/orders/{order_id}/partial-shipments
Authorization: Bearer your_token

Bir siparişe ait kısmi gönderim bilgilerini listeler. Sadece durum 11 veya 12 olan siparişler listelenir.

JavaScript Örneği
const axios = require('axios');

const getPartialShipments = async (orderId) => {
  try {
    const response = await axios.get(
      `https://idnsx.com/espazar/api/v1/orders/${orderId}/partial-shipments`,
      {
        headers: {
          'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
        }
      }
    );

    console.log('Kısmi gönderimler:', response.data.data.shipments);

    return response.data;
  } catch (error) {
    console.error('Hata:', error.response.data);
  }
};

getPartialShipments('ORD-2025-68e5001492c13');
Response Örneği (Başarılı)
{
  "success": true,
  "timestamp": "2025-10-08 21:05:15",
  "request_id": "req_68e579eb2c3d4e5f",
  "data": {
    "shipments": [
      {
        "order_id": "ORD-2025-68e5001492c13",
        "tracking_number": "YK987654321TR",
        "status": "partial_shipment",
        "note": "[Kısmi Gönderim] İlk parti gönderildi",
        "created_at": 1728410430,
        "updated_at": 1728410430
      }
    ]
  }
}
⚠️ Önemli Notlar
  • Durum Filtresi: Sadece satici_durum = 11 veya 12 olan siparişler listelenir.
  • Boş Liste: Kısmi gönderim yoksa shipments array'i boş döner.
  • Tek Kayıt: Şu an sistemde bir sipariş için tek kısmi gönderim kaydı tutulur.

📊 Kısmi Gönderim Özeti

1

Kısmi Gönderim Oluştur

POST /partial-ship

Hazır ürünleri önce gönder

2

Gönderimleri Listele

GET /partial-shipments

Kısmi gönderim bilgilerini gör

3

Durum Güncelle

PATCH /partial-shipments/{id}

Gönderim bilgilerini güncelle

💡 Kullanım Senaryoları:

  • • Stokta olmayan ürünler için diğer ürünleri bekletmeden gönderim
  • • Farklı depolardan gönderilecek ürünler için ayrı kargo takibi
  • • Tedarik süresi uzun olan ürünler için önce hazır olanları gönderme
  • • Müşteri memnuniyeti için hızlı teslimat sağlama

Ek Sipariş İşlemleri

Sipariş Geçmişi

GET /orders/{id}/history

Not Ekleme

POST /orders/{id}/notes

Para İadesi

POST /orders/{id}/refund

Marka Yönetimi

🏷️ Marka Yönetimi Nedir?

Satıcıların kendi markalarını platform üzerinde kaydetmesi ve yönetmesi için kullanılan API endpoint'leri. Tüm marka başvuruları admin onayından geçer ve sadece onaylanan markalar ürünlerde kullanılabilir.

📋 Listeleme

GET /brands

➕ Oluşturma

POST /brands

👁️ Detay

GET /brands/{id}

✏️ Güncelleme

PUT /brands/{id}

🗑️ Silme

DELETE /brands/{id}

🏷️ Marka Durumları

pending (0)

Onay bekliyor - Düzenlenebilir ve silinebilir

active (1)

Admin onaylandı - Ürünlerde kullanılabilir

rejected (-1)

Admin reddetti - rejection_reason alanında açıklama

📋 Marka Listeleme

GET /api/v1/brands
Authorization: Bearer your_token

Satıcının tüm marka başvurularını listeler. Pagination ve status filtreleme desteklenir.

Query Parametreleri
Parametre Tip Varsayılan Açıklama
page integer 1 Sayfa numarası
per_page integer 50 Sayfa başına kayıt (max 100)
status string - pending, active, rejected
JavaScript Örneği
const axios = require('axios');

const listBrands = async (status = null, page = 1) => {
  try {
    const params = { page: page, per_page: 50 };
    if (status) params.status = status;

    const response = await axios.get(
      'https://idnsx.com/espazar/api/v1/brands',
      {
        params: params,
        headers: {
          'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
        }
      }
    );

    console.log('Markalar:', response.data.data.brands);
    console.log('Toplam:', response.data.data.meta.total_items);

    return response.data;
  } catch (error) {
    console.error('Hata:', error.response.data);
  }
};

// Kullanım örnekleri
listBrands(); // Tüm markalar
listBrands('active'); // Sadece onaylı markalar
listBrands('pending', 2); // 2. sayfadaki bekleyen markalar
Response Örneği (Başarılı)
{
  "success": true,
  "timestamp": "2025-10-08 22:15:30",
  "request_id": "req_68e58a329d4e5f6a",
  "data": {
    "brands": [
      {
        "id": 114,
        "brand_name": "Apple Inc",
        "logo": "https://localhost/dosya/brands/apple-logo.jpg",
        "categories": ["Elektronik", "Akıllı Telefon"],
        "status": "pending",
        "rejection_reason": null,
        "created_at": 1728414618,
        "updated_at": 1728414618
      },
      {
        "id": 113,
        "brand_name": "Samsung Elektronik",
        "logo": "https://localhost/dosya/brands/samsung-logo.jpg",
        "categories": ["Elektronik", "Beyaz Eşya"],
        "status": "active",
        "rejection_reason": null,
        "created_at": 1728411370,
        "updated_at": 1728414000
      }
    ],
    "meta": {
      "current_page": 1,
      "total_pages": 1,
      "per_page": 50,
      "total_items": 2,
      "has_next": false,
      "has_prev": false
    }
  }
}
Response Alanları Açıklaması
  • id - Marka ID'si
  • brand_name - Marka adı
  • logo - Logo URL'si (null olabilir)
  • categories - İlişkili kategori isimleri (array)
  • status - pending, active veya rejected
  • rejection_reason - Red nedeni (sadece rejected durumunda)
  • created_at - Oluşturulma tarihi
  • updated_at - Son güncelleme tarihi
⚠️ Önemli Notlar
  • Sadece Kendi Markaları: Satıcı sadece kendi oluşturduğu markaları görebilir.
  • Sıralama: Markalar son işlem tarihine göre azalan sırayla listelenir.
  • Logo URL: Logo yoksa null döner, varsa tam URL ile döner.

➕ Marka Oluşturma (Yeni Başvuru)

POST /api/v1/brands
Authorization: Bearer your_token

Yeni bir marka başvurusu oluşturur. Başvuru otomatik olarak "pending" durumunda oluşturulur ve admin onayı bekler.

Request Body Parametreleri
Parametre Tip Zorunlu Açıklama
brand_name string Evet Marka adı (benzersiz olmalı)
category_ids array Evet İlişkili kategori ID'leri
logo string Hayır Logo dosya adı (opsiyonel). Sistem tarafında /dosya/marka/{logo} altında tutulur.
Request Body Örneği
{
  "brand_name": "Samsung Electronics",
  "category_ids": [1234, 5678, 91011],
  "logo": "samsung-logo.webp"
}
JavaScript Örneği
const axios = require('axios');

const createBrand = async (brandName, categoryIds, logoUrl = null) => {
  try {
    const requestBody = {
      brand_name: brandName,
      category_ids: categoryIds
    };

    if (logoUrl) {
      requestBody.logo = logoUrl;
    }

    const response = await axios.post(
      'https://idnsx.com/espazar/api/v1/brands',
      requestBody,
      {
        headers: {
          'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
          'Content-Type': 'application/json'
        }
      }
    );

    console.log('Marka başvurusu oluşturuldu!');
    console.log('Marka ID:', response.data.data.brand_id);
    console.log('Durum:', response.data.data.status);

    return response.data;
  } catch (error) {
    if (error.response.status === 409) {
      console.error('Bu marka adı zaten kullanılıyor!');
    } else {
      console.error('Hata:', error.response.data);
    }
  }
};

// Kullanım örneği
createBrand(
  'Samsung Electronics',
  [1234, 5678, 91011],
  'https://example.com/logos/samsung.jpg'
);
Response Örneği (Başarılı)
{
  "success": true,
  "timestamp": "2025-10-08 22:30:10",
  "request_id": "req_68e58db2e7f9a0b1",
  "data": {
    "brand_id": 115,
    "message": "Brand application submitted successfully. Waiting for admin approval.",
    "status": "pending_approval"
  },
  "message": "Brand application submitted successfully"
}
Hata Response Örnekleri

409 - Marka Adı Zaten Var

{
  "success": false,
  "error": {
    "message": "Brand name already exists for this seller",
    "code": "Conflict"
  }
}

400 - Geçersiz Kategori ID

{
  "success": false,
  "error": {
    "message": "Invalid category IDs",
    "code": "Bad Request"
  }
}
⚠️ Önemli Notlar
  • Benzersiz Marka Adı: Aynı satıcı için marka adı benzersiz olmalıdır.
  • Kategori Validasyonu: Kategori ID'leri sistemde mevcut olmalıdır, geçersiz ID'ler filtrelenir.
  • Otomatik Durum: Yeni markalar otomatik olarak "pending" (0) durumunda oluşturulur.
  • Admin Onayı: Marka kullanılabilir olmadan önce admin onayı gereklidir.

👁️ Marka Detayı

GET /api/v1/brands/{id}
Authorization: Bearer your_token

Belirli bir markanın detaylı bilgilerini getirir. Listeleme endpoint'inden farklı olarak ek detaylar içerir.

URL Parametreleri
Parametre Tip Açıklama
id integer Marka ID'si
JavaScript Örneği
const axios = require('axios');

const getBrandDetails = async (brandId) => {
  try {
    const response = await axios.get(
      `https://idnsx.com/espazar/api/v1/brands/${brandId}`,
      {
        headers: {
          'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
        }
      }
    );

    console.log('Marka Adı:', response.data.data.brand_name);
    console.log('Durum:', response.data.data.status);
    console.log('Kategoriler:', response.data.data.categories);
    console.log('Admin İşlemi:', response.data.data.last_admin_action);

    return response.data;
  } catch (error) {
    if (error.response.status === 404) {
      console.error('Marka bulunamadı veya erişim reddedildi!');
    } else {
      console.error('Hata:', error.response.data);
    }
  }
};

getBrandDetails(113);
cURL Örneği
curl -X 'GET' \
  'https://idnsx.com/espazar/api/v1/brands/113' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
  -H 'Accept: application/json'
Response Örneği (Başarılı)
{
  "success": true,
  "timestamp": "2025-10-08 22:45:20",
  "request_id": "req_68e591209f3a4b5c",
  "data": {
    "id": 113,
    "brand_name": "Samsung Electronics",
    "logo": "https://localhost/dosya/brands/samsung-logo.jpg",
    "categories": ["Elektronik", "Beyaz Eşya", "Akıllı Telefon"],
    "status": "active",
    "rejection_reason": null,
    "created_at": 1728411370,
    "updated_at": 1728414000,
    "last_admin_action": "Reviewed by admin"
  }
}

404 - Marka Bulunamadı

{
  "success": false,
  "error": {
    "message": "Brand not found",
    "code": "Not Found"
  }
}
⚠️ Önemli Notlar
  • Sahiplik Kontrolü: Sadece kendi markanıza ait detayları görebilirsiniz.
  • Ek Alan: last_admin_action alanı sadece detay endpoint'inde bulunur.
  • 404 Hatası: Marka bulunamazsa veya size ait değilse 404 döner.

✏️ Marka Güncelleme

PUT /api/v1/brands/{id}
Authorization: Bearer your_token

Sadece "pending" (onay bekleyen) durumundaki markalar güncellenebilir!

Active veya rejected durumundaki markaları güncellemeye çalışırsanız 400 hatası alırsınız.

Request Body Parametreleri (Tümü Opsiyonel)
Parametre Tip Zorunlu Açıklama
brand_name string Hayır Yeni marka adı (benzersiz olmalı)
category_ids array Hayır Güncel kategori ID'leri
logo string Hayır Yeni logo URL'si
Request Body Örneği
{
  "brand_name": "Samsung Electronics Turkey",
  "category_ids": [1234, 5678, 91011, 12131],
  "logo": "https://example.com/logos/samsung-updated.jpg"
}
JavaScript Örneği
const axios = require('axios');

const updateBrand = async (brandId, updates) => {
  try {
    const response = await axios.put(
      `https://idnsx.com/espazar/api/v1/brands/${brandId}`,
      updates,
      {
        headers: {
          'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
          'Content-Type': 'application/json'
        }
      }
    );

    console.log('Marka güncellendi!');
    console.log('Marka ID:', response.data.data.brand_id);

    return response.data;
  } catch (error) {
    if (error.response.status === 400) {
      console.error('Sadece pending markalar güncellenebilir!');
    } else if (error.response.status === 409) {
      console.error('Bu marka adı zaten kullanılıyor!');
    } else {
      console.error('Hata:', error.response.data);
    }
  }
};

// Kullanım örnekleri
// Sadece adı güncelle
updateBrand(113, {
  brand_name: 'Samsung Electronics Turkey'
});

// Sadece kategorileri güncelle
updateBrand(113, {
  category_ids: [1234, 5678, 91011]
});

// Tüm alanları güncelle
updateBrand(113, {
  brand_name: 'Samsung Electronics Turkey',
  category_ids: [1234, 5678, 91011],
  logo: 'https://example.com/logos/samsung-new.jpg'
});
Response Örneği (Başarılı)
{
  "success": true,
  "timestamp": "2025-10-08 23:00:15",
  "request_id": "req_68e594ff1a2b3c4d",
  "data": {
    "brand_id": 113,
    "message": "Brand updated successfully"
  },
  "message": "Brand updated successfully"
}
Hata Response Örnekleri

400 - Sadece Pending Markalar Güncellenebilir

{
  "success": false,
  "error": {
    "message": "Only pending brands can be updated",
    "code": "Bad Request"
  }
}

409 - Marka Adı Çakışması

{
  "success": false,
  "error": {
    "message": "Brand name already exists",
    "code": "Conflict"
  }
}

404 - Marka Bulunamadı

{
  "success": false,
  "error": {
    "message": "Brand not found or access denied",
    "code": "Not Found"
  }
}
⚠️ Önemli Notlar
  • Sadece Pending: Yalnızca "pending" (durum=0) markalar güncellenebilir.
  • Kısmi Güncelleme: Sadece değiştirmek istediğiniz alanları gönderin.
  • Marka Adı Benzersizliği: Yeni marka adı aynı satıcı için benzersiz olmalıdır.
  • Kategori Validasyonu: Geçersiz kategori ID'leri otomatik filtrelenir.
  • Otomatik Timestamp: son_islem_tarihi otomatik güncellenir.

🗑️ Marka Silme

DELETE /api/v1/brands/{id}
Authorization: Bearer your_token

Sadece "pending" durumundaki markalar silinebilir!

Bu işlem geri alınamaz. Onaylanmış veya reddedilmiş markaları silemezsiniz.

URL Parametreleri
Parametre Tip Açıklama
id integer Silinecek marka ID'si
JavaScript Örneği
const axios = require('axios');

const deleteBrand = async (brandId) => {
  // Onay iste
  const confirmed = confirm(`Marka ID ${brandId} silinecek. Emin misiniz?`);
  if (!confirmed) return;

  try {
    const response = await axios.delete(
      `https://idnsx.com/espazar/api/v1/brands/${brandId}`,
      {
        headers: {
          'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
        }
      }
    );

    console.log('Marka başarıyla silindi!');
    // 204 No Content döner, data olmaz

    return response;
  } catch (error) {
    if (error.response.status === 400) {
      console.error('Sadece pending markalar silinebilir!');
    } else if (error.response.status === 404) {
      console.error('Marka bulunamadı veya erişim reddedildi!');
    } else {
      console.error('Hata:', error.response.data);
    }
  }
};

deleteBrand(114);
cURL Örneği
curl -X 'DELETE' \
  'https://idnsx.com/espazar/api/v1/brands/114' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN'
Response Örneği (Başarılı)

HTTP Status: 204 No Content

Başarılı silme işleminde response body yoktur. Sadece 204 status kodu döner.

Hata Response Örnekleri

400 - Sadece Pending Markalar Silinebilir

{
  "success": false,
  "error": {
    "message": "Only pending brands can be deleted",
    "code": "Bad Request"
  }
}

404 - Marka Bulunamadı

{
  "success": false,
  "error": {
    "message": "Brand not found or access denied",
    "code": "Not Found"
  }
}
⚠️ Önemli Notlar
  • Sadece Pending: Yalnızca "pending" (durum=0) markalar silinebilir.
  • Geri Alınamaz: Silme işlemi kalıcıdır ve geri alınamaz.
  • 204 Response: Başarılı silme işlemi 204 No Content döner (body yok).
  • Onaylanmış Markalar: Active veya rejected markaları silemezsiniz.
  • Kullanıcı Onayı: Silme işleminden önce kullanıcıdan onay almanız önerilir.

📊 Marka Yönetimi Özeti

1

Marka Listeleme

GET /brands

Tüm markalarınızı listeleyin

2

Marka Oluştur

POST /brands

Yeni marka başvurusu yapın

3

Marka Detayı

GET /brands/{id}

Detaylı marka bilgisi

4

Marka Güncelle

PUT /brands/{id}

Pending markaları düzenleyin

5

Marka Sil

DELETE /brands/{id}

Pending markaları silin

💡 Marka Yaşam Döngüsü

Pending

Başvuru yapıldı

Admin İnceleme

Onay bekliyor

Active

Kullanıma hazır

Not: Pending aşamasında güncelleme ve silme yapabilirsiniz. Active veya rejected durumundaki markalarda değişiklik yapamazsınız.

Kategori Yönetimi

Kategori listesi ve hiyerarşik yapı için API endpoint'leri.

🔒 Read-Only API

Kategori API'si sadece okuma işlemlerini destekler. Kategori ekleme, güncelleme veya silme işlemleri yapılamaz. Tüm POST, PUT, PATCH ve DELETE istekleri 405 Method Not Allowed hatası döndürür.

Kategori Listeleme

Filtreleme, arama ve sayfalama ile kategori listesi

Hiyerarşik Ağaç

Tüm kategorilerin ağaç yapısında gösterimi

Kategori Detayı

Alt kategoriler ve SEO bilgileriyle detay

📊 Kategori Hiyerarşisi

Level 1 - Ana kategoriler (parent_id = 0)
Level 2 - Alt kategoriler
Level 3 - Alt-alt kategoriler

1. Kategori Listeleme

📝 Kategori Listeleme Nedir?

Platformdaki tüm kategorileri sayfalama, filtreleme ve arama özellikleriyle listeler. Ana kategoriler, alt kategoriler veya belirli bir kategorinin çocukları listelenebilir.

📌 API Endpoint

GET https://idnsx.com/espazar/api/v1/categories
Authorization: Bearer {token}

🔍 Query Parametreleri

Parametre Tip Zorunlu Açıklama
page integer Hayır Sayfa numarası (varsayılan: 1)
per_page integer Hayır Sayfa başına kayıt (varsayılan: 50, max: 100)
parent_id integer Hayır Üst kategori ID (0 = ana kategoriler)
level integer Hayır Kategori seviyesi (1, 2 veya 3)
search string Hayır Kategori adında arama terimi

💻 JavaScript Örneği (Axios)

// Tüm ana kategorileri listele
const response = await axios.get('https://idnsx.com/espazar/api/v1/categories', {
  params: {
    page: 1,
    per_page: 50,
    parent_id: 0,  // Ana kategoriler
    level: 1        // Level 1 kategoriler
  },
  headers: {
    'Authorization': `Bearer ${accessToken}`
  }
});

console.log('Kategoriler:', response.data.data.categories);
console.log('Toplam:', response.data.data.meta.total);

// Belirli bir kategorinin alt kategorilerini listele
const subCategories = await axios.get('https://idnsx.com/espazar/api/v1/categories', {
  params: { parent_id: 137 },  // ID'si 137 olan kategorinin çocukları
  headers: { 'Authorization': `Bearer ${accessToken}` }
});

// Kategori ara
const searchResult = await axios.get('https://idnsx.com/espazar/api/v1/categories', {
  params: { search: 'telefon' },
  headers: { 'Authorization': `Bearer ${accessToken}` }
});

🔧 cURL Örneği

curl -X GET "https://idnsx.com/espazar/api/v1/categories?page=1&per_page=50&parent_id=0&level=1" \
  -H "Authorization: Bearer YOUR_TOKEN_HERE" \
  -H "Accept: application/json"

✅ Response Örneği (200 OK)

{
  "success": true,
  "timestamp": "2025-10-07 09:35:20",
  "request_id": "req_68e4c37c5eaa12.20836111",
  "data": {
    "categories": [
      {
        "id": 137,
        "name": "Cep Telefonu",
        "parent_id": 0,
        "parent_name": null,
        "order": 1,
        "commission_rate": 5.5,
        "seo": {
          "title": "Cep Telefonu Kategorisi",
          "keyword": "cep telefonu, akıllı telefon",
          "description": "En iyi cep telefonları"
        },
        "images": {
          "icon": "https://localhost/dosya/icon.png",
          "image": "https://localhost/dosya/category.jpg"
        },
        "features": {
          "show_on_homepage": true,
          "has_legal_warning": false,
          "installment_available": true
        },
        "stats": {
          "child_count": 5,
          "product_count": 1250
        },
        "created_at": 1728307200,
        "updated_at": 1728307200
      }
    ],
    "meta": {
      "total": 150,
      "page": 1,
      "per_page": 50,
      "total_pages": 3,
      "has_next": true,
      "has_prev": false
    }
  }
}

📋 Response Alanları Açıklaması

id Kategori benzersiz ID'si
name Kategori adı (kategori_adi)
parent_id Üst kategori ID'si (0 = ana kategori)
parent_name Üst kategori adı (null ise ana kategori)
order Sıralama değeri (küçükten büyüğe)
commission_rate Komisyon oranı (% olarak, örn: 5.5)
seo SEO bilgileri (title, keyword, description)
images Kategori görselleri (icon ve image, mutlak URL)
features Özellikler (anasayfa gösterim, yasal uyarı, taksit durumu)
stats İstatistikler (alt kategori sayısı, ürün sayısı)
created_at Oluşturma tarihi (kayit_tarihi)
updated_at Son güncelleme tarihi (son_islem_tarihi)

💡 Önemli Notlar

  • Read-Only: Bu API sadece okuma işlemi yapar, yazma yapamaz
  • parent_id = 0: Ana kategorileri filtreler
  • level parametresi: 1, 2 veya 3 olarak kategori seviyelerini filtreler
  • search: Kategori adında LIKE arama yapar (kategori_adi)
  • Görseller: Mutlak URL döner (https://localhost/dosya/)
  • installment_available: taksit_durum = 1 ise false (ters mantık)
  • child_count: Direkt alt kategorilerin sayısı (torunlar dahil değil)
  • product_count: O kategoriye ait ürün sayısı (ana_kategori_id)

2. Kategori Ağacı (Hiyerarşik Yapı)

🌳 Kategori Ağacı Nedir?

Tüm kategorileri hiyerarşik ağaç yapısında döndürür. Ana kategoriler altında alt kategoriler, onların altında torun kategoriler şeklinde iç içe geçmiş yapı. Sayfalama yapmaz, tüm kategorileri tek seferde getirir.

📌 API Endpoint

GET https://idnsx.com/espazar/api/v1/categories/tree
Authorization: Bearer {token}

🔍 Query Parametreleri

Bu endpoint parametre almaz. Tüm kategorileri ağaç yapısında döndürür.

💻 JavaScript Örneği (Axios)

// Tüm kategori ağacını getir
const response = await axios.get('https://idnsx.com/espazar/api/v1/categories/tree', {
  headers: {
    'Authorization': `Bearer ${accessToken}`
  }
});

console.log('Kategori Ağacı:', response.data.data.category_tree);
console.log('Toplam Kategori:', response.data.data.total_categories);

// Kategorileri recursive olarak işle
function processCategoryTree(categories, level = 0) {
  categories.forEach(category => {
    console.log(`${'  '.repeat(level)}${category.name} (ID: ${category.id})`);

    if (category.children && category.children.length > 0) {
      processCategoryTree(category.children, level + 1);
    }
  });
}

processCategoryTree(response.data.data.category_tree);

🔧 cURL Örneği

curl -X GET "https://idnsx.com/espazar/api/v1/categories/tree" \
  -H "Authorization: Bearer YOUR_TOKEN_HERE" \
  -H "Accept: application/json"

✅ Response Örneği (200 OK)

{
  "success": true,
  "timestamp": "2025-10-07 09:35:20",
  "request_id": "req_68e4c37c5eaa12.20836111",
  "data": {
    "category_tree": [
      {
        "id": 137,
        "name": "Elektronik",
        "order": 1,
        "commission_rate": 5.5,
        "show_on_homepage": true,
        "images": {
          "icon": "https://localhost/dosya/icon.png",
          "image": "https://localhost/dosya/category.jpg"
        },
        "children": [
          {
            "id": 138,
            "name": "Cep Telefonu",
            "order": 1,
            "commission_rate": 6.0,
            "show_on_homepage": true,
            "images": {
              "icon": null,
              "image": null
            },
            "children": [
              {
                "id": 139,
                "name": "Akıllı Telefonlar",
                "order": 1,
                "commission_rate": 6.5,
                "show_on_homepage": false,
                "images": {
                  "icon": null,
                  "image": null
                },
                "children": []
              }
            ]
          }
        ]
      }
    ],
    "total_categories": 150
  }
}

📋 Response Alanları Açıklaması

category_tree Ana kategorilerin dizisi (parent_id = 0)
id Kategori benzersiz ID'si
name Kategori adı (kategori_adi)
order Sıralama değeri (sira)
commission_rate Komisyon oranı (% olarak)
show_on_homepage Anasayfada gösterim durumu (anasayfa_gosterim)
images Kategori görselleri (icon ve image, mutlak URL)
children Alt kategorilerin dizisi (recursive yapı)
total_categories Sistemdeki toplam kategori sayısı

💡 Önemli Notlar

  • Tüm kategoriler: Tek seferde tüm kategorileri döndürür (sayfalama yok)
  • Recursive yapı: children alanı iç içe geçmiş kategorileri içerir
  • Performans: Çok sayıda kategori varsa yavaş olabilir
  • Boş children: Alt kategorisi olmayan kategorilerde [] (boş dizi)
  • Sıralama: parent_id ASC, sira ASC, kategori_adi ASC
  • Kullanım alanı: Mega menü, kategori seçici, navigasyon için ideal
  • Basit yapı: SEO, features, stats gibi detaylar yok (sadece temel bilgiler)

3. Kategori Attribute & Varyant Sözlüğü

🎯 Amaç

Belirli bir kategoriye admin panelinden bağlanan varyant ve filtreleri, bunlara ait tüm seçenekleriyle (alt varyantlar ve filtre_ozellik kayıtları) birlikte döner. Böylece entegratör, satıcının panelinde gördüğü kombinasyonları API üzerinden de aynı ID'lerle kurabilir.

📌 API Endpoint

GET https://idnsx.com/espazar/api/v1/categories/{id}/attributes
Authorization: Bearer {token}

🔍 Kullanım: Önce kategori seçin, ardından bu endpoint ile o kategoriye bağlı tüm varyant ve filtre ID'lerini ve insan-okunur isimlerini alın.

✅ Response Örneği (özet)

{
  "success": true,
  "timestamp": "2025-12-01 12:00:00",
  "request_id": "req_...",
  "data": {
    "category_id": 137,
    "variants": [
      {
        "id": 1,
        "name": "Renk",
        "system_name": "Ana Renk",
        "is_color": true,
        "options": [
          { "id": 60, "name": "Beyaz" },
          { "id": 61, "name": "Beyaz - Siyah" }
        ]
      }
    ],
    "filters": [
      {
        "id": 870,
        "name": "Materyal",
        "system_name": "Kadın T-Shirt Materyal",
        "options": [
          { "id": 7865, "name": "%100 Organik Pamuk" },
          { "id": 7866, "name": "%100 Pamuk" }
        ]
      }
    ]
  }
}

🔁 Önerilen Akış

  • 1. İlgili kategoriyi seçtikten sonra GET /categories/{id}/attributes çağrısını yapın.
  • 2. Dönen variants ve filters dizilerini kendi panelinizde seçenek listeleri olarak gösterin.
  • 3. Kullanıcı seçim yaptığında, seçilen öğelerin id değerlerini ürün/varyant oluşturma isteklerinde kullanın (örneğin attributes alanında).
  • 4. Böylece admin panelindeki varyant/filtre kurgusu ile entegrasyon tarafındaki yapı bire bir aynı kalır.

3. Kategori Detayı

📄 Kategori Detayı Nedir?

Belirli bir kategorinin tüm detaylı bilgilerini getirir. Kategori yolu (breadcrumb), alt kategoriler, SEO bilgileri, varyant/filtre yapılandırması dahil. Kategori detay sayfası veya ürün ekleme formları için kullanılır.

📌 API Endpoint

GET https://idnsx.com/espazar/api/v1/categories/{id}
Authorization: Bearer {token}

🔗 URL Parametreleri

Parametre Tip Zorunlu Açıklama
id integer Evet Kategori ID'si (örn: 1751)

💻 JavaScript Örneği (Axios)

// Kategori detayını getir
const categoryId = 1751;
const response = await axios.get(`https://idnsx.com/espazar/api/v1/categories/${categoryId}`, {
  headers: {
    'Authorization': `Bearer ${accessToken}`
  }
});

const category = response.data.data;
console.log('Kategori:', category.name);
console.log('Yol:', category.path.map(p => p.name).join(' > '));
console.log('Alt Kategoriler:', category.subcategories);
console.log('Varyantlar:', category.configuration.variants);

// Hata kontrolü
try {
  const response = await axios.get(`https://idnsx.com/espazar/api/v1/categories/99999`, {
    headers: { 'Authorization': `Bearer ${accessToken}` }
  });
} catch (error) {
  if (error.response?.status === 404) {
    console.error('Kategori bulunamadı');
  }
}

🔧 cURL Örneği

curl -X GET "https://idnsx.com/espazar/api/v1/categories/1751" \
  -H "Authorization: Bearer YOUR_TOKEN_HERE" \
  -H "Accept: application/json"

✅ Response Örneği (200 OK)

{
  "success": true,
  "timestamp": "2025-10-07 09:38:36",
  "request_id": "req_68e4c37c5eaa12.20836111",
  "data": {
    "id": 1751,
    "name": "Külçe Gümüş",
    "path": [
      {"id": 1625, "name": "Altın & Gümüş"},
      {"id": 1744, "name": "Yatırımlık Gümüş"},
      {"id": 1751, "name": "Külçe Gümüş"}
    ],
    "parent_id": 1744,
    "parent_name": "Yatırımlık Gümüş",
    "order": 0,
    "commission_rate": 6.5,
    "seo": {
      "title": "Külçe Gümüş",
      "keyword": "Külçe Gümüş, Gümüş, Yatırımlık Gümüş...",
      "description": "EsnafPazar'da gümüşle yatırımınızı şekillendirin!...",
      "tags": "Külçe Gümüş, Gümüş, Yatırımlık Gümüş..."
    },
    "images": {
      "icon": null,
      "image": null
    },
    "features": {
      "show_on_homepage": false,
      "has_legal_warning": false,
      "installment_available": false
    },
    "configuration": {
      "variants": [],
      "filters": ["616"]
    },
    "stats": {
      "child_count": 0,
      "product_count": 0
    },
    "subcategories": [],
    "created_at": "1713262225",
    "updated_at": "1735898893"
  }
}

❌ Hata Response Örneği (404)

{
  "success": false,
  "timestamp": "2025-10-07 09:40:12",
  "request_id": "req_68e4c47d2b8a45.12345678",
  "error": {
    "message": "Category not found",
    "code": "Not Found"
  }
}

📋 Response Alanları Açıklaması

id Kategori benzersiz ID'si
name Kategori adı (kategori_adi)
path Kategori yolu (breadcrumb) - üstten alta doğru tüm kategoriler
parent_id Üst kategori ID'si
parent_name Üst kategori adı
order Sıralama değeri (sira)
commission_rate Komisyon oranı (% olarak, komisyon)
seo SEO bilgileri (title, keyword, description, tags/etiket)
images Kategori görselleri (icon, image - mutlak URL veya null)
features Özellikler (show_on_homepage, has_legal_warning, installment_available)
configuration Varyant ID'leri (varyant) ve filtre ID'leri (filtre) dizileri
stats İstatistikler (child_count, product_count)
subcategories Direkt alt kategorilerin detaylı listesi (id, name, order, commission_rate, images, product_count)
created_at Oluşturma tarihi - UNIX timestamp (kayit_tarihi)
updated_at Son güncelleme tarihi - UNIX timestamp (son_islem_tarihi)

💡 Önemli Notlar

  • path: Breadcrumb için kullanılır, en üst kategoriden başlayıp seçili kategoriye kadar
  • subcategories: Sadece direkt alt kategorileri gösterir (torunları değil)
  • configuration.variants: Virgülle ayrılmış varyant ID'leri dizisi (explode edilmiş)
  • configuration.filters: Virgülle ayrılmış filtre ID'leri dizisi
  • 404 Hatası: Kategori bulunamazsa "Category not found" hatası döner
  • Tarih formatı: created_at ve updated_at UNIX timestamp formatında
  • Boş alanlar: images null olabilir, subcategories boş dizi [] olabilir
  • Kullanım alanı: Kategori detay sayfası, ürün ekleme formu, breadcrumb

Raporlama

Satıcıların işletme performansını analiz etmeleri için kapsamlı raporlama API'leri.

🔒 Read-Only API

Raporlama API'si sadece okuma işlemlerini destekler. Tüm POST, PUT, PATCH ve DELETE istekleri 405 Method Not Allowed hatası döndürür.

Satış Raporu

Sipariş, gelir ve ürün bazlı satış analizi

Ürün Performansı

Ürün bazlı satış, stok ve dönüşüm analizi

Stok Raporu

Stok seviyeleri, değeri ve uyarılar

Finansal Rapor

Gelir, komisyon, bakiye ve kar/zarar

1. Satış Raporu

📊 Satış Raporu Nedir?

Belirli bir tarih aralığında satıcının sipariş ve gelir performansını analiz eder. Günlük satış trendleri, en çok satan ürünler ve sipariş durumlarını içerir.

📌 API Endpoint

GET https://idnsx.com/espazar/api/v1/reports/sales
Authorization: Bearer {token}

🔍 Query Parametreleri

Parametre Tip Zorunlu Açıklama
start_date string Hayır Başlangıç tarihi YYYY-MM-DD (varsayılan: 30 gün önce)
end_date string Hayır Bitiş tarihi YYYY-MM-DD (varsayılan: bugün)

💻 JavaScript Örneği (Axios)

// Son 30 günün satış raporu
const response = await axios.get('https://idnsx.com/espazar/api/v1/reports/sales', {
  headers: {
    'Authorization': `Bearer ${accessToken}`
  }
});

// Belirli tarih aralığı
const reportWithDates = await axios.get('https://idnsx.com/espazar/api/v1/reports/sales', {
  params: {
    start_date: '2025-01-01',
    end_date: '2025-01-31'
  },
  headers: { 'Authorization': `Bearer ${accessToken}` }
});

console.log('Toplam Sipariş:', response.data.data.summary.total_orders);
console.log('Toplam Gelir:', response.data.data.summary.total_revenue);
console.log('Günlük Satışlar:', response.data.data.daily_sales);
console.log('En Çok Satan Ürünler:', response.data.data.top_products);

🔧 cURL Örneği

curl -X GET "https://idnsx.com/espazar/api/v1/reports/sales?start_date=2025-01-01&end_date=2025-01-31" \
  -H "Authorization: Bearer YOUR_TOKEN_HERE" \
  -H "Accept: application/json"

✅ Response Yapısı

period: Rapor tarih aralığı (start_date, end_date)

summary: total_orders, completed_orders, cancelled_orders, total_revenue, average_order_value, net_profit

daily_sales: Günlük bazda satış verileri dizisi (date, orders, revenue)

top_products: En çok satan 10 ürün (product_id, name, sku, quantity_sold, revenue)

2. Ürün Performans Raporu

📦 Ürün Performansı Nedir?

Tüm ürünlerin satış performansını, stok durumunu ve dönüşüm oranlarını analiz eder.

📌 API Endpoint

GET https://idnsx.com/espazar/api/v1/reports/products

Parametre: Bu endpoint parametre almaz, tüm ürünleri döndürür.

💻 Kullanım Örneği

const report = await axios.get('https://idnsx.com/espazar/api/v1/reports/products', {
  headers: { 'Authorization': `Bearer ${accessToken}` }
});

summary: total_products, total_revenue, total_quantity_sold, average_conversion_rate

products: Ürün listesi - her ürün için: product_id, name, sku, price, current_stock, total_sold, total_revenue, view_count, conversion_rate

3. Stok Raporu

📦 Stok Raporu Nedir?

Tüm ürünlerin stok seviyelerini, stok değerini ve uyarıları analiz eder.

📌 API Endpoint

GET https://idnsx.com/espazar/api/v1/reports/stock

Parametre: Bu endpoint parametre almaz.

💻 Kullanım Örneği

const report = await axios.get('https://idnsx.com/espazar/api/v1/reports/stock', {
  headers: { 'Authorization': `Bearer ${accessToken}` }
});

threshold: Satıcının stok uyarı eşiği (stok_uyari_tabani)

summary: total_products, in_stock, low_stock, out_of_stock, total_stock_value

stock_data: Ürün listesi - her ürün için: product_id, name, sku, current_stock, status (in_stock/low_stock/out_of_stock), stock_value, estimated_days_remaining

4. Finansal Rapor

💰 Finansal Rapor Nedir?

Belirli bir tarih aralığında satıcının gelir, gider, komisyon ve bakiye bilgilerini analiz eder.

📌 API Endpoint

GET https://idnsx.com/espazar/api/v1/reports/financial

🔍 Query Parametreleri

Parametre Tip Zorunlu Açıklama
start_date string Hayır Başlangıç tarihi YYYY-MM-DD (varsayılan: 30 gün önce)
end_date string Hayır Bitiş tarihi YYYY-MM-DD (varsayılan: bugün)

💻 Kullanım Örneği

const report = await axios.get('https://idnsx.com/espazar/api/v1/reports/financial', {
  params: {
    start_date: '2025-01-01',
    end_date: '2025-01-31'
  },
  headers: { 'Authorization': `Bearer ${accessToken}` }
});

period: Rapor tarih aralığı (start_date, end_date)

financial_summary: gross_revenue, sales_revenue, shipping_revenue, net_earnings, platform_commission, payment_commission, shipping_support

order_summary: invoiced_orders, uninvoiced_orders, total_orders

balance_info: current_balance (kasa), pending_payments, available_balance

💡 Önemli Notlar

  • Read-Only: Tüm raporlar sadece GET metodunu destekler
  • Tarih Formatı: YYYY-MM-DD (örn: 2025-01-31)
  • Varsayılan Aralık: Tarih belirtilmezse son 30 gün
  • Tarih Validasyonu: start_date, end_date'ten sonra olamaz (400 hatası döner)
  • Gerçek Zamanlı: Tüm raporlar güncel verileri içerir
  • Satıcı Bazlı: Her satıcı sadece kendi verilerini görebilir

Webhook Yönetimi

Gerçek zamanlı bildirimler için webhook sistemi. Sipariş, ürün ve stok değişikliklerini anında bildirim olarak alabilirsiniz.

Desteklenen Event'ler

order.created - Yeni sipariş
order.updated - Sipariş güncellendi
order.cancelled - Sipariş iptal
order.paid - Sipariş ödendi
product.updated - Ürün güncellendi
stock.low - Stok azaldı

Webhook Oluşturma

Webhook Aboneliği Oluştur

POST /api/v1/webhooks
Authorization: Bearer your_token
{
  "url": "https://yourapp.com/webhook",
  "events": ["order.created", "order.updated", "product.updated"],
  "secret": "your_webhook_secret",
  "active": true
}

Webhook Listeleme

Webhook Aboneliklerini Listele

GET /api/v1/webhooks
Authorization: Bearer your_token

Webhook Güncelleme

Webhook Güncelle

PUT /api/v1/webhooks/{id}
Authorization: Bearer your_token
{
  "url": "https://yourapp.com/new-webhook",
  "events": ["order.created", "order.shipped"],
  "active": true
}

Webhook Silme

Webhook Sil

DELETE /api/v1/webhooks/{id}
Authorization: Bearer your_token

Webhook Payload Örneği

Gelen Webhook Verisi

Headers:

Content-Type: application/json
X-Webhook-Secret: your_webhook_secret
X-Webhook-Event: order.created
{
  "event": "order.created",
  "timestamp": "2025-01-15 10:30:00",
  "seller_id": 123,
  "data": {
    "order_id": "ORD-2025-12345",
    "order_number": "ORD-2025-12345",
    "status": "pending",
    "total": 24229.99,
    "customer": {
      "name": "Ahmet Yılmaz",
      "email": "ahmet@example.com"
    }
  }
}

Kod Örnekleri

Webhook Oluşturma (JavaScript)

const webhook = await axios.post('/api/v1/webhooks', {
  url: 'https://yourapp.com/webhook',
  events: ['order.created', 'order.updated', 'product.updated'],
  secret: 'your_webhook_secret',
  active: true
}, {
  headers: { 'Authorization': `Bearer ${accessToken}` }
});

// Response: { success: true, data: { webhook_id: 123, message: "Webhook subscription created successfully" } }

Webhook Listeleme (JavaScript)

const webhooks = await axios.get('/api/v1/webhooks', {
  headers: { 'Authorization': `Bearer ${accessToken}` }
});

// Response: { success: true, data: { webhooks: [...] } }

Webhook Güncelleme (JavaScript)

const updatedWebhook = await axios.put(`/api/v1/webhooks/${webhookId}`, {
  events: ['order.created', 'order.shipped'],
  active: true
}, {
  headers: { 'Authorization': `Bearer ${accessToken}` }
});

// Response: { success: true, data: { message: "Webhook updated successfully" } }

Webhook Silme (JavaScript)

const deletedWebhook = await axios.delete(`/api/v1/webhooks/${webhookId}`, {
  headers: { 'Authorization': `Bearer ${accessToken}` }
});

// Response: { success: true, data: { message: "Webhook deleted successfully" } }

Önemli Notlar

  • • Webhook URL'si HTTPS olmalıdır (güvenlik için)
  • X-Webhook-Secret header'ını kontrol edin
  • X-Webhook-Event header'ı ile event türünü belirleyin
  • • Webhook'lar 10 saniye timeout ile gönderilir
  • • Başarısız webhook'lar otomatik olarak takip edilir
  • • Webhook'lar asenkron olarak gönderilir

Hata Yönetimi

HTTP Status Kodları

Kod Anlam Açıklama
200OKBaşarılı
201CreatedOluşturuldu
204No Contentİçerik yok
400Bad RequestGeçersiz istek
401UnauthorizedYetkilendirme hatası
403ForbiddenYasak
404Not FoundBulunamadı
429Too Many RequestsÇok fazla istek
500Internal Server ErrorSunucu hatası

Hata Yanıt Örneği

Hata Yanıt Örneği
{
  "success": false,
  "timestamp": "2025-10-06 18:30:00",
  "request_id": "req_xxx",
  "error": {
    "message": "Authentication required",
    "code": "Unauthorized"
  }
}

Rate Limiting

Rate Limit Bilgileri

Limit: 1000 istek/saat (satıcı bazlı)

Sıfırlama: Her saat başı

Response Headers

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 950
X-RateLimit-Reset: 1640995200

Kod Örnekleri

PHP ile Token Alma ve Ürün Listeleme

<?php
// Token alma
$tokenResponse = file_get_contents('https://idnsx.com/espazar/api/v1/auth/token', false,
    stream_context_create([
        'http' => [
            'method' => 'POST',
            'header' => 'Content-Type: application/json',
            'content' => json_encode([
                'api_key' => 'YOUR_API_KEY',
                'api_secret' => 'YOUR_API_SECRET'
            ])
        ]
    ]));

$tokenData = json_decode($tokenResponse, true);
$accessToken = $tokenData['data']['access_token'];

// Ürünleri listeleme
$context = stream_context_create([
    'http' => [
        'header' => "Authorization: Bearer $accessToken"
    ]
]);

$products = file_get_contents('https://idnsx.com/espazar/api/v1/products/', false, $context);
echo $products;
?>

Python Örneği

import requests

# Token alma
token_response = requests.post('https://idnsx.com/espazar/api/v1/auth/token', json={
    'api_key': 'YOUR_API_KEY',
    'api_secret': 'YOUR_API_SECRET'
})

access_token = token_response.json()['data']['access_token']

# Ürünleri listeleme
headers = {'Authorization': f'Bearer {access_token}'}
products = requests.get('https://idnsx.com/espazar/api/v1/products/', headers=headers)
print(products.json())

JavaScript (Node.js) Örneği

const axios = require('axios');

// Token alma
const tokenResponse = await axios.post('https://idnsx.com/espazar/api/v1/auth/token', {
    api_key: 'YOUR_API_KEY',
    api_secret: 'YOUR_API_SECRET'
});

const accessToken = tokenResponse.data.data.access_token;

// Ürünleri listeleme
const productsResponse = await axios.get('https://idnsx.com/espazar/api/v1/products/', {
    headers: {
        'Authorization': `Bearer ${accessToken}`
    }
});

console.log(productsResponse.data);

Ürün Yönetimi Örnekleri

Ürün Oluşturma (JavaScript)

// Yeni ürün oluşturma
const newProduct = await axios.post('https://idnsx.com/espazar/api/v1/products', {
    title: 'Samsung Galaxy S24',
    description: 'Yeni nesil akıllı telefon',
    category_id: 137,
    price: 25999.99,
    market_price: 27999.99,
    sku: 'PROD-12345',
    barcode: '8690123456789'
}, {
    headers: {
        'Authorization': `Bearer ${accessToken}`,
        'Content-Type': 'application/json'
    }
});

console.log('Yeni ürün oluşturuldu:', newProduct.data);
// Response: { success: true, data: { product_id: 12345, message: "Product created successfully" } }

Ürün Varyantlarını Listeleme

// Ürün varyantlarını listeleme
const variants = await axios.get(`https://idnsx.com/espazar/api/v1/products/${productId}/variants`, {
    headers: {
        'Authorization': `Bearer ${accessToken}`
    }
});

console.log('Varyantlar:', variants.data);
// Response: { success: true, data: { variants: [...] } }

Ürün Varyantı Oluşturma

// Ürün varyantı oluşturma
const variant = await axios.post(`https://idnsx.com/espazar/api/v1/products/${productId}/variants`, {
    attributes: {
        "1": 5,  // Renk: Mavi
        "2": 8   // Boyut: 128GB
    },
    price: 25999.99,
    market_price: 27999.99,
    stock_quantity: 50
}, {
    headers: {
        'Authorization': `Bearer ${accessToken}`,
        'Content-Type': 'application/json'
    }
});

console.log('Varyant oluşturuldu:', variant.data);
// Response: { success: true, data: { variant_id: 1, stock_code: "SKU-12345-abc123", message: "Product variant created successfully" } }

Stok Güncelleme

// Stok güncelleme
const stockUpdate = await axios.post(`https://idnsx.com/espazar/api/v1/products/${productId}/stock`, {
    main_stock: 100,
    variants: [
        {
            stock_code: "SKU123",
            stock_quantity: 50,
            price: 25999.99,
            market_price: 27999.99
        }
    ],
    bulk_update: [
        {
            stock_code: "SKU456",
            stock_quantity: 25,
            operation: "add"
        }
    ]
}, {
    headers: {
        'Authorization': `Bearer ${accessToken}`,
        'Content-Type': 'application/json'
    }
});

console.log('Stok güncellendi:', stockUpdate.data);
// Response: { success: true, data: { message: "Stock updated successfully", product_id: 12345, updated_at: 1728307200 } }

Resim Yükleme (FormData)

// Resim yükleme
const FormData = require('form-data');
const fs = require('fs');

const form = new FormData();
form.append('image', fs.createReadStream('product-image.jpg'));
form.append('is_main', 'true');
form.append('sort_order', '1');

const imageUpload = await axios.post(`https://idnsx.com/espazar/api/v1/products/${productId}/images`, form, {
    headers: {
        'Authorization': `Bearer ${accessToken}`,
        ...form.getHeaders()
    }
});

console.log('Resim yüklendi:', imageUpload.data);
// Response: { success: true, data: { image_id: 1, image_url: "product_12345_abc123.jpg", is_main: true, sort_order: 1, message: "Image uploaded successfully" } }

Toplu Ürün Güncelleme

// Toplu ürün güncelleme
const bulkUpdate = await axios.post('https://idnsx.com/espazar/api/v1/products/bulk-update', {
    update_fields: ['product_name', 'price', 'market_price'],
    products: [
        {
            product_id: 12345,
            product_name: 'Güncellenmiş Ürün Adı',
            price: 299.99,
            market_price: 399.99
        },
        {
            product_id: 12346,
            product_name: 'Başka Ürün',
            price: 199.99
        }
    ]
}, {
    headers: {
        'Authorization': `Bearer ${accessToken}`,
        'Content-Type': 'application/json'
    }
});

console.log('Toplu güncelleme tamamlandı:', bulkUpdate.data);
// Response: { success: true, data: { message: "Bulk update completed", results: { success: 2, errors: 0, total: 2, details: [...] } } }