Node.js İle Webhook Kullanarak Ödeme Bildirimleri Alma Nasıl Yapılır?

Node.js İle Webhook Kullanarak Ödeme Bildirimleri Alma Nasıl Yapılır?
Node.js İle Webhook Kullanarak Ödeme Bildirimleri Alma Nasıl Yapılır?

Gereksinimler ve Ön Hazırlık

Projeye başlamadan önce geliştirme ortamınızın güncel olduğundan emin olmalısınız. 2026 standartlarına uygun olarak Node.js'in LTS (Long Term Support) sürümünü kullanmanız önerilir.

  • Node.js (v20 veya üzeri sürüm)
  • Express.js (Hızlı ve esnek web çatısı)
  • Body-parser (Gelen istek gövdesini ayrıştırmak için)
  • Ngrok veya benzeri bir tünelleme aracı (Yerel sunucunuzu dış dünyaya açmak için)

Öncelikle projenizi oluşturun ve gerekli paketleri yükleyin:

mkdir odeme-webhook-projesi
cd odeme-webhook-projesi
npm init -y
npm install express body-parser dotenv

Bu komutlar, projenizin temel dizin yapısını oluşturacak ve gerekli bağımlılıkları package.json dosyanıza ekleyecektir.

Temel Webhook Sunucusu Kurulumu

Webhook bildirimlerini karşılamak için Express.js kullanarak basit bir POST rotası oluşturacağız. Webhook'lar her zaman POST isteği olarak gelir, bu yüzden sunucunuzun bu isteği kabul etmesi gerekir.

const express = require('express');
const bodyParser = require('body-parser');
const app = express();

// Webhook verisi genellikle JSON formatında gelir
app.use(bodyParser.json());

app.post('/webhook/odeme-bildirimi', (req, res) => {
    const veri = req.body;
    console.log('Gelen Bildirim:', veri);
    
    // İşlem başarılı alındı bilgisini sağlayıcıya gönder
    res.status(200).send('Bildirim alındı');
});

app.listen(3000, () => console.log('Sunucu 3000 portunda çalışıyor.'));

Yukarıdaki kod, /webhook/odeme-bildirimi adresine gelen tüm istekleri karşılar ve konsola yazdırır. Ödeme sağlayıcısına 200 OK yanıtı döndürmek, bildirim başarıyla ulaştı mesajı iletmek için zorunludur.

Webhook Verisini Güvenli Bir Şekilde Doğrulama

Webhook'lar herkese açık bir URL üzerinden gelir. Kötü niyetli kişilerin sunucunuza sahte ödeme bildirimleri göndermesini engellemek için "İmza Doğrulama" (Signature Verification) yapmalısınız. Ödeme sağlayıcıları genellikle isteğin başlık (header) kısmına gizli bir anahtar ile imzalanmış bir değer ekler.

const crypto = require('crypto');

function dogrula(payload, imza, gizliAnahtar) {
    const hmac = crypto.createHmac('sha256', gizliAnahtar);
    const hesaplananImza = hmac.update(JSON.stringify(payload)).digest('hex');
    return hesaplananImza === imza;
}

Bu fonksiyon, gelen verinin gerçekten ödeme sağlayıcısından gelip gelmediğini kontrol eder. Güvenlik için asla imzasız gelen verileri işlemeyin.

Webhook İşleme Mantığı ve Hata Yönetimi

Bildirim alındıktan sonra veritabanı güncellemeleri yapmanız gerekir. Bu süreçte hata yönetimi, sistemin kararlılığı için kritiktir.

app.post('/webhook/odeme-bildirimi', (req, res) => {
    const imza = req.headers['x-odeme-imza'];
    
    if (!dogrula(req.body, imza, process.env.WEBHOOK_SECRET)) {
        return res.status(401).send('Geçersiz imza');
    }

    try {
        const { siparisId, durum } = req.body;
        // Veritabanı güncelleme işlemi burada yapılır
        console.log(`Sipariş ${siparisId} durumu: ${durum}`);
        res.status(200).send('İşlem tamamlandı');
    } catch (error) {
        res.status(500).send('Sunucu hatası');
    }
});

