T-SOFT/Storefront API/Ödeme Devri

Ödeme Devri

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ış.

Basit anlatım: Müşteri ödemeye hazır olduğunda uygulama kendi ödeme ekranını çizmez — müşteriyi, zaten giriş yapmış hâlde web ödeme sayfasına devreder. Uygulama API'den tek kullanımlık kısa ömürlü bir devir bağlantısı ister, bu bağlantıyı bir web görünümünde (web view) açar; sunucu token'ı doğrular, aynı müşteriyi web oturumuna sessizce giriş yaptırır ve sepet/ödeme sayfasına yönlendirir. Token ~60 saniyede ölür ve yalnızca bir kez kullanılabilir, böylece çalınan bir bağlantı bir dakika sonra işe yaramaz.

Bu özellik, token ile kimliklenen mobil uygulamadan çerez/oturum tabanlı web mağazasına oturum kimliği devri yapar; böylece web sepeti ve web ödeme akışı aynı müşteriyi görür. İki uç birlikte çalışır: uygulama bir devir bağlantısı üretir, tarayıcı bu bağlantıyı tüketir. Devir iki kimlikte de mümkündür: üye müşteri (storefront:account token'ı) ve misafir (storefront:cart token'ı). Her ikisi de aynı tüketme ucunu (/api/v3/storefront/checkout/handoff) paylaşır; fark yalnızca hangi üretme ucunun çağrıldığıdır. Bu bir JSON:API kaynağı değildir — sade uçlardır.

Üye devir oturumu üretme

POST /api/v3/storefront/2026-01/checkout-session

Müşteri token'ı (storefront:account scope'u) gerekir; uygulama (app) token'ı ile istek 401 döner.

curl -X POST "https://<domain>/api/v3/storefront/2026-01/checkout-session" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <customer_access_token>" \
  -d '{ "returnPath": "/odeme" }'

Yanıt 200:

{
  "url": "https://<domain>/api/v3/storefront/checkout/handoff?t=<urlencoded-token>",
  "expiresAt": "2026-07-10T12:34:56+00:00"
}
AlanTipKural
urlstringUygulamanın web görünümünde açması gereken devir bağlantısı. Biçim: {site}/api/v3/storefront/checkout/handoff?t={token}.
expiresAtstringToken'ın mutlak son geçerlilik anı (ISO-8601, UTC).

İstek gövdesi opsiyoneldir:

AlanTipKural
returnPathstringDevir sonrası gidilecek hedef yol. Gönderilmezse varsayılan /sepet. İzin listesinde değilse hata verilmez — sessizce varsayılana çekilir.

İzin verilen dönüş yolları: /sepet, /odeme, /checkout, /order, /uye-siparisleri (ve bunların alt yolları, örn. /odeme/adim-2). /sepetx gibi sınır ihlalleri izinli sayılmaz.

Misafir devir oturumu üretme

POST /api/v3/storefront/2026-01/checkout-guest-session

