Saat 9.00'da indirim başlar. CDN ürün sayfalarını ayakta tutar, ama checkout'ta (ödeme adımında) işler ters gider: iki müşteri aynı ceketin son adedini satın alır, zaman aşımından sonraki bir yeniden deneme aynı kartta iki ödeme blokesi bırakır ve bir olay kaybolduğu için depo bir siparişten bir saat geç haberdar olur.
Bunların hiçbiri kapasite sorunu değil. Hepsi sınır sorunu: hangi verinin sahibi kim ve hangi adımların müşteri beklerken tamamlanması gerekiyor.
Bu yazı, orta ölçekli bir mağaza için gerçekçi bir e-ticaret mimarisini ele alıyor: bileşenler ve veri sahipliği, adım adım checkout yolu, sonrasındaki sipariş hattı, zirve trafiği ve platformun bir diyagramı.
Müşterilerin yaptıklarından başlayın
Bir mağazanın yaptıklarının çoğunu beş yolculuk kapsar ve bunların ihtiyaçları birbirinden çok farklıdır:
| Yolculuk | Yoldaki bileşenler | Ne eski olabilir |
|---|---|---|
| Gezinme | CDN, ağ geçidi, katalog | Önbellekteki bir sayfadaki fiyatlar ve stok, dakikalarca |
| Arama | Arama indeksi | Değişen ürünler, saniyelerce |
| Sepet | Sepet | Müşterinin az önce değiştirdiği hiçbir şey |
| Checkout | Checkout, envanter, ödeme sağlayıcısı, siparişler | Hiçbir şey |
| Sipariş takibi | Siparişler, fulfillment | Kargo durumu, dakikalarca |
İsteklerin çoğunu gezinme ve arama taşır ve bu ikisi eski veriye tahammül eder; checkout ise az istek taşır ve hiç tahammül etmez. Mimarinin büyük kısmı bu ayrımdan çıkar.
Bileşenler ve her birinin sahip olduğu veri
Uçta bir CDN sayfaları ve görselleri önbelleğe alır; bir API ağ geçidi (ya da her istemci türü için bir backend for frontend) geri kalan isteklerde kimlik doğrulaması yapar, hız sınırı uygular ve onları yönlendirir. Bunların arkasındaki her servis kendi verisinin sahibidir:
| Servis | Sahip olduğu veri | Tipik veri deposu | Tutarlılık ihtiyacı |
|---|---|---|---|
| Katalog (Catalog) | Ürünler, varyantlar, fiyatlar | Postgres, önbellekler üzerinden okunur | Nihai tutarlılık; checkout fiyatları yeniden okur |
| Arama (Search) | Facet'li ürün indeksi | OpenSearch ya da Elasticsearch | Nihai tutarlılık; katalog değişiklikleriyle güncellenir |
| Sepet (Cart) | Müşteri başına sepet satırları | TTL'li Redis | Müşteri başına read-your-writes |
| Checkout | Oturumlar: toplamlar, rezervasyon ve ödeme kimlikleri | Postgres | Oturum içinde güçlü tutarlılık |
| Envanter (Inventory) | SKU başına stok, rezervasyonlar | Postgres | Güçlü: stoktan fazlası asla satılmaz |
| Siparişler (Orders) | Siparişler, durum geçmişi, outbox | Postgres | Güçlü: sipariş başına tek yazıcı |
| Ödeme hizmet sağlayıcısı (PSP) | Provizyonlar, tahsilatlar, iadeler | PSP'nin kendisi | Esas alınan, PSP'nin kaydıdır |
| Fulfillment | Gönderiler, takip numaraları | WMS ya da 3PL | Nihai tutarlılık; olaylarla yürür |
Diğer servisler sahibin API'sini ya da olaylarını kullanır, asla tablolarını değil. Stok ve siparişler veritabanı işlemleri (transaction) gerektirir; sepetler ve arama indeksi gerçek bir zarar vermeden geride kalabilir, hatta bir yazmayı kaybedebilir.
Adım adım checkout yolu
Checkout, müşterinin aynı anda birkaç servisi beklediği tek akıştır:
Sepeti yeniden fiyatlandırın. Checkout sepeti okur, katalogdan güncel fiyatları alır ve vergiyi, kargoyu ve indirimleri sunucu tarafında hesaplar. Tarayıcının hesapladığı toplama asla güvenmeyin.
Stoku bir bitiş süresiyle rezerve edin; burada süre 15 dakika:
-- One transaction: take the stock, then record the hold UPDATE stock SET reserved = reserved + 2 WHERE sku = 'JKT-042-M' AND on_hand - reserved >= 2; -- 0 rows: out of stock, stop INSERT INTO reservations (checkout_id, sku, qty, expires_at) VALUES ('chk_41a', 'JKT-042-M', 2, now() + interval '15 minutes');İki müşteri son ceket için yarıştığında, PostgreSQL'in varsayılan yalıtım düzeyi Read Committed'da ikinci güncelleme bekler, ardından WHERE koşulunu yeni satıra göre yeniden denetler; böylece müşterilerden biri sıfır satır alır. Bir temizleyici, süresi dolan rezervasyonları stoka geri verir. Barındırılan bir ödeme sayfası kullanıyorsanız süreleri eşleyin: Stripe Checkout oturumları, daha kısa bir bitiş süresi (en az 30 dakika) belirlemediğiniz ya da onları kendiniz sonlandırmadığınız sürece 24 saat geçerlidir;
checkout.session.expiredolayı ürünleri serbest bırakmanız gerektiğini bildirir.Ödemeyi bir idempotency anahtarıyla oluşturun. Checkout, PSP'den sunucu tarafında hesaplanan toplam tutar için manuel tahsilatlı bir ödeme ister; idempotency anahtarı çağrıdan önce kaydedilir. Zaman aşımından sonra aynı anahtarla yeniden deneyin: Stripe kaydedilmiş yanıtı döndürür, ikinci bir ödeme oluşturmaz. Stripe'ın anahtarları en fazla 255 karakterdir ve 24 saat sonra silinebilir.
Provizyon alın. Önce stok rezervasyonunu uzatın ki ödemenin ortasında süresi dolmasın. Müşteri kart bilgilerini PSP'nin alanlarına girer; böylece kart numaraları sunucularınıza hiç ulaşmaz. Kartı çıkaran banka 3-D Secure isteyebilir. Başarılı olursa tutar bloke edilir: Manuel tahsilatlı bir Stripe ödemesi
requires_capturedurumuna geçer vepayment_intent.amount_capturable_updatedolayını yayar. Tarayıcının yönlendirmesine değil, bu webhook'a güvenin; ayrıntılar için ödeme geçidi entegrasyon diyagramına bakın.Siparişi oluşturun. Sipariş servisi siparişi
placeddurumunda oluşturur ve aynı işlemde bir outbox tablosunaOrderPlacedyazar. Ardından checkout, envanter servisine rezervasyonu tahsise dönüştürmesini söyler.Tahsilatı gönderimde yapın. Fulfillment gönderimi yaptığında sipariş servisi tahsilatı yapar. Bu yazının yazıldığı tarihte (Kasım 2026) Stripe'ın belgelerine göre online kart provizyonları genellikle 7 gün, üye işyerinin başlattığı Visa işlemlerinde ise 5 gün (tam olarak 4 gün 18 saat) geçerlidir; ardından bloke kalkar ve ödeme iptal edilir. Çoğu kartlı ödeme tek bir tahsilata izin verir; kısmi bir tahsilat ise kalan tutarın blokesini kaldırır.
Sipariş oluşmadan önce bir adım başarısız olursa önceki adımları ters sırayla geri alın: Provizyonu iptal edin, rezervasyonu serbest bırakın. Bu, orkestratörü checkout olan bir saga örneğidir.
Para, stok ve sipariş durumu nerede değişir
| Sipariş durumu | Ne zaman atanır | Ödeme | Stok |
|---|---|---|---|
| Checkout açık | Stok rezerve edildiğinde | Oluşturuldu, provizyon alınmadı | 15 dakika rezerve |
| Sipariş verildi (Placed) | PSP provizyonu bildirdiğinde | Tutar bloke | Siparişe tahsis edildi |
| Gönderildi (Shipped) | Fulfillment gönderdiğinde | Tahsil edildi | Eldeki stoktan düşüldü |
| İptal edildi (Canceled) | Gönderimden önce iptal edildiğinde | Provizyon iptal edildi | Serbest bırakıldı |
| İade edildi (Returned) | İade teslim alındığında | Ücret iade edildi | Kontrolden sonra stoka geri alındı |
Zor durumlar satırların arasında saklıdır. Provizyon, rezervasyonun süresi dolduktan sonra gelirse ve stok kaldıysa yeniden rezerve edin; kalmadıysa provizyonu iptal edin ve müşteriye haber verin. Stokta olmayan ürün için alınan bir sipariş (backorder) 7 günlük pencereyi aşacaksa tutarın tamamını ilk gönderimde tahsil edin, PSP'niz sunuyorsa uzatılmış provizyon kullanın (Stripe'a göre bazı kart ağlarında 30 güne kadar) ya da ücreti peşin alıp gönderemediğiniz kısmı iade edin. ACH ve iDEAL gibi bazı ödeme yöntemleri ayrı tahsilatı hiç desteklemez.
Sipariş oluşturulduktan sonra
placed sonrasındaki her şey asenkron çalışır. Bir aktarıcı (relay), OrderPlaced olayını outbox'tan order-events topic'ine yayınlar; böylece commit ile broker arasında hiçbir olay kaybolmaz (transactional outbox desenine bakın). Fulfillment ürünleri toplar, paketler ve gönderir, ardından tahsilatı tetikleyen OrderShipped olayını yayınlar. Bildirim servisi e-postaları gönderir; analitik her olayı veri ambarına yükler.
Teslimat en az bir kez garantisiyle yapılır; bu yüzden tüketiciler tekrarları olay kimliğine göre ayıklar. Topic'i sipariş kimliğine göre anahtarlamak, her siparişin olaylarını sırasında tutar.
Mikroservis mimari diyagramı ise kartı OrderPlaced sonrasında ücretlendirir. Bu yaklaşım müşteri etkileşimi gerektirmeyen ödemelere uyar; 3-D Secure müşterinin orada olmasını gerektirdiğinden bu tasarım provizyonu checkout içinde alır.
Zirve trafiğinde ayakta kalmak
7.200 siparişlik bir indirim saati, %2 dönüşüm oranı ve oturum başına 10 sayfa görüntüleme varsayın: 360.000 oturum ve 3,6 milyon sayfa görüntüleme, yani saniyede 2 siparişe karşılık saniyede yaklaşık 1.000 sayfa görüntüleme. İki tarafın da kendi korumasına ihtiyacı var:
- Kataloğu uçta önbelleğe alın.
Cache-Control: public, max-age=0, s-maxage=300, stale-while-revalidate=60ile CDN bir ürün sayfasını beş dakika boyunca sunar, ardından RFC 5861'in tanımladığı gibi sayfayı arka planda yeniden çekerken bir dakikaya kadar daha sunmaya devam eder. %90 isabet oranında origin sunucusu saniyede 1.000 yerine 100 sayfa görüntüleme alır. Fiyat değiştiğinde önbelleği temizleyin; checkout zaten yeniden kontrol eder. - Checkout'un önüne bir kuyruk koyun. Sanal bir bekleme odası, müşterileri envanterin ve PSP'nin kaldırabileceği bir hızla içeri alır; bilet rezervasyon sistemi tasarımında olduğu gibi.
- Sıcak SKU'ları koruyun. Bir SKU için yapılan rezervasyonlar tek bir satırı birer birer günceller. İşlem başına 2 ms kilit süresiyle o satır saniyede 500 rezervasyon civarında tavan yapar. İşlemi kısa ve PSP çağrılarından arınmış tutun, büyük indirimli bir kampanya ürününün stokunu birkaç satıra bölün ve sipariş başına adedi sınırlayın.
- PSP'nizin hız sınırlarını indirimden önce öğrenin.
Bundan daha küçük başlayın
Birçok mağaza bunların hepsini kurmamalı. Shopify ya da BigCommerce gibi barındırılan bir platform kataloğu, sepeti ve checkout'u sizin yerinize çalıştırır; bu durumda diyagramınız onun etrafındaki uygulamaları ve webhook'ları gösterir.
Özel geliştirilen bir sistem çoğu zaman en iyi modüler bir monolit olarak başlar: aynı sınırlar, tek bir dağıtım biriminin içinde modüller olarak. Shopify mühendisleri 2019'da, en büyük Ruby on Rails kod tabanlarından birini mikroservislere bölmek yerine siparişler, kargo, envanter ve faturalama etrafında yeniden düzenlediklerini anlattı. Bir modül kendi ölçeklemesine ya da kendi sürümlerine ihtiyaç duyduğunda onu ayrı bir servis olarak çıkarın; diyagram yine geçerlidir.
E-ticaret platformu diyagramı
Diyagram içeriği
- Shopper
- CDN
- API gateway / BFF
- Catalog
- Search
- Cart
- Checkout
- Orders
- Inventory
- Payment provider (PSP)
- order-events
- Fulfillment
- Notifications
- Analytics warehouse
- HTTPS
- misses, API
- GET /products
- GET /search
- POST /cart/items
- POST /checkout
- GET /orders/{id}
- product changes
- read cart
- reserve, 15 min
- authorize + idempotency key
- place order
- capture on OrderShipped
- OrderPlaced
- placed, shipped
- all events
Nasıl okunur:
- İstekler sol üstten girer: müşteri, CDN, ardından her yolculuğu tek bir servise yönlendiren ağ geçidi.
- Mavi, gezinme yoludur. Kesikli kenar, arama indeksinin ürün değişikliklerine yetişmesini gösterir.
- Kehribar rengi checkout yoludur; müşteri burada bekler: sepeti okuma, stoku rezerve etme, provizyon alma ve siparişi oluşturma.
- Ödeme sağlayıcısı iki çağrı alır: checkout sırasında provizyon,
OrderShippedgeldiğinde tahsilat (kesikli turkuaz). - Mor kesikli kenarlar olaylardır: outbox'tan order-events üzerinden fulfillment'a, bildirimlere ve analitiğe.
- Her servis kendi deposunu belirtir; Markdown bloğu da rakamları listeler.
E-ticaret mimari diyagramlarını net çizmek
- Ağ geçidi kenarlarını rotalarla etiketleyin, örneğin
GET /products; böylece okuyanlar sayfaları servislerle eşleştirebilir. - Her serviste deposunu yazın. Paylaşılan bir veritabanı gözden kaçamamalı.
- Beklenen için düz, sonrası için kesikli çizgi. Müşterinin beklediği çağrılar olaylardan farklı görünmeli.
- Süreleri kenarlara yazın. En çok incelenmesi gerekenler rezervasyon süresi ve tahsilat tetikleyicisidir.
- Provizyonu ve tahsilatı iki ayrı kenar olarak çizin. PSP'ye giden tek bir ok kritik zamanlamayı gizler.
- Pod'ları, bölgeleri, vergi ve dolandırıcılık önleme sağlayıcılarını ve arka ofisi dışarıda bırakın.
Archboard'da oluşturun
- Google ya da GitHub ile giriş yapın ve bir diyagram oluşturun.
- C4 Model paketinden bir Kişi düğümü, onun altına da Bulut paketinden bir CDN ve bir API ağ geçidi ekleyin.
- C4 Model paketinden beş Konteyner düğümünü bir sütun hâlinde ekleyin: Catalog, Search, Cart, Checkout ve Orders; her birinin deposunu Açıklama alanına yazın.
- Inventory için bir Konteyner, ödeme sağlayıcısı için bir Harici sistem ve order-events için Veri paketinden bir Konu ekleyin. Bunların sağına Fulfillment ve Notifications için Konteyner düğümleri ile Veri paketinden bir Veri ambarı ekleyin.
- Ağ geçidini rota etiketleriyle beş servise bağlayın. Checkout çağrılarını düz; ürün değişikliklerini, tahsilatı ve olayları kesikli yapın.
- Rakamlar için Temel paketinden bir Markdown bloğu, gösterge ve temel kurallar için de Metin notları ekleyin.
Servisleriniz bir Compose dosyasından çalışıyorsa Docker Compose'dan diyagrama aracı kutuların taslağını çıkarır; mikroservis mimarisi şablonu da başka bir başlangıç noktasıdır. Örnek 15 diyagram düğümü kullanıyor ve Free planın sınırları içinde kalıyor.
SSS
Bir e-ticaret mimarisinin ana bileşenleri nelerdir? Bir CDN, bir API ağ geçidi; katalog, arama, sepet, checkout, envanter ve siparişler için servisler; bir ödeme sağlayıcısı; ayrıca fulfillment, bildirimler ve analitik. Barındırılan platformlar bunların çoğunu bir arada sunar.
Bir online mağaza mikroservis kullanmalı mı? Varsayılan olarak hayır. Aynı sınırlara sahip modüler bir monoliti işletmek daha basittir ve Shopify da çekirdeği için bunu seçti. Bir modül bağımsız ölçeklemeye ya da bağımsız sürümlere ihtiyaç duyduğunda onu ayrı bir servise çıkarın.
Stokta olandan fazla satış nasıl önlenir? Stoku SKU başına tek bir atomik, koşullu güncellemeyle rezerve edin, her rezervasyona bir bitiş süresi verin ve tahsisi yalnızca sipariş oluşturulduğunda yapın. Stok durumuna asla önbellekteki bir sayfaya bakarak karar vermeyin.
Bir online mağaza ödemeyi ne zaman tahsil etmeli? Fiziksel ürünlerde genellikle gönderimde; böylece yalnızca gönderilen ürün için ücret alırsınız. Online kart provizyonları genellikle 7 gün geçerlidir. Stripe'ta Klarna 28 gün, PayPal ise 10 gün tanır; Stripe bunu 20 güne uzatmaya çalışır.
E-ticaret siteleri trafik sıçramalarıyla nasıl başa çıkar? Kataloğu CDN'den sunar, müşterileri checkout'un önünde kuyruğa alır, sıcak SKU'ları ve ödeme sağlayıcısını korurlar. Checkout kapasitesini sayfa görüntülemelerinden ayrı planlayın.