T-SOFT/Storefront API/Sepet

Sepet

Yetki:storefront:account (üye) veya storefront:cart (misafir) — uygulama token'ı yetmez. Token almak için Kimlik Doğrulama, hata gövdelerinin biçimi için Genel Bakış.

Oturum sahibinin sepetini okur ve yönetir: sepet dokümanı (cart) ile satır işlemleri (cart-items). Üye müşteri token'ı (storefront:account) veya misafir sepet token'ı (storefront:cart) gerekir — iki kimlik de aynı yanıt şeklini alır. Misafir token'ı edinme ve girişte sepet birleşmesi için Misafir Sepeti sayfasına bak. Fiyat alanları Money şemasıyla döner.

Sepeti okuma

GET /cart

curl "https://<domain>/api/v3/storefront/2026-01/cart" \
  -H "Accept: application/vnd.api+json" \
  -H "Authorization: Bearer <access_token>"
{
  "data": {
    "type": "carts",
    "id": "me",
    "attributes": {
      "totalQuantity": 3,
      "subtotal": { "amount": "300.00", "currencyCode": "TRY", "decimalPlaces": 2 }
    },
    "relationships": {
      "items": {
        "data": [{ "type": "cart-items", "id": "57" }]
      }
    }
  },
  "included": [
    {
      "type": "cart-items",
      "id": "57",
      "attributes": {
        "productId": 123,
        "variantId": null,
        "quantity": 3,
        "productName": "Kırmızı Elbise",
        "image": "https://cdn.example.com/Data/K/urun.jpg",
        "availableForSale": true,
        "unitPrice": { "amount": "100.00", "currencyCode": "TRY", "decimalPlaces": 2 },
        "lineTotal": { "amount": "300.00", "currencyCode": "TRY", "decimalPlaces": 2 },
        "vatRate": 20,
        "orderNote": null,
        "giftNote": null,
        "giftPackage": false
      }
    }
  ]
}
  • data.id her zaman "me"'dir — sepet, token'ın sahibine göre çözülür; path'te sepet id'si yoktur.
  • data.attributes her zaman totalQuantity ve subtotal taşır; mağaza yapılandırmasına göre sepet fiyat alanları ve aktif kampanyalar da eklenir.
  • Boş sepet: totalQuantity: 0, subtotal.amount: "0.00", relationships.items.data: [], included: []; fiyat alanlarının ve kampanyaların hiçbiri dönmez.

Sepeti boşaltma

DELETE /cart

curl -X DELETE "https://<domain>/api/v3/storefront/2026-01/cart" \
  -H "Accept: application/vnd.api+json" \
  -H "Authorization: Bearer <access_token>"

Yanıt 200 — boşaltılmış sepet dokümanı döner (204 değil): totalQuantity: 0, included: []. Yalnızca token sahibinin satırları silinir.

Satır ekleme

POST /cart-items

İstek gövdesi düz JSON'dur (JSON:API data sarmalaması yok):

curl -X POST "https://<domain>/api/v3/storefront/2026-01/cart-items" \
  -H "Accept: application/vnd.api+json" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <access_token>" \
  -d '{ "productId": 123, "variantId": 45, "quantity": 2 }'

Yanıt 201 Created — güncel sepet dokümanının tamamı + meta.affectedItemId:

{
  "data": { "type": "carts", "id": "me", "attributes": { "totalQuantity": 2, "subtotal": { "amount": "100.00", "currencyCode": "TRY", "decimalPlaces": 2 } }, "relationships": { "items": { "data": [{ "type": "cart-items", "id": "57" }] } } },
  "included": [ { "type": "cart-items", "id": "57", "attributes": { "productId": 123, "variantId": 45, "quantity": 2, "productName": "Kırmızı Elbise", "image": "https://cdn.example.com/Data/K/urun.jpg", "availableForSale": true, "unitPrice": { "amount": "50.00", "currencyCode": "TRY", "decimalPlaces": 2 }, "lineTotal": { "amount": "100.00", "currencyCode": "TRY", "decimalPlaces": 2 }, "vatRate": 20, "orderNote": null, "giftNote": null, "giftPackage": false } } ],
  "meta": { "affectedItemId": "57" }
}
AlanTipKural
productIdintZorunlu, en az 1
variantIdintVaryantlı üründe zorunlu, varyantsızda gönderilmez; en az 1
quantityintZorunlu, 1–100000
  • Sepette aynı ürün/varyant satırı zaten varsa adet toplanır (2 + 3 → 5), yeni satır açılmaz; meta.affectedItemId aynı satırı gösterir.
  • meta.affectedItemId string'dir ve eklenen/güncellenen satırın included[].id değeriyle eşleşir.

