İlk dijital ürünüm için kurduğum satış altyapısı
Bu altyapıda ödeme yok, sipariş de yok. Önce teslimatı, izni ve “hayır” diyebilmeyi kurdum — ve en pahalı ders, bir kusuru düzeltirken ürettiğim yeni kusurdan çıktı.

Bu altyapıda ödeme yok.
Sipariş tablosu boş, ödeme sağlayıcısı seçilmedi, kredi kartı alan bir ekran yazılmadı. "Satış altyapısı" derken kastettiğim şey checkout değil; onun etrafındaki her şey. Ve bu sıralama bir eksiklik değil, karar.
Çünkü ürünü teslim edemiyorsan ödeme alman bir işe yaramıyor. Teslimatın çalıştığını gördükten sonra ödeme eklemek bir günlük iş. Tersi doğru değil.
Önce teslimat, ve teslimat e-posta demek
Ürün bir e-kitap, teslimat bir e-posta. Kulağa iki saatlik iş gibi geliyor. Değildi.
E-posta HTML'i web HTML'i değil. Gmail var() desteklemiyor, yani sitenin tasarım token'larının hiçbiri çalışmıyor. Outlook'un Windows sürümü sayfayı Word motoruyla çiziyor, yani düzen tablo olmak zorunda ve bağlantıya verdiğin iç boşluk yok sayılıyor — düğmeler tablo olarak kuruluyor. SVG hiç çizilmiyor, marka işareti PNG'ye çevriliyor. Outlook masaüstü görselleri varsayılan olarak engelliyor, o yüzden markayı metin söylüyor, işaret yanında duruyor.
Sonra iPhone'da posta tamamen ters döndü. color-scheme: light yazmak istemciyi ters çevirmekten alıkoymuyor; koyu modu postanın kendisi yönetmek zorunda. Satır içi stiller <style> bloğunu yendiği için koyu paletteki her kural !important taşıyor.
Bu ayrıntıların tek tek önemi yok. Önemli olan şu: teslimat, ödeme ekranından daha çok kırılgan parça içeriyordu.
İzin: onay kutusu yok, ve olmamalı
Bülten formunda "aydınlatma metnini okudum" kutusu yok. Bu bir unutma değil.
KVKK Kurulu'nun 2026/347 sayılı ilke kararı aydınlatma metni için onay istenmemesini söylüyor — aydınlatma bir bilgilendirmedir, rıza değil. Kaynağın teslimi ise sözleşmenin ifasına dayanıyor (m.5/2-c), yani ayrıca açık rıza aranmıyor. Ticari elektronik ileti onayı (6563) bambaşka bir kurum ve bu ikisiyle birleştirilemez.
Bir kuralın yazılı olması onun uygulandığı anlamına gelmediği için, kaynak üzerinde denetleyen bir betik var: formda bir onay kutusu belirirse denetim bunu söylüyor.
Asıl iş "hayır" diyebilmekte
Ayrılma bağlantısı bir sayfaya gidiyor, sayfadaki düğme ayırıyor. Doğrudan ayırmıyor.
Sebep şu: e-postadaki bağlantıyı yalnız insan tıklamıyor. Gmail, Outlook ve kurumsal güvenlik ağ geçitleri gelen postadaki her bağlantıyı önceden açıyor. Ayrılmayı bir GET isteğine bağlarsan, postayı hiç okumamış kişiler tarayıcı yüzünden listeden düşer ve bunu kimse fark etmez. Kayıp sessiz olur.
Yanında RFC 8058 tek tık ayrılma var: Gmail'in kendi "listeden çık" düğmesi ayrı bir uca form kodlu POST atıyor. İki biçim tek yerde ayrıştırılıyor, çünkü ikisini iki ayrı yerde çözmek bir gün ikisinin ayrışması demekti.
Bir de satır silinmiyor. unsubscribed_at işaretleniyor. Silmek daha temiz görünürdü ama silinen satır aynı adresin ertesi gün yeniden eklenmesini engellemez — ve o kişi haklı olarak "ayrıldım, yine geliyor" der.
Bir düzeltmenin ürettiği yeni kusur
Bu bölüm altyapının en pahalı dersini taşıyor.
Ayrılmış bir adres bir daha asla abone olamıyordu. Formu dolduruyor, ekranda "Kaydın alındı" görüyor, hiçbir şey gelmiyor. Kişi açısından bu, çalışmayan bir siteden ayırt edilemez.
Düzeltme açıktı: ayrılmış adrese bir onay postası gönder, geri dönüşü sahibine sordur. Bir form gönderimi bir ayrılma talebini geçersiz kılamaz, çünkü formu dolduranın o adresin sahibi olduğuna dair elimizde hiçbir kanıt yok. Adresi bilen herkes doldurabilir.
Denetim burada durmadı ve iyi ki durmadı. İlk tasarımda tekrarı yalnızca 24 saatlik bir pencere seyreltiyordu, yani durdurmuyordu. Adresi bilen üçüncü bir kişi her gün bir kez formu gönderip, ayrılmış birine bizim alan adımızdan süresiz olarak posta attırabiliyordu. Kurbanın çıkış yolu yoktu: postanın kendisi "bir şey yapmana gerek yok" diyor, listeden çıkma bağlantısı zaten ayrılmış birini tekrar ayırıyor, ve "bir daha sorma" diye bir kayıt tutulmuyordu.
Düzeltmeden önceki hâl garantili sıfır postaydı. Yani düzeltme, kusuru kapatırken önceki durumdan daha kötü bir şey üretiyordu. Çözüm bir deneme sayacı oldu: o adrese kaç onay postası gittiğinin üst sınırı.
Buradan çıkan kural bende kaldı: bir kusuru düzeltirken önceki hâlden daha kötü bir durum üretmek kabul edilemez. Ve bunu düzeltmeyi yazarken değil, denetimi yaparken fark ettim.
Ne ölçüyorum, ne ölçmüyorum
Kaynak sayfasını kaç kişi gördü, kaçı formu gönderdi — bu ikisi kendi tablomda sayılıyor. Sayaç ziyaretçiye ait hiçbir şey yazmıyor: ne IP, ne özet, ne oturum, ne çerez. Bedeli, tekil ziyaretçi sayamamak. Kabul ettim, çünkü buranın işi oran.
Dönüşüm oranı, görüntüleme sıfırken sıfır değil boş gösteriliyor. "Kimse görmedi" ile "gördü ama dönüşmedi" bambaşka iki şey ve sıfıra bölmeyi sıfır yazarak kapatmak, olmayan bir başarısızlığı raporlamak olurdu.
Bilmediğim şey
Bu altyapının satış yaptığını bilmiyorum, çünkü henüz bir satış yok. Yazdığım şey çalışan bir sistemin anlatısı değil; kurulmuş bir sistemin envanteri ve kararların gerekçeleri.
Bir de sıralamanın doğru olduğundan emin değilim. "Önce teslimat, sonra ödeme" bana mantıklı geliyor ama tersini deneyip karşılaştırmadım. Belki ödeme ekranı olmadan yapılan hiçbir şey talebi test etmiyor ve ben aylarca kimsenin istemediği bir şeyin altyapısını kurdum. Bunu ancak ödeme eklendiğinde öğreneceğim.