Üye olmadan alışverişe devam eden ziyaretçiyi, misafir sepet token'ı üzerinden aynı web ödeme akışına devreder. Misafir sepet token'ı (storefront:cart scope'u) gerekir; token edinme için misafir sepeti sayfasına bak.

Bu uç iki mağaza ayarına birden bağlıdır (üyeliksiz alışveriş kapısı). Ayarlardan biri kapalıysa uç 403 döner:

AyarAnlamı
SatinAlmaSureciUyeliksizBaslaSatın alma sürecine üyeliksiz başlama açık olmalı (1).
UyelikOlmadanDevamEtGoster"Üyelik olmadan devam et" seçeneği gösterimde olmalı (1).
curl -X POST "https://<domain>/api/v3/storefront/2026-01/checkout-guest-session" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <guest_cart_access_token>" \
  -d '{ "returnPath": "/odeme" }'

Yanıt 200 (üye ucuyla birebir aynı şekil):

{
  "url": "https://<domain>/api/v3/storefront/checkout/handoff?t=<urlencoded-token>",
  "expiresAt": "2026-07-11T12:34:56+00:00"
}
  • Yanıt gövdesi ve returnPath davranışı üye ucuyla aynıdır (url + expiresAt; izin listesi dışı yol sessizce /sepet'e çekilir).
  • Üretilen token misafir oturumunu köprüler: tüketildiğinde web tarafında misafir oturumu kurulur, üye kimliği (SesUyeId) YAZILMAZ. Kalan akış tüketme ucunda üye ile aynıdır.
  • Misafir üretme ucu, üye ucundan ayrı ve daha sıkı bir IP hız sınırına tabidir (bkz. Yapılandırma).

Devri tüketme (oturum köprüsü)

GET /api/v3/storefront/checkout/handoff?t=<token>

Bu uç tarayıcı (web view) tarafından açılır; API guard'ı DEĞİL, web oturum grubundadır — kimlik doğrulaması token'ın kendisidir. Aynı uç hem üye hem misafir token'ını işler: token içindeki özne (sub) üyeyse müşteri web oturumuna, misafirse misafir web oturumuna köprülenir. Sunucu token'ı doğrular ve tüketir, ardından token'daki dönüş yoluna 302 yönlendirir.

Misafir tüketmede iki ek koşul vardır: token tüketildiği anda da üyeliksiz alışveriş ayar kapısı hâlâ açık olmalı (arada kapatıldıysa /sepet'e düşer) ve token'daki misafir sepet referansı boş olmamalıdır.

  • Başarı: token'ın returnPath değerine (/odeme vb.) yönlendirir ve yeni bir oturum çerezi yazar.
  • Başarısızlık (geçersiz/süresi dolmuş/kullanılmış token veya izinsiz yol): sessizce varsayılan /sepet yoluna yönlendirir; oturuma kimlik yazılmaz.

Bu uç JSON hata gövdesi döndürmez; her sonuç bir 302 yönlendirmedir. İstemci başarıyı, beklenen returnPath sayfasına düşmekle (varsayılan /sepet'e sekmemekle) anlar.

Güvenlik davranışı

Bu özelliğin çekirdeği güvenlik sertleştirmesidir (V5-11259):

  • Kısa ömürlü, imzalı, tek kullanımlık token. Token app.key ile HMAC-SHA256 imzalıdır; sahte imza reddedilir. Varsayılan ömür 60 saniyedir (token_ttl_seconds).
  • Tek kullanım (one-shot). Token tüketildiğinde benzersiz kimliği (jti) önbelleğe atomik olarak işaretlenir; ikinci kullanım geçersizdir. Uygulama devir bağlantısını yalnızca bir kez açmalı, harcanmış saymalı (geri/yenile, önizleme, link tarayıcıları tekrar açarsa kimliksiz /sepet'e düşer).
  • Oturum sabitleme (session fixation) önlemi. Başarılı devirde sunucu oturum kimliğini yeniden üretir (eski oturumu yok eder), sonra kimliği yazar.
  • Açık yönlendirme (open-redirect) savunması. returnPath hem üretimde hem tüketimde izin listesine karşı doğrulanır; site dışına yönlendirme engellenir.
  • Kayıt (log) hijyeni. Ret durumlarında yalnızca IP ve maskelenmiş müşteri referansı loglanır; ham token veya düz müşteri id'si asla loglanmaz.

Aynı sertleştirme emsalleri misafir devrine de taşınmıştır (V5-11329): misafir token'ı da HMAC imzalı, tek kullanımlık ve kısa ömürlüdür; misafir tüketmede oturum kimliği yeniden üretilir; returnPath misafir uçta da izin listesine karşı doğrulanır. Misafir oturumu web tarafında üye kimliği (SesUyeId) yazmaz — yalnızca misafir sepet oturumu köprülenir. Üyeliksiz alışveriş kapısı hem üretme hem tüketme aşamasında ayrı ayrı denetlenir.

Yapılandırma

config/storefront-checkout.php (handoff anahtarı altında):

AnahtarVarsayılanAnlamı
token_ttl_seconds60Devir token'ının saniye cinsinden ömrü (üye + misafir ortak).
issue_rate_limit10Üretme uçlarının dakikalık üst sınırı (token + IP başına). Misafir uçta bu limit de uygulanır.
guest_issue_ip_rate_limit30Misafir üretme ucuna EK olarak uygulanan IP başına dakikalık üst sınır. Misafir uç iki limite birden tabidir: token başına 10 VE IP başına 30.
handoff_rate_limit30Tüketme ucunun dakikalık üst sınırı (IP başına).
default_return_path/sepetİstenen/token yolu izinli değilken veya token geçersizken düşülen varsayılan hedef.
allowed_return_paths['/sepet','/odeme','/checkout','/order','/uye-siparisleri']İzin verilen dönüş yolu ön ekleri.

Hatalar

Durum koduUçSebep
401üye üretmeToken yok/geçersiz veya müşteri token'ı değil; müşteri pasif/banlı
403üye üretmeMüşteri token'ında storefront:account scope'u yok
429üye üretmeDakikada 10'dan fazla istek (token + IP başına)
401misafir üretmeToken yok/geçersiz; misafir sepet token'ı değil (üye müşteri token'ı da bu uçta 401 alır)
403misafir üretmeMisafir token'ında storefront:cart scope'u yok; VEYA üyeliksiz alışveriş ayar kapısı kapalı
429misafir üretmeToken başına dakikada 10 veya IP başına dakikada 30 sınırı aşıldı
302tüketmeHer sonuç yönlendirmedir; hata için ayrı durum kodu yoktur (başarısızlıkta /sepet'e yönlendirir — misafirde ayar kapısı kapandıysa veya sepet referansı boşsa da /sepet)
429tüketmeDakikada 30'dan fazla istek (IP başına)