Bir müşteri ödeme düğmesine bastığında bağlantı zaman aşımına uğrayabilir. Tarayıcı yanıtı alamasa bile ödeme sağlayıcısı işlemi başarıyla tamamlamış olabilir. Kullanıcı tekrar denerse veya uygulama isteği otomatik olarak yeniden gönderirse aynı sipariş için ikinci tahsilat oluşma riski doğar. Benzer problem sipariş oluşturma, bakiye yükleme, fatura kesme ve webhook işleme süreçlerinde de görülür.
Idempotency, aynı mantıksal işlem birden fazla kez gönderildiğinde sistemin ilk başarılı işlemden sonra ek yan etki üretmemesini sağlar. Amaç her isteğe aynı HTTP cevabını vermek değil; ikinci kez ödeme almak, iki sipariş açmak veya aynı webhook nedeniyle iki e-posta göndermek gibi istenmeyen sonuçları önlemektir.
Bu rehber sanal POS entegrasyonunun genel adımlarına girmez. Odak; güvenli yeniden deneme, idempotency key tasarımı, sonuç saklama, eş zamanlı istekler ve ödeme veya webhook tekrarlarının nasıl yönetileceğidir.
Idempotency nedir?
Idempotency, bir işlemin aynı girdilerle birden fazla kez uygulanmasının sistemde ilk uygulamadan daha fazla değişiklik oluşturmaması özelliğidir. Örneğin bir kullanıcının teslimat adresini belirli bir değere ayarlamak tekrarlandığında sonuç değişmez. Buna karşılık “bakiyeye 100 TL ekle” işlemi iki kez çalışırsa bakiye iki kez artar ve doğal olarak idempotent değildir.
HTTP Semantics standardı, bir metodun birden fazla özdeş istek sonucundaki amaçlanan sunucu etkisi tek istekle aynıysa idempotent kabul edildiğini belirtir RFC 9110 HTTP Semantics. Bu tanım, istemcinin yanıt alamadığı durumlarda hangi istekleri güvenle tekrar edebileceğini anlamak açısından önemlidir.
Idempotent işlem ile duplicate kontrolü aynı şey midir?
Duplicate kontrolü idempotency tasarımının bir parçasıdır; fakat tek başına yeterli değildir. Sunucu yalnızca aynı anahtarın daha önce görülüp görülmediğine bakarsa ilk işlem hâlâ devam ederken gelen eş zamanlı ikinci isteği yanlışlıkla çalıştırabilir. Ayrıca aynı anahtarın farklı payload ile kullanılması veri tutarsızlığı oluşturabilir.
Tam idempotency akışı; işlem kimliğini, istek içeriğini, işlem durumunu, oluşturulan kaynağı ve döndürülecek sonucu birlikte yönetir. Aynı anahtar aynı işlem için kullanıldığında mevcut sonuç döndürülür. Aynı anahtar farklı işlem parametreleriyle gelirse istek reddedilir.
HTTP metotları açısından idempotency nasıl değerlendirilir?
RFC 9110’a göre PUT ve DELETE ile güvenli HTTP metotları idempotent semantiğe sahiptir. POST ise varsayılan olarak idempotent değildir; aynı POST isteğinin iki kez gönderilmesi iki ayrı kaynak veya işlem üretebilir. Bununla birlikte uygulama, POST isteğine idempotency key ekleyerek iş mantığını idempotent hale getirebilir.
| İşlem örneği | Doğal davranış | Retry riski | Önerilen yaklaşım |
|---|---|---|---|
| GET /orders/123 | Kaynağı okur | Düşük; sunucu durumu değişmemelidir | Standart retry politikası ve zaman aşımı kontrolü |
| PUT /users/45/address | Adresi verilen değere ayarlar | Aynı payload ile sonuç aynı kalır | Kaynak sürümü ve yetki kontrolüyle tekrar edilebilir |
| DELETE /cart/items/8 | Kaynağı kaldırır | Tekrarında kaynak zaten bulunmayabilir | Son durumun silinmiş olması başarı olarak yorumlanabilir |
| POST /orders | Yeni sipariş oluşturur | İki ayrı sipariş oluşabilir | Idempotency key ve benzersiz işlem kaydı |
| POST /payments | Tahsilat başlatır | Çift tahsilat oluşabilir | Sağlayıcı ve uygulama katmanında aynı işlem anahtarı |
HTTP metodunun idempotent olması iş sürecinin tamamının otomatik olarak güvenli olduğu anlamına gelmez. DELETE isteği içinde yanlışlıkla her çağrıda yeni audit kaydı, bildirim veya ücret üretiliyorsa yan etkiler ayrıca değerlendirilmelidir.
Idempotency key nedir?
Idempotency key, istemcinin tek bir mantıksal işlemi tanımlamak için ürettiği benzersiz değerdir. Aynı işlem yeniden denendiğinde aynı anahtar kullanılır. Yeni bir sipariş veya yeni bir ödeme niyeti başladığında yeni anahtar oluşturulur.
Stripe, bağlantı hatası sonrasında aynı işlemi güvenli biçimde tekrar etmek için oluşturma ve güncelleme isteklerinde idempotency key kullanılmasını destekler Stripe Idempotent Requests. PayPal da belirli POST çağrılarında kullanıcı tarafından üretilen PayPal-Request-Id başlığıyla tekrarların ilişkilendirilmesini sağlar PayPal Idempotency.
Anahtar tahmin edilmesi zor ve yeterince benzersiz olmalıdır. UUID gibi rastgele değerler yaygın bir tercihtir. Ancak anahtarın benzersiz olması kadar yaşam döngüsü de önemlidir: kullanıcı aynı düğmeye tekrar bastığında yeni anahtar üretmek korumayı etkisiz hale getirir.
Aynı idempotency key ne zaman yeniden kullanılmalıdır?
Anahtar yalnızca aynı mantıksal işlemin teknik tekrarlarında kullanılmalıdır. İlk ödeme isteğinin yanıtı alınamadıysa aynı anahtar ve aynı parametrelerle yeniden deneme yapılır. Kullanıcı daha sonra farklı tutarda yeni bir ödeme başlatıyorsa yeni anahtar gerekir.
- Ağ zaman aşımı sonrası aynı isteğin yeniden gönderilmesinde aynı anahtarı kullanın.
- HTTP 5xx veya belirsiz bağlantı sonucunda sağlayıcının önerdiği retry politikasına uyun.
- Kullanıcının yeni bir sipariş veya yeni ödeme niyeti için yeni anahtar üretin.
- Aynı anahtarı farklı tutar, para birimi, kullanıcı veya sipariş için kullanmayın.
- Anahtarın saklama süresini hizmet sağlayıcının dokümantasyonuna göre değerlendirin.
Idempotency anahtarlarının ne kadar süre saklandığı platforma göre değişir. Bu nedenle belirli bir sağlayıcının süre politikasını evrensel standart gibi kabul etmemek gerekir. Uygulamanın kendi işlem kaydı, sağlayıcının saklama penceresinden daha uzun süre korunması gereken iş gereksinimlerini ayrıca karşılamalıdır.
Sunucu idempotency key’i nasıl işlemelidir?
Sunucu yeni bir anahtar aldığında anahtarı iş kapsamıyla birlikte kalıcı veya güvenilir bir depoda kaydetmelidir. Kayıt yalnızca anahtarı değil, istek özeti, işlem durumu, oluşturulan kaynak kimliği ve döndürülecek sonucu da içerebilir.
- İstemci anahtar ve istek payload’ını gönderir.
- Sunucu anahtarı kullanıcı, endpoint veya tenant kapsamıyla birlikte arar.
- Anahtar yoksa benzersiz kısıt altında “işleniyor” kaydı oluşturur.
- İşlemi gerçekleştirir ve sonucu kaydeder.
- Aynı anahtar tekrar gelirse kayıtlı sonucu veya mevcut işlem durumunu döndürür.
- Aynı anahtar farklı payload özetiyle gelirse çakışma hatası verir.
- Başarısızlığın retry edilebilir olup olmadığını kaydın durumuna göre belirler.
Bu mekanizma, API entegrasyonu içinde yalnızca controller seviyesinde tutulmamalıdır. Birden fazla uygulama sunucusu varsa işlem kaydı bütün örnekler tarafından görülebilen ortak ve atomik bir veri katmanında bulunmalıdır.
Payload hash neden saklanmalıdır?
Aynı idempotency key ile farklı istek içeriği gönderilirse sunucunun ikinci isteği önceki sonuca bağlaması tehlikelidir. Örneğin ilk istekte 500 TL, ikinci istekte 700 TL bulunuyorsa hangi işlemin temsil edildiği belirsizleşir. Bu nedenle normalleştirilmiş iş parametrelerinin özeti veya hash değeri kayıtla ilişkilendirilebilir.
Stripe, mevcut bir idempotency key’in farklı parametrelerle yeniden kullanılmasında hata vererek yanlış tekrarları önler Stripe Idempotent Requests. Benzer kontrol uygulamanın kendi API katmanında da yapılmalıdır.
Hash hesabına geçici alanlar, timestamp veya her denemede değişen tracing değerleri kontrolsüz eklenmemelidir. Özet, işlemin iş anlamını belirleyen alanları temsil etmelidir.
Eş zamanlı aynı istekler nasıl yönetilir?
Kullanıcının çift tıklaması veya iki retry worker’ının aynı anda çalışması, aynı idempotency key’in milisaniyeler içinde iki kez gelmesine neden olabilir. “Önce ara, sonra ekle” şeklindeki iki ayrı işlem yarış koşulu oluşturur; iki istek de anahtarı bulamayarak işlemi başlatabilir.
Çözüm, anahtar üzerinde veritabanı unique constraint, atomik insert veya uygun kilitleme kullanmaktır. İlk istek işlem kaydını oluşturur; ikinci istek benzersiz kısıta takılır ve mevcut kaydı okur. İşlem hâlâ sürüyorsa sunucu “processing” durumunu veya kontrollü bir yeniden deneme cevabını döndürebilir.
Adyen, aynı idempotency key ile gelen eş zamanlı isteklerden yalnızca birinin işlenmesini ve diğerinin geçici hata alabilmesini kendi API idempotency davranışında açıklar Adyen API Idempotency. Bu örnek, concurrency davranışının istemci retry politikasında ayrıca ele alınması gerektiğini gösterir.
Başarılı sonuç mu, hata sonucu mu saklanmalıdır?
Başarılı işlemin sonucu mutlaka işlem anahtarıyla ilişkilendirilmelidir. Tekrarlanan istekte yeni işlem yapmak yerine mevcut kaynak kimliği ve durum döndürülür. Hataların saklanması ise hata türüne göre değişir.
- Kalıcı doğrulama hatası: Aynı payload ile tekrarın sonucu değişmeyecekse kayıtlı hata döndürülebilir.
- Geçici altyapı hatası: İşlem başlamadıysa anahtar kontrollü retry için yeniden kullanılabilir.
- Belirsiz sonuç: Dış sağlayıcı işlemi tamamlamış olabilir; önce işlem durumu sorgulanmalıdır.
- İşlem devam ediyor: İkinci istek yeni işlem başlatmamalı, mevcut durumu takip etmelidir.
Stripe’ın düşük seviyeli hata rehberi, bağlantı hatasında ilk isteğin sonucunun bilinmeyebileceğini ve idempotency’nin istemciye güvenli uzlaştırma imkânı verdiğini belirtir Stripe Gelişmiş Hata Yönetimi.
Ödeme sistemlerinde idempotency neden kritiktir?
Ödeme işlemlerinde ağ zaman aşımı, kullanıcının tekrar tıklaması, mobil bağlantının kesilmesi veya sunucunun yanıtı alamaması çift tahsilat riski oluşturur. Uygulama, ödeme sağlayıcısına aynı sipariş için aynı idempotency key ile gitmeli; kendi veritabanında da sipariş ile ödeme niyetini benzersiz biçimde ilişkilendirmelidir.
Sanal POS entegrasyonu içinde yalnızca sağlayıcının idempotency desteğine güvenmek yeterli olmayabilir. Kullanıcı aynı sipariş için yeni anahtarlarla tekrar tekrar ödeme isteği oluşturabiliyorsa uygulama seviyesinde sipariş durumu ve aktif ödeme girişimi kontrol edilmelidir.
PayPal, idempotent POST çağrılarının aynı sunucu etkisini tekrar üretmeden güvenli biçimde yeniden gönderilebilmesini açıklar PayPal API Requests. Adyen de timeout sonrasında aynı ödeme isteğinin tekrar edilmesinde idempotency’nin istenmeyen çift işlemi önlediğini belirtir Adyen API Idempotency.
Ödeme akışında uygulama ve sağlayıcı anahtarı nasıl ilişkilendirilir?
En güvenli yaklaşım, işletmenin kendi ödeme girişimi kaydını oluşturmasıdır. Bu kayıt sipariş kimliği, müşteri, tutar, para birimi, durum, uygulama idempotency key’i ve sağlayıcı işlem kimliğini taşır. Sağlayıcıya gönderilen idempotency key bu ödeme girişimiyle ilişkilendirilir.
İstek zaman aşımına uğrarsa uygulama yeni ödeme girişimi açmak yerine mevcut kaydı bulur. Aynı anahtarla sağlayıcıya tekrar gider veya sağlayıcı işlem durumunu sorgular. Başarılı webhook daha sonra gelirse aynı ödeme kaydı güncellenir; yeni sipariş veya tahsilat oluşturulmaz.
Webhook işlemleri neden idempotent olmalıdır?
Webhook sağlayıcıları teslim başarısız olduğunda aynı olayı yeniden gönderebilir. Yanıt sağlayıcıya ulaşmadığında işlem sunucuda tamamlanmış olsa bile tekrar teslim oluşabilir. Bu nedenle webhook handler her teslimi ilk kez geliyormuş gibi yan etki üretmemelidir.
Stripe, webhook endpoint’lerinin aynı event’i birden fazla kez alabileceğini ve işlenen event kimliklerinin kaydedilerek tekrarların atlanmasını önerir Stripe Webhook Best Practices. Shopify da aynı webhook tesliminin ağ zaman aşımı veya retry nedeniyle tekrar gelebileceğini; handler’ın idempotent olması veya teslim kimliğiyle duplicate kontrolü yapması gerektiğini belirtir Shopify Webhook Deliveries.
Webhook doğrulaması ile idempotency farklı kontrollerdir. İmza doğrulaması isteğin gerçekten sağlayıcıdan geldiğini gösterir; event kimliği kontrolü ise aynı geçerli olayın ikinci kez yan etki üretmesini önler. İkisi birlikte uygulanmalıdır.
Webhook deduplication kaydı nasıl tutulmalıdır?
Webhook event kimliği, event türü, işlenme durumu ve işlenen kaynak kimliği güvenilir bir tabloda saklanabilir. Event ilk kez geldiğinde atomik olarak “processing” kaydı oluşturulur. Kayıt zaten varsa handler mevcut duruma göre başarı cevabı döndürür veya işlemin bitmesini beklemeden kontrollü biçimde çıkar.
İşlem tamamlanmadan event’i “processed” işaretlemek mesaj kaybına; iş tamamlandıktan sonra durum yazılamadan hata almak ise tekrar işlem riskine yol açar. İş verisi ile event durumunun mümkün olduğunca aynı transaction içinde güncellenmesi veya outbox benzeri güvenilir desenler kullanılması gerekir.
Veritabanı unique constraint tek başına yeterli midir?
Unique constraint güçlü bir son savunma hattıdır. Aynı sipariş numarası, ödeme girişimi veya webhook event kimliği ikinci kez eklenmeye çalışıldığında veritabanı duplicate kaydı engeller. Fakat yalnızca hatayı yakalamak, kullanıcıya doğru mevcut sonucu döndürmek için yeterli değildir.
Idempotency katmanı duplicate hatasından sonra mevcut kaynağı bulmalı ve işleme uygun cevap vermelidir. Ayrıca farklı tabloları etkileyen yan etkiler, e-posta veya harici API çağrıları unique constraint’in dışında kalabilir. Tasarım bütün iş akışını kapsamalıdır.
Idempotency key güvenlik anahtarı mıdır?
Hayır. Idempotency key kimlik doğrulama veya yetkilendirme yerine geçmez. Bir saldırgan başka kullanıcının anahtarını tahmin etse bile o işleme erişememelidir. Anahtar; kullanıcı, tenant, endpoint ve kimlik doğrulama bağlamıyla sınırlandırılmalıdır.
- Anahtarı kullanıcılar arasında global erişim anahtarı olarak kullanmayın.
- Kimlik doğrulama ve işlem yetkisini her istekte kontrol edin.
- Anahtarları loglarken hassas payload veya ödeme bilgisini sızdırmayın.
- Tek bir anahtarın sınırsız süre saklanması gerekip gerekmediğini değerlendirin.
- Temizleme işlemini aktif veya denetim gerektiren kayıtları bozmadan planlayın.
Idempotency hangi metriklerle izlenmelidir?
Üretim ortamında duplicate istek oranı, idempotency hit sayısı, aynı anahtarla farklı payload hataları, processing durumunda kalan kayıtlar, anahtar saklama süresi ve eş zamanlı çakışmalar izlenmelidir. Ödeme tarafında aynı sipariş için birden fazla sağlayıcı işlem kimliği oluşması kritik alarmdır.
Loglarda idempotency key’in tamamı yerine güvenli bir hash veya dahili işlem kimliği kullanılabilir. İstemci request ID, idempotency key, sipariş kimliği ve sağlayıcı işlem kimliği korelasyon halinde tutulursa belirsiz ödeme vakaları daha hızlı incelenir.
En sık yapılan idempotency hataları
- Her retry denemesinde yeni idempotency key üretmek.
- Aynı anahtarı farklı payload ile kabul etmek.
- Anahtarı yalnızca uygulama sunucusunun belleğinde tutmak.
- “Önce kontrol et, sonra ekle” yarış koşulunu atomik işlemle korumamak.
- İşlem sonucu yerine yalnızca “anahtar kullanıldı” bilgisini saklamak.
- Webhook imza doğrulamasını duplicate kontrolü sanmak.
- Ödeme sağlayıcısı idempotent diye uygulama sipariş durumunu kontrol etmemek.
- İşleniyor durumda kalan kayıtlar için timeout ve uzlaştırma planı oluşturmamak.
- Retry edilebilir ve kalıcı hataları ayırmamak.
- Anahtar temizleme süresini iş ve sağlayıcı davranışından bağımsız belirlemek.
Uygulama öncesi idempotency kontrol listesi
- Hangi endpoint veya işlemler ikinci kez yan etki üretebilir?
- Tek mantıksal işlem için anahtarı hangi katman üretecek?
- Retry sırasında aynı anahtarın korunması garanti mi?
- Anahtar hangi kullanıcı, tenant ve endpoint kapsamında benzersiz?
- İstek özeti veya payload hash’i karşılaştırılıyor mu?
- Eş zamanlı istekler unique constraint veya atomik işlemle engelleniyor mu?
- Processing, succeeded ve failed durumları tanımlı mı?
- Belirsiz dış servis sonucunda işlem durumu nasıl uzlaştırılacak?
- Webhook event kimliği ve iş sonucu birlikte korunuyor mu?
- Duplicate, conflict ve stuck işlem metrikleri için alarm var mı?
Sonuç: Güvenli retry, işlem kimliğini korumakla başlar
Idempotency, ağ hatalarının kaçınılmaz olduğu API ve ödeme sistemlerinde aynı işlemin güvenle tekrar edilebilmesini sağlar. Doğru tasarım; benzersiz işlem anahtarı, payload kontrolü, atomik kayıt, sonuç saklama ve mevcut işlemi yeniden kullanma davranışını birlikte içerir.
Ödeme sağlayıcısının idempotency desteği önemli bir korumadır; fakat uygulamanın sipariş, ödeme girişimi ve webhook kayıtlarını kendi iş kurallarıyla koruması gerekir. Idempotency yalnızca duplicate satırı engellemek değil, belirsiz bir isteğin hangi iş sonucuna ait olduğunu güvenilir biçimde bulabilmektir.
Sıkça Sorulan Sorular
Idempotency çift ödemeyi tamamen engeller mi?
Doğru uygulandığında aynı mantıksal ödeme isteğinin retry nedeniyle ikinci kez işlenmesini önler. Ancak kullanıcı yeni anahtarlarla yeni ödeme girişimleri oluşturabiliyorsa sipariş ve ödeme durumu uygulama seviyesinde de kontrol edilmelidir.
Idempotency key’i istemci mi sunucu mu üretmelidir?
İki yaklaşım da mümkündür. Önemli olan tek mantıksal işlem boyunca aynı anahtarın korunması, yeni işlemde yeni anahtar oluşturulması ve anahtarın kullanıcı ile işlem kapsamına bağlanmasıdır.
Aynı idempotency key farklı payload ile gönderilebilir mi?
Gönderilmemelidir. Sunucu istek parametrelerini veya payload özetini karşılaştırmalı ve aynı anahtarla farklı işlem yapılmak istenirse çakışma hatası döndürmelidir.
GET isteklerinde idempotency key gerekli midir?
GET metodu HTTP semantiğine göre güvenli ve idempotent olmalıdır. Normal okuma isteklerinde ayrıca idempotency key genellikle gerekmez; ancak istemci retry, cache ve tutarlılık davranışını yine doğru yönetmelidir.
Webhook event’i ikinci kez gelirse ne yapılmalıdır?
İmza doğrulamasından sonra event veya teslim kimliği güvenilir depoda kontrol edilmelidir. Daha önce başarıyla işlendi ise yeni yan etki üretmeden başarılı yanıt dönülmelidir.
Idempotency kaydı ne kadar süre saklanmalıdır?
Tek bir evrensel süre yoktur. Sağlayıcının idempotency penceresi, istemci retry süresi, ödeme uzlaştırma ihtiyacı, webhook teslim politikası ve denetim gereksinimi birlikte değerlendirilmelidir.