Satır güncelleme

PATCH /cart-items/{itemId}

curl -X PATCH "https://<domain>/api/v3/storefront/2026-01/cart-items/57" \
  -H "Accept: application/vnd.api+json" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <access_token>" \
  -d '{ "quantity": 5 }'

Yanıt 200 — güncel sepet dokümanı (bu uçta meta yoktur). quantity mutlak değer olarak yazılır, artırım yapmaz. Kural: zorunlu, tam sayı, 1–100000.

Satır notları

PATCH /cart-items/{itemId}/notes

Sipariş notu, hediye notu ve hediye paketi tercihi satır bazında tutulur. Alanlar tek tek gönderilebilir; istekte yer almayan not olduğu gibi kalır.

curl -X PATCH "https://<domain>/api/v3/storefront/2026-01/cart-items/57/notes" \
  -H "Accept: application/vnd.api+json" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <access_token>" \
  -d '{"orderNote": "Kapıya bırakmayın", "giftPackage": true}'

Yanıt, güncellenmiş sepetin tamamıdır — satır notları included[] içindeki cart-items kaydında döner.

AlanTipKural
orderNotestring | nullSiparişe iliştirilen not; not yoksa null
giftNotestring | nullHediye notu; not yoksa null
giftPackageboolHediye paketi istenip istenmediği; varsayılan false

Bir notu silmek için değerini boş gönderin ({"orderNote": null}). Karakter sınırları mağaza ayarlarından okunur; sınır aşılırsa istek 422 döner. Başka bir müşterinin satırına not yazılamaz, bu durumda 404 alırsınız.

Satır silme

DELETE /cart-items/{itemId}

curl -X DELETE "https://<domain>/api/v3/storefront/2026-01/cart-items/57" \
  -H "Accept: application/vnd.api+json" \
  -H "Authorization: Bearer <access_token>"

Yanıt 200 — satır çıkarılmış güncel sepet dokümanı.

Kupon uygulama ve kaldırma

POST /cart/coupon · DELETE /cart/coupon

curl -X POST "https://<domain>/api/v3/storefront/2026-01/cart/coupon" \
  -H "Accept: application/vnd.api+json" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <access_token>" \
  -d '{ "couponCode": "WELCOME10" }'

Yanıt 200 — güncel sepet dokümanı. Kupon geçerliyse data.attributes.appliedCoupon ve discountTotal alanları eklenir:

{
  "data": {
    "type": "carts",
    "id": "me",
    "attributes": {
      "appliedCoupon": {
        "code": "WELCOME10",
        "description": "Hoş geldin indirimi",
        "discountType": "percent",
        "discountAmount": { "amount": "30.00", "currencyCode": "TRY", "decimalPlaces": 2 }
      },
      "discountTotal": { "amount": "30.00", "currencyCode": "TRY", "decimalPlaces": 2 },
      "grandTotal": { "amount": "270.00", "currencyCode": "TRY", "decimalPlaces": 2 }
    }
  }
}

couponCode zorunludur, en fazla 100 karakter. Kuponu kaldırmak için aynı yola DELETE gönder; gövde gerekmez, yanıt yine güncel sepet dokümanıdır.

Kampanya seçme ve kaldırma

POST /cart/campaign · DELETE /cart/campaign

curl -X POST "https://<domain>/api/v3/storefront/2026-01/cart/campaign" \
  -H "Accept: application/vnd.api+json" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <access_token>" \
  -d '{ "campaignId": 41 }'

Yanıt 200 — güncel sepet dokümanı; seçilen kampanya data.attributes.appliedCampaign altında döner:

{
  "data": {
    "type": "carts",
    "id": "me",
    "attributes": {
      "appliedCampaign": {
        "id": 41,
        "name": "Hafta Sonu Fırsatı",
        "description": "Seçili ürünlerde 2 al 1 öde",
        "discountAmount": { "amount": "50.00", "currencyCode": "TRY", "decimalPlaces": 2 }
      },
      "discountTotal": { "amount": "50.00", "currencyCode": "TRY", "decimalPlaces": 2 }
    }
  }
}

campaignId zorunlu bir tam sayıdır (en az 1) ve kampanyalar listesindeki id değerlerinden biri olmalıdır. Seçimi kaldırmak için aynı yola DELETE gönder.