Burada try-catch bloğu kullanarak veritabanı işlemlerinde oluşabilecek hataların sunucuyu çökertmesini engelliyoruz.

Kritik Güvenlik Uyarısı: Webhook uç noktanızı asla herkese açık bir şekilde loglamayın. Gelen verilerde hassas müşteri bilgileri olabilir. Ayrıca, veritabanı işlemlerinizde SQL Injection koruması için mutlaka parametreli sorgular (prepared statements) kullanın.

Webhook Yöntemlerinin Karşılaştırılması

Yöntem Avantajı Dezavantajı
Senkron (Anlık) Hızlı yanıt süresi Sunucu yoğunluğunda hata riski
Kuyruk Yapısı (Asenkron) Yüksek ölçeklenebilirlik Karmaşık mimari

Yerel Ortamda Test Etme

Webhook'ları test etmek için internete açık bir URL'ye ihtiyacınız vardır. Ngrok, yerel sunucunuzu geçici bir URL ile dış dünyaya açar.

# Terminalde çalıştırın
ngrok http 3000

Ngrok size https://rastgele-isim.ngrok.io gibi bir adres verecektir. Bu adresi ödeme sağlayıcınızın panelindeki "Webhook URL" kısmına yapıştırarak testlerinizi gerçekleştirebilirsiniz.

Sıkça Sorulan Sorular

Webhook neden 200 OK yanıtı bekler?

Ödeme sağlayıcıları, bildiriminizin başarıyla ulaşıp ulaşmadığını anlamak için HTTP 200 yanıtını bekler. Eğer yanıt alamazlarsa, bildirimi tekrar göndermeye (retry) çalışırlar.

İmza doğrulama neden zorunludur?

İmza doğrulaması olmazsa, saldırganlar URL'nizi tahmin edip sahte ödeme onayları göndererek ürünlerinizi ücretsiz alabilirler.

Webhook isteği başarısız olursa ne olur?

Çoğu ödeme sağlayıcısı, başarısız olan istekleri belirli aralıklarla (exponential backoff) tekrar dener. Sunucunuzun bu isteklere karşı idempotent (aynı işlemi tekrar etse de veriyi bozmayan) olması gerekir.

Çok sayıda bildirim gelirse sunucum yavaşlar mı?

Evet, yoğun trafik altında webhook işlemlerini bir mesaj kuyruğuna (Redis, RabbitMQ) atıp arka planda işlemek en iyi pratiktir.

Hangi verileri veritabanında saklamalıyım?

İşlem ID, ödeme durumu, zaman damgası ve ödeme sağlayıcısından gelen ham veriyi (debug için) saklamanız önerilir.

Webhook Süreçlerinde İleri Düzey Hata Ayıklama ve Loglama Stratejileri

Webhook sistemleri, dış dünyadan gelen ve kontrolünüz dışında tetiklenen olaylardır. Bu nedenle, bir hata oluştuğunda sorunun nerede olduğunu (ağ mı, imza doğrulama mı, yoksa veritabanı mı) anlamak için kapsamlı bir loglama mekanizması şarttır. Sadece hata mesajlarını değil, gelen isteğin ham gövdesini (raw body) de loglamak, özellikle imza doğrulama sorunlarını çözmek için kritiktir.

Aşağıdaki örnekte, gelen her isteği bir log dosyasına veya merkezi bir loglama servisine (Winston gibi) kaydeden bir middleware yapısı görebilirsiniz:

const winston = require('winston');

const logger = winston.createLogger({
  level: 'info',
  format: winston.format.json(),
  transports: [
    new winston.transports.File({ filename: 'webhook-errors.log', level: 'error' }),
    new winston.transports.File({ filename: 'webhook-all.log' })
  ]
});

function webhookLogger(req, res, next) {
  logger.info('Yeni webhook isteği alındı', {
    headers: req.headers,
    body: req.body,
    timestamp: new Date().toISOString()
  });
  next();
}

