Webhook entegrasyonlarını hata ayıklama: imzalar, yeniden denemeler, yeniden oynatma, olay günlükleri
İmzaları standardize ederek, yeniden denemeleri güvenli hâle getirerek, yeniden oynatma etkinleştirerek ve aranabilir olay günlükleri tutarak webhook entegrasyonlarını nasıl hata ayıklayacağınızı öğrenin.

Webhook entegrasyonları neden kara kutuya dönüşür
Webhook, bir şey olduğunda bir uygulamanın sizin uygulamanızı araması demektir. Bir ödeme sağlayıcısı size “ödeme başarılı” der, bir form aracı “yeni gönderim” der veya bir CRM “fırsat güncellendi” raporlar. Basit hisseder, ta ki bir şey bozulana ve açılacak bir ekran, belirgin bir geçmiş veya güvenli bir yeniden oynatma yolu olmadığını fark edene kadar.
İşte bu yüzden webhook sorunları bu kadar sinir bozucudur. İstek gelir (veya gelmez). Sisteminiz bunu işler (veya başarısız olur). İlk sinyal çoğunlukla “müşteriler ödeme yapamıyor” ya da “durum güncellenmedi” gibi belirsiz bir destek talebidir. Sağlayıcı yeniden denerse çoğaltmalar alabilirsiniz. Bir yük alanı değişirse ayrıştırıcınız sadece bazı hesaplar için kırılabilir.
Yaygın belirtiler:
- Gönderilip gönderilmediğini veya sadece işlenmediğini anlayamadığınız “eksik” olaylar
- Çift teslimatlar ve bunun yarattığı yan etkiler (iki fatura, iki e-posta, iki durum değişikliği)
- Yalnızca bazen başarısız olan payload değişiklikleri (yeni alanlar, eksik alanlar, yanlış tipler)
- Bir ortamda geçen imza kontrollerinin başka bir ortamda başarısız olması
Hata ayıklanabilir bir webhook kurulumunun karşıtı tahmine dayalı çalışmadır. İzlenebilir (her teslimatı ve onunla ne yaptığınızı bulabilirsiniz), tekrarlanabilir (geçmiş bir olayı güvenle yeniden oynatabilirsiniz) ve doğrulanabilir (kaynak ve işleme sonuçlarını kanıtlayabilirsiniz). Birisi “bu olayın başına ne geldi?” diye sorduğunda, dakikalar içinde kanıtla cevap verebilmelisiniz.
AppMaster gibi bir platformda uygulama geliştiriyorsanız bu zihniyet daha da önem kazanır. Görsel mantık hızlı değişebilir, ancak yine de net bir olay geçmişine ve dış sistemlerin asla kara kutu haline gelmemesi için güvenli yeniden oynatmaya ihtiyacınız vardır.
Webhook'ları gözlemlenebilir kılmak için gereken asgari veriler
Baskı altında hata ayıklarken her seferinde aynı temellere ihtiyaç duyarsınız: güvenilir, aranabilir ve yeniden oynatılabilir bir kayıt. Bunlar yoksa her webhook birer tekil gizem haline gelir.
Sisteminizde tek bir webhook “olayı”nın ne anlama geldiğine karar verin. Ona bir makbuz gibi davranın: bir gelen istek bir saklanan olay eşittir, işleme sonra olsa bile.
En azından saklayın:
- Olay ID'si: sağlarken sağlayıcının ID'sini kullanın; yoksa siz oluşturun.
- Güvenilir alım verisi: ne zaman aldığınız ve kimin gönderdiği (sağlayıcı adı, uç nokta, IP varsa).
received_at'i payload içindeki zaman damgalarından ayrı tutun. - İşleme durumu ve nedeni: küçük bir durum kümesi kullanın (received, verified, handled, failed) ve kısa bir hata nedeni saklayın.
- Ham istek ve ayrıştırılmış görünüm: denetimler ve imza kontrolleri için ham body ve başlıkları tam olarak saklayın; arama ve destek için ayrıştırılmış JSON görünümü de saklayın.
- Korelasyon anahtarları: aranabilir alanlardan biri veya ikisi (order_id, invoice_id, user_id, ticket_id).
Örnek: bir ödeme sağlayıcısı “payment_succeeded” gönderir ama müşteriniz hâlâ ödememiş görünür. Olay günlüğünüz ham isteği içeriyorsa imzayı doğrulayabilir ve tam tutar ile para birimini görebilirsiniz. Ayrıca invoice_id içeriyorsa destek, faturaya göre olayı bularak onun “failed” durumunda takılı kaldığını görür ve mühendisliğe net bir hata nedeni aktarabilir.
AppMaster içinde pratik bir yaklaşım, Data Designer'da bir “WebhookEvent” tablosu oluşturmak ve her adım tamamlandıkça durumu güncelleyen bir Business Process kullanmaktır. Araç mesele değil; tutarlı kayıt önemlidir.
Logların okunabilir olması için olay yapısını standardize edin
Her sağlayıcı farklı bir payload biçimi gönderiyorsa loglarınız her zaman dağınık hissedecektir. Sabit bir olay “zarfı” hata ayıklamayı hızlandırır çünkü veriler değişse bile aynı alanlara bakarak tarama yapabilirsiniz.
Kullanışlı bir zarf tipik olarak şunları içerir:
id(benzersiz olay id'si)type(ör.invoice.paidgibi anlaşılır olay adı)created_at(olayın gerçekleştiği zaman, sizin aldığınız zaman değil)data(iş yükü payload'u)version(ör.v1)
Aşağıda olduğu gibi basit bir örneği olduğu gibi kaydedip depolayabilirsiniz:
{
"id": "evt_01H...",
"type": "payment.failed",
"created_at": "2026-01-25T10:12:30Z",
"version": "v1",
"correlation": {"order_id": "A-10492", "customer_id": "C-883"},
"data": {"amount": 4990, "currency": "USD", "reason": "insufficient_funds"}
}
Bir adlandırma stilini seçin (snake_case veya camelCase) ve ona sadık kalın. Tipler konusunda da katı olun: amount bazen string bazen sayı olmasın.
Versiyonlama sizin emniyet ağınızdır. Alanları değiştirmeniz gerektiğinde v2 yayınlayın ve bir süre v1 çalışmaya devam etsin. Bu destek vakalarını önler ve yükseltmeleri hata ayıklamayı kolaylaştırır.
Tutarlı ve test edilebilir imza doğrulaması
İmzalar webhook uç noktanızın açık kapı haline gelmesini önler. Doğrulama olmadan URL'inizi öğrenen herkes sahte olay gönderebilir ve saldırganlar gerçek istekleri değiştirmeye çalışabilir.
En yaygın desen paylaşılan sırla HMAC imzasıdır. Gönderici ham istek gövdesini (en iyisi) veya kanonik bir dizgeyi imzalar. Siz HMAC'i yeniden hesaplayıp karşılaştırırsınız. Birçok sağlayıcı, yakalanmış isteklerin daha sonra yeniden oynatılmasını önlemek için imzaya bir zaman damgası dahil eder.
Bir doğrulama rutininin sıkıcı ve tutarlı olması gerekir:
- JSON ayrıştırılmadan önce ham gövdeyi tam olarak okuyun.
- Sağlayıcının algoritması ve sizin sırrınızla HMAC'i yeniden hesaplayın.
- Sabit zamanlı bir fonksiyonla karşılaştırın.
- Eski zaman damgalarını reddedin (kısa bir pencere kullanın, birkaç dakika gibi).
- Kapalı başarısızlık: eksik veya bozuk bir şey varsa geçersiz sayın.
Bunu test edilebilir yapın. Doğrulamayı küçük bir fonksiyona koyun ve bilinen-iyi ile bilinen-kötü örneklerle test yazın. Yaygın zaman kaybı ayrıştırılmış JSON yerine ham baytları imzalamamaktır.
Gün başından itibaren gizli anahtar döndürmeyi planlayın. Geçişler sırasında iki aktif sırrı destekleyin: önce en yeniyi deneyin, sonra öncekiye geri dönün.
Doğrulama başarısız olduğunda gizli bilgileri sızdırmadan hata ayıklamaya yetecek kadar günlük kaydı tutun: sağlayıcı adı, zaman damgası (çok eski olup olmadığı), imza versiyonu, istek/korelasyon ID'si ve ham gövdenin kısa bir hash'i (gövdeyi kendisini değil).
Tekrarlamalar ve yan etki oluşturmadan idempotentlik
Yeniden denemeler normaldir. Sağlayıcılar zaman aşımında, ağ kopmalarında veya 5xx cevaplarda yeniden dener. Sisteminiz işi yapmış olsa bile, sağlayıcı yanıtınızı zamanında alamamış olabilir, bu yüzden aynı olay tekrar gelebilir.
Önceden hangi yanıtların “yeniden dene” veya “durdur” anlamına geldiğine karar verin. Birçok ekip şu kuralları kullanır:
- 2xx: kabul edildi, yeniden deneme durdurulsun
- 4xx: yapılandırma veya istek problemi, genellikle yeniden denemeyi durdur
- 408/429/5xx: geçici hata veya rate limit, yeniden dene
Idempotentlik, aynı olayı birden çok kez güvenle işleyebilmek demektir; yan etkilerin (iki kez ücretlendirme, çift sipariş oluşturma, iki e-posta gönderme) tekrarlanmasını önler. Webhook'ları en az bir kez teslim (at-least-once) olarak kabul edin.
Pratik bir desen, gelen her olayın benzersiz ID'sini ve işleme sonucunu saklamaktır. Tekrar teslimatta:
- Eğer başarılıysa, 2xx dönün ve hiçbir şey yapmayın.
- Eğer başarısızsa, dahili işleme yeniden deneyin (veya yeniden denemeye uygun bir durum döndürün).
- Eğer işlemdeyse, paralel çalışmayı önleyin ve kısa bir “kabul edildi” yanıtı döndürün.
Dahili yeniden denemeler için üstel geri çekilme (exponential backoff) ve maksimum deneme sayısı kullanın. Limit aşıldığında olayı "inceleme gerekiyor" durumuna taşıyın ve son hatayı saklayın. AppMaster içinde bu, olay ID'leri ve durumları için küçük bir tablo ve yeniden denemeleri planlayıp tekrarlayan hataları yönlendiren bir Business Process ile temiz şekilde eşleşir.
Destek ekiplerinin sorunları hızlıca çözmesini sağlayan yeniden oynatma araçları
Yeniden denemeler otomatik; yeniden oynatma kasti.
Bir yeniden oynatma aracı “gönderildiğini düşünüyoruz” durumunu aynı payload ile tekrarlanabilir bir teste dönüştürür. Bu sadece iki koşul doğruysa güvenlidir: idempotentlik ve denetim izi. Idempotentlik çift ücretlendirme, çift sevkiyat veya çift e-posta göndermeyi engeller. Denetim izi kimin neyi yeniden oynattığını ve sonuçlarını gösterir.
Tek olay yeniden oynatma vs zaman aralığı yeniden oynatma
Tek olay yeniden oynatma destek için yaygındır: bir müşteri, bir başarısız olay, düzeltme sonrası yeniden gönder. Zaman aralığı yeniden oynatma ise bir sağlayıcı kesintisinde kullanılır: belirli bir zaman penceresinde başarısız olan her şeyi tekrar göndermeniz gerekir.
Seçimi basit tutun: olay türü, zaman aralığı ve durum (failed, timed out veya teslim edildi ama onaylanmadı) ile filtreleyin; sonra tek bir olayı veya bir partiyi yeniden oynatın.
Kaza önleyici tedbirler
Yeniden oynatma güçlü olmalı ama tehlikeli olmamalı. Bazı korumalar yardımcı olur:
- Role dayalı erişim
- Hedef başına oran sınırları
- Denetim kaydında saklanan zorunlu açıklama notu
- Büyük toplu yeniden oynatmalar için isteğe bağlı onay
- Göndermeden doğrulayan bir kuru çalıştırma (dry-run) modu
Yeniden oynatma sonrası orijinal olayın yanında sonucu gösterin: başarılı, hâlâ hata veriyor (son hata ile) veya yoksayıldı (idempotentlik ile çoğaltma tespit edildi).
Olay günlükleri — olay anlarında işe yarayan bilgiler
Webhook bir olayı aksattığında dakikalar içinde cevaplara ihtiyacınız olur. İyi bir günlük net bir hikaye anlatır: ne geldi, onunla ne yaptınız ve nerede durdu.
Ham isteği tam olarak saklayın: zaman damgası, yol, yöntem, başlıklar ve ham gövde. Sağlayıcı alanları değiştirdiğinde veya ayrıştırıcınız verileri yanlış okuduğunda ham payload tek gerçek kaynaktır. Kaydetmeden önce gizli değerleri maskalayın (authorization başlıkları, token'lar ve ihtiyaç duymadığınız kişisel veya ödeme verileri).
Ham veri tek başına yeterli değildir. Ayrıca aranabilir bir ayrıştırılmış görünüm saklayın: olay türü, dış olay ID'si, müşteri/hesap tanımlayıcıları, ilgili obje ID'leri (invoice_id, order_id) ve sizin iç korelasyon ID'niz. Bu, destek ekibinin “müşteri 8142 için tüm olayları” her payload'ı açmadan bulmasını sağlar.
İşleme sırasında tutarlı ifadelerle kısa bir adım zaman çizelgesi tutun; örneğin: “validated signature”, “mapped fields”, “checked idempotency”, “updated records”, “queued follow-ups”.
Saklama süresi önemli. Gerçek gecikmeleri ve itirazları karşılayacak kadar geçmiş tutun ama sonsuza kadar biriktirmeyin. Ham payload'ları önce silmeyi veya anonimleştirmeyi düşünün, hafif meta verileri ise daha uzun saklayın.
Adım adım: hata ayıklanabilir bir webhook hattı inşa edin
Alıcıyı küçük bir boru hattı gibi kurun; net kontrol noktaları olsun. Her istek saklanan bir olay, her işleme çalışması bir deneme ve her hata aranabilir bir kayıt olsun.
Alıcı boru hattı
HTTP uç noktasını sadece alım olarak değerlendirin. Baştan minimum işi yapın, sonra işlemi bir işçiye taşıyın ki zaman aşımı gizemli davranışlara dönüşmesin.
- Başlıkları, ham gövdeyi, alım zaman damgasını ve sağlayıcıyı yakalayın.
- İmzayı doğrulayın (veya açık bir “doğrulama başarısız” durumu saklayın).
- Kararlı bir olay ID'si ile kuyruklayın.
- Idempotency kontrolleri ve iş mantığı ile bir işçi tarafından işleyin.
- Sonucu (başarı/başarısızlık) ve yardımcı bir hata mesajını kaydedin.
Pratikte iki temel kayıt istersiniz: her webhook olayı için bir satır ve her işleme denemesi için bir satır.
Sağlam bir olay modeli şunları içerir: event_id, provider, received_at, signature_status, payload_hash, payload_json (veya ham payload), current_status, last_error, next_retry_at. Deneme kayıtları şunları saklayabilir: attempt_number, started_at, finished_at, http_status (varsa), error_code, error_text.
Veri oluştuğunda, destek ekibinin event ID, müşteri ID veya zaman aralığı ile arama yapabileceği küçük bir yönetici sayfası ekleyin; duruma göre filtreleme sunun. Sade ve hızlı bir arayüz yapın.
Uyarıları tekil hatalara değil desenlere göre ayarlayın. Örneğin: “sağlayıcı 5 dakikada 10 kez hata verdi” veya “olay failed durumunda takılı kaldı”.
Gönderen taraf beklentileri
Eğer gönderme tarafını kontrol ediyorsanız üç şeyi standardize edin: her zaman bir olay ID'si ekleyin, her zaman payload'u aynı şekilde imzalayın ve düz bir dille bir yeniden deneme politikası yayınlayın. Bu, bir ortak “gönderdik” dediğinde ve sisteminiz hiçbir şey göstermediğinde bitmeyen tartışmaları önler.
Örnek: bir ödemeler webhook'unun 'failed' durumundan 'fixed'e geçişi ve yeniden oynatma
Yaygın bir desen, bir Stripe webhook'unun iki şey yapmasıdır: bir Order kaydı oluşturur, sonra bir makbuz e-posta/SMS gönderir. Basit gibi görünür; ta ki bir olay başarısız olana ve kimsenin müşterinin ücretlendirilip ücretlendirilmediğini, siparişin var olup olmadığını veya makbuzun gönderilip gönderilmediğini bilmemesine kadar.
Gerçekçi bir hata: Stripe imzalama sırrınızı döndürürsünüz. Birkaç dakika boyunca uç noktanız hâlâ eski sırla doğruluyorsa Stripe olayları gönderir ama sunucunuz bunları 401/400 ile reddeder. Panoda “webhook failed” gözükürken uygulama log'larınız sadece “invalid signature” der.
İyi loglar nedeni açıkça gösterir. Başarısız olay için kayıt, kararlı bir olay ID'si ve uyumsuzluğu belirleyecek kadar doğrulama detayı göstermelidir: imza versiyonu, imza zaman damgası, doğrulama sonucu ve açık bir reddetme nedeni (yanlış sırrı kullanma vs zaman damgası sapması). Döndürme sırasında hangi sır denendiğini (“current” vs “previous” gibi), ham sırrı değil, kaydetmek faydalıdır.
Sırrı düzelttikten ve kısa bir pencere için hem "current" hem de "previous" kabul edildikten sonra, birikmiş işleri hâlâ ele almanız gerekir. Bir yeniden oynatma aracı bunu hızlı bir işe dönüştürür:
- Olayı event_id ile bulun.
- Hata nedeninin çözüldüğünü doğrulayın.
- Olayı yeniden oynatın.
- Idempotentliği doğrulayın: Order bir kez oluşturulsun, makbuz bir kez gönderilsin.
- Yeniden oynatma sonucu ve zaman damgalarını ticket'a ekleyin.
Yaygın hatalar ve nasıl kaçınılır
Çoğu webhook sorunu sistemler yalnızca son hatayı kaydettiği için gizemli görünür. Her teslimatı küçük bir olay raporu gibi ele alın: ne geldi, ne kararlaştırdınız ve sonra ne oldu.
Tekrarlayan bazı hatalar:
- Sadece istisnaları loglamak yerine tam yaşam döngüsünü (received, verified, queued, processed, failed, retried) kaydetmeme
- Maskelenmeden tam payload ve başlıkları saklamak; sonra gizli veya kişisel verileri yakaladığınızı fark etmek
- Yeniden denemeleri tamamen yeni olaylar gibi ele almak ve bunun çift ücretlendirme veya çoğaltmalara yol açması
- Olay dayanıklı şekilde saklanmadan 200 OK döndürmek; böylece panolar yeşil görünürken işler sonra kaybolur
Pratik düzeltmeler:
- Minimal, aranabilir bir istek kaydı ve durum değişiklikleri saklayın.
- Varsayılan olarak hassas alanları maskalayın ve ham payloadlara erişimi kısıtlayın.
- Idempotentliği sadece kodda değil veritabanı seviyesinde zorunlu kılın.
- Olay güvenle saklanmadan onay vermeyin.
- Yeniden oynatmayı desteklenen bir akış olarak inşa edin, tek seferlik bir betik olarak değil.
AppMaster kullanıyorsanız bu parçalar doğal olarak platforma uyar: Data Designer'da bir olay tablosu, doğrulama ve işleme için durum odaklı Business Process'ler ve arama ile yeniden oynatma için bir yönetici UI'sı oluşturabilirsiniz.
Hızlı kontrol listesi ve sonraki adımlar
Her seferinde aynı temellere ulaşmayı hedefleyin:
- Her olayın benzersiz bir event_id'si olsun ve ham payload alındığı gibi saklansın.
- Her istekte imza doğrulaması çalışsın ve başarısızlıklar açık bir neden içersin.
- Yeniden denemeler öngörülebilir olsun ve işlemciler idempotent olsun.
- Yeniden oynatma yetkili rollerle sınırlı olsun ve bir denetim izi bıraksın.
- Loglar event_id, provider id, durum ve zaman ile aranabilir olsun; kısa bir “ne oldu” özeti bulunsun.
Bunlardan sadece birinin eksik olması bile entegrasyonu kara kutuya çevirebilir. Ham payload'u saklamazsanız sağlayıcının ne gönderdiğini kanıtlayamazsınız. İmza hataları spesifik değilse kimin hatalı olduğunu tartışmakla saatler harcarsınız.
Bunu el ile her bileşeni yazmadan çabuk kurmak isterseniz, AppMaster size veri modelini, iş akışlarını ve yönetici UI'sını tek bir yerde bir araya getirmede yardımcı olabilir; aynı zamanda gerektiğinde gerçek kaynak kodu da üretir.