AlanTipKural
appliedCouponobjeYalnız geçerli bir kupon uygulanmışken döner; code, description, discountType, discountAmount taşır
appliedCampaignobjeYalnız bir kampanya seçilmiş ve müşteri bağlamında hâlâ uygulanabilirken döner; id, name, description, discountAmount taşır
discountTotalMoneyKupon ve kampanya indirimlerinin toplamı. Yalnız toplam sıfırdan büyükken döner
grandTotalMoneyİndirimler düşülmüş, KDV dahil ödenecek tutar. Yalnız dolu sepette döner

Bu alanların hepsi KOŞULLUDUR — koşul sağlanmadığında null dönmez, yanıtta HİÇ YER ALMAZ. Geçersiz veya süresi dolmuş bir kupon kodu gönderildiğinde istek hata vermez; kupon uygulanmaz ve appliedCoupon alanı yanıtta yer almaz. İstemci sonucu bu alanın varlığına bakarak doğrulamalıdır.

Sepet fiyat alanları

data.attributes, mağaza yapılandırmasına göre kargo ve minimum sipariş bilgisi taşıyabilir. Tüm tutarlar Money şemasıyla döner:

{
  "data": {
    "type": "carts",
    "id": "me",
    "attributes": {
      "totalQuantity": 2,
      "subtotal": { "amount": "831.67", "currencyCode": "TRY", "decimalPlaces": 2 },
      "freeCargoThreshold": { "amount": "5000.00", "currencyCode": "TRY", "decimalPlaces": 2 },
      "cargoPrice": { "amount": "49.90", "currencyCode": "TRY", "decimalPlaces": 2 },
      "minimumOrderAmount": { "amount": "300.00", "currencyCode": "TRY", "decimalPlaces": 2 },
      "belowMinimumOrder": false
    }
  }
}
AlanTipKural
cargoPriceMoneySepetin KDV dahil toplamına göre hesaplanan kargo bedeli. "0.00" dönmesi kargonun ücretsiz olduğu anlamına gelir: eşik aşılmış, müşteri/grup kargodan muaf veya sepetteki tüm ürünler ücretsiz kargolu.
freeCargoThresholdMoneyÜcretsiz kargo eşiği. Sepetin KDV dahil toplamı bu tutara ulaştığında cargoPrice "0.00" olur.
minimumOrderAmountMoneyAktif ödeme yöntemlerinde tanımlı en düşük sipariş alt limiti.
belowMinimumOrderboolSepetin KDV dahil toplamı minimumOrderAmount altındaysa true; minimumOrderAmount ile her zaman birlikte döner.

Bu alanların hepsi KOŞULLUDUR — koşul sağlanmadığında alan null dönmez, yanıtta HİÇ YER ALMAZ (varlık kontrolü yap):

  • cargoPrice ve freeCargoThreshold yalnızca mağazanın "sepette kargo fiyatı görünsün" ayarı açıkken döner.
  • freeCargoThreshold ayrıca varsayılan kargo firmasında ücretsiz kargo limiti tanımlı olmasını gerektirir; limit yoksa yalnızca cargoPrice gelir.
  • minimumOrderAmount ve belowMinimumOrder yalnızca en az bir aktif ödeme yönteminde sıfırdan büyük alt limit tanımlıysa döner.
  • Boş sepette bu alanların hiçbiri dönmez; data.attributes yalnızca totalQuantity ve subtotal içerir.

Eşik ve alt limit karşılaştırmaları, satır toplamlarına satırın vatRate değeri eklenerek bulunan KDV dahil tutar üzerinden yapılır; subtotal ise satır toplamıdır — iki taban birebir aynı olmayabilir. İstemci eşik hesabını kendisi yapmamalı, belowMinimumOrder ve cargoPrice değerlerini sunucudan okumalıdır.

Kampanyalar

Dolu sepette data.attributes.campaigns, o an sepete uygulanabilir aktif kampanyaların salt-okuma listesini taşır. Bu alan yalnızca bilgilendirme amaçlıdır — mağaza panelindeki kampanya motorundan okunan ad ve açıklamayı gösterir, sepet üzerinde bir hesaplama yapmaz.

{
  "data": {
    "type": "carts",
    "id": "me",
    "attributes": {
      "totalQuantity": 2,
      "subtotal": { "amount": "300.00", "currencyCode": "TRY", "decimalPlaces": 2 },
      "campaigns": [
        { "id": 41, "name": "Hafta Sonu Fırsatı", "description": "Seçili ürünlerde 2 al 1 öde", "logicalGroup": 3 }
      ]
    }
  }
}
AlanTipKural
idintKampanyanın kimliği.
namestringKampanya adı.
descriptionstringSepette gösterilmek üzere hazırlanmış kampanya açıklaması (boş olabilir).
logicalGroupintKampanyanın mantıksal grup numarası; aynı gruptaki kampanyalar birlikte değerlendirilir. Sıralama logicalGroup içinde önceliğe göredir.