app.post('/webhook', webhookLogger, (req, res) => {
  // İşleme mantığı burada devam eder
});

Webhook İşlemlerinde Performans Optimizasyonu

Ödeme bildirimleri yoğun trafik anlarında sunucunuzu kilitleyebilir. Eğer webhook endpoint'iniz içerisinde ağır veritabanı sorguları veya e-posta gönderimi gibi uzun süren işlemler yapıyorsanız, sunucunuzun 200 OK yanıtını geciktirirsiniz. Bu durum, ödeme sağlayıcısının isteği "başarısız" olarak işaretleyip tekrar denemesine (retry) yol açar.

Bu sorunu aşmak için Event-Driven (Olay Tabanlı) mimariyi benimsemelisiniz. Webhook isteğini alın, imzasını doğrulayın ve veriyi bir mesaj kuyruğuna (Redis, RabbitMQ veya BullMQ) atarak hemen yanıt döndürün.

const Queue = require('bull');
const paymentQueue = new Queue('payment-processing');

app.post('/webhook', async (req, res) => {
  const isValid = verifySignature(req);
  
  if (!isValid) return res.status(403).send('Geçersiz imza');

  // İşlemi kuyruğa ekle ve hemen yanıt ver
  await paymentQueue.add({
    transactionId: req.body.id,
    data: req.body
  });

  res.status(200).send('İstek alındı ve kuyruğa eklendi');
});

Dağıtım (Deployment) ve Güvenlik İpuçları

Webhook sunucunuzu canlıya alırken dikkat etmeniz gereken bazı kritik noktalar şunlardır:

  • IP Whitelisting: Ödeme sağlayıcınızın webhook gönderen IP adreslerini biliyorsanız, sunucunuzda sadece bu IP'lerden gelen isteklere izin veren bir güvenlik duvarı (Firewall) kuralı oluşturun.
  • HTTPS Zorunluluğu: Webhook'lar asla HTTP üzerinden çalışmamalıdır. Veri trafiğinin şifrelenmesi, "Man-in-the-Middle" saldırılarını engellemek için zorunludur.
  • Rate Limiting: Kötü niyetli kişilerin veya hatalı yapılandırılmış bir sistemin sunucunuza binlerce istek atmasını engellemek için express-rate-limit gibi kütüphaneler kullanarak endpoint'inizi koruma altına alın.
  • Zaman Aşımı (Timeout) Ayarları: Node.js sunucunuzun varsayılan timeout süresini, ödeme sağlayıcınızın beklediği yanıt süresine göre optimize edin.
Pro İpucu: Eğer ödeme sağlayıcınız webhook'ları tekrar gönderiyorsa (retry mekanizması), sisteminizde Idempotency (Tekrarlanabilirlik) kontrolü yapın. Aynı transaction_id ile gelen ikinci bir isteğin veritabanını bozmadığından veya aynı işlemi iki kez tetiklemediğinden emin olun.

Sonuç

Node.js ile webhook kullanarak ödeme bildirimleri almak, güvenli bir ödeme altyapısı kurmanın temel taşıdır. Bu rehberde, sunucu kurulumundan imza doğrulamaya ve hata yönetimine kadar kritik adımları inceledik. Bir sonraki adım olarak, gelen bildirimleri bir mesaj kuyruğuna aktararak sisteminizi daha dayanıklı hale getirmeyi deneyebilirsiniz.

Sorumluluk Reddi: Bu makalede paylaşılan kodlar eğitim amaçlıdır. Üretim ortamında (production) kullanmadan önce mutlaka güvenlik denetimlerinden geçirin ve ödeme sağlayıcınızın resmi dokümantasyonundaki güncel güvenlik protokollerini uygulayın.
Bu yazıya tepkinizi paylaşın:
Deniz Arslan

On yıldır dijital içerik üretimi ve editörlük alanında çalışıyorum. Karmaşık süreçleri herkesin anlayabileceği basit ve adım adım rehberlere dönüştürme konusunda uzmanım.

Yorumlar (0)

Yorum Yaz