Yapay zeka ile e-ticaret sitesi yapmak için bir kodlama ajanına ürün kataloğunu, sepeti ve ödeme akışını adım adım yazdırırsın; tipik bir kurulum Next.js, bir veritabanı ve Stripe ya da Türkiye’de iyzico, PayTR gibi bir ödeme sağlayıcısıdır. Ajan kodu hızlı yazar, ama fiyatın sunucuda hesaplanması, ödemenin webhook ile doğrulanması ve kart bilgisinin hiç saklanmaması gibi kuralları senin koyman gerekir. Önce hazır bir platformun (Shopify gibi) sana yetip yetmediğine karar vermek de işin parçası.
Bu yazıda o kararla başlıyorum, sonra özel bir mağazayı ajana nasıl yazdıracağını sırayla anlatıyorum: veri modeli, sepet, ödeme, webhook, stok, e-postalar, yasal sayfalar ve yayın. Her adımda kopyalayıp kullanabileceğin prompt’lar var. Sonda yapay zekanın e-ticarette en sık yaptığı hatalar ve bir güvenlik listesi duruyor.
Önce karar: hazır platform mu, özel site mi?
Bu sorunun dürüst cevabı çoğu zaman “hazır platform”. Shopify, WooCommerce ya da Türkiye’deki yerel e-ticaret altyapıları ödeme, stok, kargo entegrasyonu, fatura ve güvenlik güncellemelerini senin yerine çözer.
| Hazır platform | Özel site (kodlama ajanıyla) | |
|---|---|---|
| Satışa başlama | Günler | Haftalar |
| Ödeme, güvenlik, güncellemeler | Platformun sorumluluğu | Senin sorumluluğun |
| Tasarım ve akış özgürlüğü | Tema ve eklentiler kadar | Sınırsız |
| Maliyet yapısı | Aylık ücret, bazen işlem komisyonu | Barındırma + ödeme sağlayıcısı komisyonu + senin zamanın |
| Taşınabilirlik | Platforma bağlı | Kod senin |
Özel site şu durumlarda mantıklı: platformun desteklemediği bir satış akışın var (abonelik + kişiye özel ürün yapılandırıcı gibi), mevcut bir uygulamanın içine mağaza ekliyorsun ya da öğrenmek ve tam kontrol istiyorsun. Bu yazı o yolu anlatıyor. Sıradan bir tanıtım sitesiyle başlamak istersen önce yapay zeka ile web sitesi yapmak yazısına bak.
1. Stack ve kurulum
Bir vibe coding projesi için önerdiğim, ajanların iyi bildiği ve dokümantasyonu bol bir yığın:
- Next.js (App Router): sayfalar, sunucu tarafı kod ve API rotaları tek projede.
- PostgreSQL: yönetilen bir servis (Supabase, Neon gibi) ya da yerelde Docker.
- Bir ORM (Prisma ya da Drizzle): şema ve migration’lar dosyada durur, ajan ve sen aynı kaynaktan okursunuz.
- Ödeme sağlayıcısı: uluslararası satış için Stripe; Türkiye’de iyzico, PayTR gibi yerel sağlayıcılar. Hepsinin ortak noktası, kartın sağlayıcının formunda girilmesi ve sonucun sunucuna bildirimle gelmesi.
- İşlemsel e-posta servisi: sipariş onayı ve kargo bildirimi için.
npx create-next-app@latest magaza
cd magaza
git status # create-next-app genelde git deposunu da başlatır; başlatmadıysa: git init
claude
2. İlk prompt: önce plan, sonra kod
E-ticarette ajana doğrudan “mağaza yap” demek, her şeyi tek seferde yazan ve kritik kısımları geçiştiren bir sonuç verir. Önce plan iste:
Next.js (App Router), PostgreSQL ve Prisma ile küçük bir e-ticaret sitesi kuracağız.
Ödeme için Stripe Checkout kullanacağız (kart bilgisi asla bizim sunucumuza gelmeyecek).
Henüz kod yazma. Önce şunları içeren bir plan çıkar:
1. Veri modeli: ürün, ürün varyantı (beden/renk), sipariş, sipariş kalemi, stok.
2. Sayfalar: ürün listesi, ürün detayı, sepet, ödeme dönüş sayfaları, basit yönetim paneli.
3. Ödeme akışı: sepetten ödeme oturumu açmaya, webhook'tan siparişi "ödendi" yapmaya kadar.
4. Hangi işlemler mutlaka sunucuda yapılmalı ve neden.
Kurallar:
- Fiyatlar veritabanında kuruş cinsinden tamsayı olarak tutulsun, float yok.
- İstemciden gelen fiyat, toplam ya da indirim tutarına asla güvenilmesin.
- Sırlar yalnızca .env'de, istemci koduna hiçbir sır gitmesin.
Planı yaz, onayımı bekle.
Planı oku, beğenmediğin yeri düzelt, sonra parça parça uygula: önce veri modeli, sonra katalog, sonra sepet, en son ödeme. Her parçadan sonra commit.
3. Ürün veritabanı
Veri modelinde dikkat ettiğim birkaç nokta:
- Para tamsayıdır. 149,90 TL veritabanında
14990olarak durur. Stripe gibi sağlayıcılar da tutarları zaten en küçük para biriminde ister. - Sipariş kalemi fiyatı kopyalar. Siparişte ürünün o anki adı ve fiyatı saklanır; ürünün fiyatı yarın değişse bile eski sipariş doğru kalır.
- Stok varyant düzeyindedir. “M beden mavi tişört” ayrı bir stok satırıdır.
- Sipariş durumu açık bir listedir:
pending,paid,shipped,cancelled,refundedgibi.
Ajan migration yazdığında dosyayı oku. Özellikle mevcut verisi olan bir tabloda DROP ya da sütun silme varsa dur ve sor.
4. Sepet
Sepet, kullanıcının tarayıcısında (ya da giriş yapmışsa veritabanında) yalnızca ürün/varyant kimliği ve adet tutmalı. Fiyat ve toplam sepette gösterilir ama her zaman sunucudan okunur.
Sepeti uygula. Sepet localStorage'da yalnızca {variantId, quantity} listesi tutsun.
Sepet sayfası fiyatları ve toplamı sunucudan güncel olarak çeksin.
Stokta olmayan ya da silinmiş ürünler sepette uyarıyla gösterilsin.
Adet 1 ile 10 arasında sınırlansın ve sunucuda da kontrol edilsin.
5. Ödeme: fiyat her zaman sunucuda hesaplanır
E-ticaretin bir numaralı kuralı: istemciden gelen fiyata asla güvenme. Tarayıcıdaki her değer değiştirilebilir. Biri geliştirici araçlarını açıp toplamı 1 TL yapabilir. Doğru akış şöyle:
- İstemci sunucuya yalnızca sepetteki
variantIdvequantitylistesini gönderir. - Sunucu her kalemin fiyatını ve stoğunu veritabanından okur, toplamı kendisi hesaplar.
- Sunucu veritabanında
pendingdurumlu bir sipariş oluşturur. - Sunucu ödeme sağlayıcısında bir ödeme oturumu açar (Stripe Checkout Session ya da yerel sağlayıcının ödeme formu) ve sipariş kimliğini oturuma ekler.
- Kullanıcı sağlayıcının sayfasına ya da iframe’ine yönlenir, kartını orada girer.
Kısaltılmış bir sunucu kodu fikri vermesi için:
// app/api/checkout/route.ts (özet)
const items = await db.variant.findMany({ where: { id: { in: cart.map(c => c.variantId) } } })
const lineItems = cart.map(c => {
const v = items.find(i => i.id === c.variantId)
if (!v || v.stock < c.quantity) throw new Error('Stok yetersiz')
return { price: v.priceKurus, quantity: c.quantity } // fiyat DB'den, istemciden değil
})
İndirim kuponları da aynı kurala tabidir: kupon kodu istemciden gelir, indirimin geçerliliği ve tutarı sunucuda hesaplanır.
6. Webhook: ödendi mi, ödenmedi mi?
Kullanıcının “ödeme başarılı” sayfasına dönmesi ödemenin alındığını kanıtlamaz; o sayfa elle açılabilir, kullanıcı sekmeyi kapatmış olabilir. Doğru kaynak, ödeme sağlayıcısının sunucuna gönderdiği bildirimdir (Stripe’ta webhook, birçok yerel sağlayıcıda callback).
Webhook uç noktası için ajana şunları mutlaka söyle:
Stripe webhook uç noktasını yaz (/api/webhooks/stripe):
- İsteğin imzasını STRIPE_WEBHOOK_SECRET ile doğrula; imzasız ya da geçersiz isteği reddet.
- İmza doğrulaması için ham istek gövdesini kullan.
- checkout.session.completed olayında sipariş kimliğini metadata'dan al,
siparişi tek bir veritabanı işlemi (transaction) içinde "paid" yap ve stoğu düş.
- İdempotent olsun: aynı olay iki kez gelirse ikinci seferde hiçbir şey değişmesin.
- Ödenen tutarı siparişteki tutarla karşılaştır; uyuşmazsa siparişi işaretle ve logla.
Yerelde test etmek için Stripe CLI olayları makinene yönlendirebilir:
stripe listen --forward-to localhost:3000/api/webhooks/stripe
Stripe’ın test modunda 4242 4242 4242 4242 gibi test kartlarıyla gerçek para harcamadan tüm akışı denersin. iyzico ve PayTR gibi sağlayıcıların da test ortamları var; yerel sağlayıcılarda bildirim imzasının ya da hash’inin nasıl doğrulanacağını kendi dokümantasyonlarından ajana okut.
7. Stok
Stok iki kişinin aynı son ürünü aynı anda alabileceği yerdir. Ajanlar bunu genelde “önce oku, sonra yaz” şeklinde yazar ve arada yarış durumu (race condition) oluşur. Doğrusu, kontrolü ve düşmeyi tek bir atomik sorguda yapmak:
UPDATE variants SET stock = stock - 2
WHERE id = 'var_123' AND stock >= 2;
-- etkilenen satır 0 ise stok yetmedi
Stoğu ödeme kesinleşince (webhook’ta) düşmek basittir; çok sınırlı ürünlerde ödeme oturumu açılırken kısa süreli bir rezervasyon da düşünebilirsin. Hangisini seçtiğini ajana açıkça söyle.
8. E-postalar
En azından iki e-posta gerekir: sipariş onayı ve kargo bildirimi. Onay e-postasını “başarılı” sayfasından değil, webhook’tan gönder; böylece yalnızca gerçekten ödenmiş siparişlere gider. E-posta servisinin API anahtarı sunucuda kalır. Gönderen alan adı için servisin istediği SPF/DKIM kayıtlarını eklemezsen e-postaların spam klasörüne düşebilir.
9. Yasal sayfalar
Bu kısım kod değil ama mağazanın parçası. Türkiye’de satış yapıyorsan en azından şunlar gerekir:
- KVKK aydınlatma metni ve gerekiyorsa açık rıza metni
- Çerez politikası
- Mesafeli satış sözleşmesi
- Ön bilgilendirme formu (sipariş tamamlanmadan önce gösterilir ve onaylanır)
- İade ve cayma hakkı koşulları
- Satıcının unvanı, adresi, iletişim bilgileri
Ön bilgilendirme formu ve mesafeli satış sözleşmesi ödeme adımında gösterilmeli ve kullanıcının onayı alınmalı; ajana bu onay kutusunu ve onayın siparişle birlikte kaydedilmesini ekletebilirsin. Yapay zeka bu metinlerin taslağını çıkarabilir, ama yayına almadan önce mutlaka bir hukukçuya ya da mali müşavirine kontrol ettir; fatura düzenleme yükümlülüklerini de onlarla konuş.
10. Yayın
Next.js projesini Vercel’e, veritabanını yönetilen bir PostgreSQL servisine koymak en kısa yol. Yayından önce:
- Ortam değişkenlerini (veritabanı adresi, ödeme ve e-posta anahtarları, webhook sırrı) barındırma servisinin panelinden gir.
- Ödeme sağlayıcısının panelinde canlı webhook adresini kaydet; canlı ve test anahtarlarını karıştırma.
- Migration’ları üretim veritabanına kontrollü çalıştır, öncesinde yedek al.
- Canlıda küçük tutarlı gerçek bir sipariş ver, iade et ve tüm akışı (e-posta, stok, sipariş durumu) gözünle doğrula.
Yapay zekanın e-ticarette sık yaptığı hatalar
- Toplamı istemcide hesaplayıp sunucuya göndermek. En tehlikelisi. Kodda istemciden gelen
priceya datotalarıyorsan bul ve sil. - Başarılı sayfasında siparişi “ödendi” yapmak. Webhook olmadan sipariş durumu değişmemeli.
- Webhook imzasını doğrulamamak ya da gövdeyi JSON’a çevirdikten sonra doğrulamaya çalışıp “çalışmıyor” diye doğrulamayı kapatmak.
- Float ile para.
0.1 + 0.2hatası faturaya yansır. - İdempotensi yok. Aynı webhook iki kez gelince stok iki kez düşer, iki e-posta gider.
- Yönetim paneli korumasız.
/adminsayfasını yazar ama API rotalarında yetki kontrolünü unutur. Her admin API’sinin sunucuda rolü kontrol ettiğinden emin ol. - Test anahtarlarıyla canlıya çıkmak ya da tersine, geliştirme sırasında canlı anahtar kullanmak.
Güvenlik
- Kart verisini asla saklama, loglama ya da kendi formunla toplama. Sağlayıcının barındırdığı ödeme sayfasını ya da formunu kullan; bu, PCI DSS kapsamını en aza indirir.
- Sırlar
.env’de,.env.gitignore’da. Gizli anahtarı (sk_...gibi) istemci koduna ya da herkese açık ortam değişkenlerine (Next.js’teNEXT_PUBLIC_önekli olanlar) koyma. - API anahtarlarını sohbete yapıştırma. Ajana anahtarın değişken adını söyle, değerini değil.
- Ajanın komutlarını oku. Üretim veritabanına bağlı bir terminalde migration,
DROPya da topluUPDATEkomutlarına otomatik onay verme. - Her diff’i oku, özellikle ödeme ve yetki kodunu. Burada ikinci bir göz şart; yapay zeka kod incelemesi yazısında bunun nasıl kurulacağını anlattım.
- Kişisel verileri en aza indir. İhtiyacın olmayan veriyi toplama; topladığını erişimi sınırlı bir şekilde sakla.
Bunu AgentVera ile yapmak
Bir mağaza projesinde birkaç ajanı ayrı tutmak işe yarıyor ve ben bunu AgentVera ile yapıyorum:
- Arka uç ve arayüz ayrı worktree’lerde. Bir Claude Code ajanı ödeme, webhook ve veri modeli üzerinde, bir Codex ajanı ürün sayfaları ve sepet arayüzünde çalışır. Her biri kendi git worktree’sinde, hepsi tek bir çalışma alanında.
- Veritabanı yöneticisi. Ajanın yazdığı tabloya, siparişlere ve stoğa ayrı bir araç açmadan veritabanı yöneticisinden bakarsın; PostgreSQL, MySQL ve SQLite destekleniyor.
- DB Guard. Ajanın yazdığı migration’ları tur sonunda tarar;
DROP, WHERE’sizUPDATEgibi riskleri DB Guard önceden gösterir. - Kod incelemesi ve önizleme. Tur bitince kod incelemesi ikinci bir modelle bakar; önizleme ortamları her worktree’nin dev sunucusunu kendi adresinde açar. Ödeme kodunu birleştirmeden önce diff’i yine kendin oku.
Bunlar işi senin yerine doğru yapmaz; neyin değiştiğini görmeni kolaylaştırır.
Kısa kontrol listesi
- Hazır platform mu özel site mi kararı bilinçli verildi
- Fiyatlar kuruş cinsinden tamsayı; sipariş kalemi fiyatı kopyalıyor
- Sepet yalnızca kimlik ve adet tutuyor; toplam sunucuda hesaplanıyor
- Sipariş yalnızca imzası doğrulanmış webhook ile “ödendi” oluyor; webhook idempotent
- Stok atomik sorguyla düşüyor
- Onay e-postası webhook’tan gidiyor; SPF/DKIM tamam
- KVKK, mesafeli satış sözleşmesi, ön bilgilendirme formu, iade koşulları yayında ve kontrol edildi
- Kart verisi hiçbir yerde yok; sırlar yalnızca sunucuda
- Canlıda gerçek bir sipariş verilip iade edildi
Sonuç
Yapay zeka ile e-ticaret sitesi yapmak mümkün ve bir ajan işin büyük kısmını hızla yazar. Ama mağazayı güvenilir yapan şeyler ajanın kendiliğinden yapacağı şeyler değil: fiyatın sunucuda hesaplanması, ödemenin webhook ile doğrulanması, stoğun atomik düşmesi, kart verisinin hiç tutulmaması ve doğru yasal metinler. Bu kuralları ilk prompt’a yaz, her adımı test modunda dene ve ödeme kodunu birleştirmeden önce mutlaka oku.