İndirim tutarı DÖNMEZ. campaigns[] hiçbir Money alanı taşımaz — ne kampanya başına ne de sepet geneli için hesaplanmış bir indirim/kazanç tutarı verilmez. Uygulama bu listeyi yalnızca "sepetine şu kampanyalar uygulanıyor" bilgisini göstermek için kullanmalı, tasarruf tutarını buradan türetmeye çalışmamalıdır. Kesin fiyat, ödeme devri sonrası web ödeme akışında netleşir.

Bu alan KOŞULLUDUR — koşul sağlanmadığında null dönmez, yanıtta HİÇ YER ALMAZ (varlık kontrolü yap):

  • Sepet boşsa (included: []) campaigns dönmez.
  • Mağazanın kampanya motoru ayarı kapalıysa dönmez.
  • O an geçerli (tarih aralığı, hafta günü, saat, kullanım limiti ve müşteri/grup filtresi tutan) hiç kampanya yoksa dönmez.
  • Kupona bağlı kampanyalar bu listeye girmez; yalnızca otomatik uygulanan kampanyalar listelenir. Kupon akışı için Kuponlar sayfasına bak.

Kampanya seti istek anında müşteri bağlamına göre çözülür: misafir sepet token'ında ziyaretçi filtreleri, üye token'ında müşterinin grubu/bayi durumu ve kişiye özel kampanya filtreleri uygulanır. İstemci bu listeyi önbelleğe alıp yeniden kullanmamalı, her sepet okumasında sunucudan gelen güncel değeri esas almalıdır.

cart-items alan semantiği

AlanTipKural
productIdintSatırın ürünü
variantIdint | nullVaryant satırında dolu, aksi halde null
quantityintSatır adedi
productNamestringÜrün adı
imagestringÜrün görseli, mutlak URL
availableForSaleboolSatılabilirlik — aşağıya bak
unitPriceMoneyBirim fiyat
lineTotalMoneySatır toplamı; ham birim fiyat × adet üzerinden hesaplanıp yuvarlanır, yuvarlanmış unitPrice × quantity çarpımından kuruş düzeyinde sapabilir
vatRatenumberSatırdaki ürünün KDV oranı, yüzde olarak (örn. 20). KDV'siz üründe 0. Sunucu, kargo eşiği ve minimum sipariş karşılaştırmalarında KDV dahil tabanı lineTotal × (1 + vatRate / 100) ile hesaplar
stocknumberSatırdaki kalemin kalan stok adedi. Varyant satırında varyantın stoğu, varyantsız satırda ürünün stoğu. Eksi stok satışı açık olsa da gerçek stok değeri döner — satılabilirlik için availableForSale kullanılır
stockUnitstringStok biriminin adı (örn. Metre, Kg). Tanımsızsa boş metin
stockIncrementnumberSepette adet artış adımı. Stok birimi tanımlı değilse veya adım tanımsızsa 1

availableForSale semantiği

  • Mağazada eksi stok satışı açıksa her satır true döner.
  • Varyant satırında varyantın kendi stoğuna bakılır; varyantsız satırda ürünün satılabilirliğine (stok 0 ise false).
  • Satır sepete girdikten sonra stok tükenirse alan false'a döner; client satırı sipariş öncesi bu alanla doğrulamalıdır.

Fiyat çözümü

unitPrice istek anında sunucuda çözülür: aktif indirim varsa indirimli fiyat, varyantın kendi fiyatı tanımlıysa varyant fiyatı, müşteri grubuna özel fiyat tanımlıysa grup fiyatı uygulanır. Client sepetteki fiyatı kendisi hesaplamamalıdır.

Hatalar

Durum koduSebep
401Token yok/geçersiz; uygulama (app) token'ı ile sepet ucuna istek; birleşme sonrası iptal edilmiş misafir token'ı
403Müşteri token'ında storefront:account ya da misafir token'ında storefront:cart scope'u eksik
404{itemId} bulunamadı veya satır token sahibine ait değil
422Geçersiz gövde: satışta olmayan ürün (/productId), varyant seçilmedi ya da geçersiz varyant (/variantId), adet 1–100000 dışı ya da tam sayı değil (/quantity), kupon kodu boş ya da 100 karakterden uzun (/couponCode), kampanya kimliği tam sayı değil (/campaignId)

422 hataları JSON:API errors[] biçimindedir ve her ihlal source.pointer ile ilgili alanı gösterir.

Sepet uçları hız sınırına tabidir; 429 yanıtında Retry-After başlığına uy.