Ön Hazırlık ve Gereksinimler
Bu projeyi hayata geçirmek için temel düzeyde React ve Node.js bilgisine sahip olmanız gerekmektedir. Ayrıca, geliştirme ortamınızda Stripe CLI aracının kurulu olması, yerel testler yapabilmeniz için zorunludur.
- Stripe hesabı ve API anahtarları (Secret Key).
- Node.js (v20 veya üzeri önerilir).
- React projesi (Vite veya Next.js).
- Stripe CLI (Yerel webhook testi için).
Stripe CLI kurulumu için terminalinize npm install -g stripe komutunu girerek aracı sisteminize dahil edebilirsiniz. Ardından stripe login komutu ile hesabınızı yetkilendirmeniz gerekecektir.
Stripe Webhook Endpoint Kurulumu
Webhook bildirimlerini almak için sunucunuzda bir endpoint (uç nokta) oluşturmalısınız. Bu endpoint, Stripe'tan gelen ham veriyi (raw body) doğrulamalıdır. Güvenlik nedeniyle, Stripe'ın gönderdiği imza (signature) başlığını mutlaka kontrol etmelisiniz.
// Express.js üzerinde webhook endpoint örneği
const express = require('express');
const app = express();
const stripe = require('stripe')('sk_test_...');
app.post('/webhook', express.raw({type: 'application/json'}), (request, response) => {
const sig = request.headers['stripe-signature'];
let event;
try {
event = stripe.webhooks.constructEvent(request.body, sig, 'whsec_...');
} catch (err) {
return response.status(400).send(`Webhook Hatası: ${err.message}`);
}
// Olayı işleme
if (event.type === 'payment_intent.succeeded') {
const paymentIntent = event.data.object;
console.log('Ödeme başarılı:', paymentIntent.id);
}
response.json({received: true});
});
Bu kod bloğunda express.raw kullanarak veriyi ham haliyle alıyoruz, çünkü imza doğrulaması için verinin değiştirilmemiş olması şarttır. stripe.webhooks.constructEvent fonksiyonu, gelen isteğin gerçekten Stripe tarafından gönderildiğini doğrular.
React Tarafında Ödeme Durumunu İzleme
React uygulamanızda ödeme durumunu göstermek için genellikle iki yöntem vardır: Webhook'tan gelen veriyi bir veritabanına yazıp React'ın bu veritabanını sorgulaması veya WebSocket kullanarak anlık bildirim alması. En yaygın ve güvenli yöntem, veritabanı ile senkronize çalışmaktır.
// React bileşeni içerisinde ödeme durumu kontrolü
import { useEffect, useState } from 'react';
const PaymentStatus = ({ sessionId }) => {
const [status, setStatus] = useState('loading');
useEffect(() => {
fetch(`/api/check-payment/${sessionId}`)
.then(res => res.json())
.then(data => setStatus(data.status));
}, [sessionId]);
return Ödeme Durumu: {status};
};
Bu bileşen, Stripe'tan gelen webhook sonrası veritabanınızda güncellenen durumu çeker. Kullanıcı ödemeyi tamamladıktan sonra sayfayı yenilediğinde veya belirli aralıklarla durum güncellenir.
Stripe CLI ile Yerel Test Yapma
Webhook'larınızı canlıya almadan önce yerel ortamda test etmelisiniz. Stripe CLI, Stripe sunucusundan gelen gerçek olayları yerel sunucunuza yönlendirmenizi sağlar. Terminalde şu komutu çalıştırın:
stripe listen --forward-to localhost:4242/webhook
Bu komut, Stripe'ın gönderdiği tüm olayları yerel 4242 portundaki sunucunuza iletir. Test amaçlı bir ödeme tetiklemek içinse şu komutu kullanabilirsiniz:
stripe trigger payment_intent.succeeded
Bu komut, sisteminize sahte bir "ödeme başarılı" olayı gönderir ve webhook endpoint'inizin doğru çalışıp çalışmadığını test etmenize olanak tanır.
Güvenlik ve En İyi Pratikler
Kritik Uyarı: Webhook endpoint'lerinizde asla Stripe Secret Key'inizi frontend (React) tarafına göndermeyin. Webhook doğrulama işlemi tamamen backend tarafında yapılmalıdır. Ayrıca, webhook endpoint'lerinizi HTTPS üzerinden yayınladığınızdan emin olun.
Güvenlik için dikkat etmeniz gereken diğer bir nokta, webhook isteklerinin tekrar gönderilebileceğidir (idempotency). Stripe, aynı olayı birden fazla kez gönderebilir. İşlemlerinizi gerçekleştirirken veritabanınızda olay kimliğini (event ID) kontrol ederek mükerrer işlemleri engelleyin.
| Yöntem | Avantajı | Dezavantajı |
|---|---|---|
| Webhook + Veritabanı | Güvenli ve tutarlı veri | Gecikme olabilir |
| WebSocket | Anlık bildirim | Sunucu yükü artar |
Yaygın Hatalar ve Çözümleri
Geliştiricilerin sıklıkla yaptığı hatalardan biri, express.json() middleware'ini webhook route'undan önce kullanmaktır. Bu, verinin gövdesini (body) bozarak imza doğrulama hatasına neden olur. Her zaman express.raw kullanın.
Bir diğer hata ise webhook'un zaman aşımına uğramasıdır. Stripe, webhook isteğine 200 OK yanıtını hızlıca bekler. Uzun süren veritabanı işlemlerini webhook'un içinde değil, arka plan kuyruklarında (worker) yapmanız önerilir.
Sıkça Sorulan Sorular
Webhook'lar neden gecikmeli çalışır?
Webhook'lar asenkron çalışır. Stripe, ödeme başarılı olduktan sonra sunucunuza bir HTTP isteği gönderir. Ağ trafiğine bağlı olarak bu işlem birkaç saniye sürebilir.
Stripe imza doğrulama hatası alıyorum, ne yapmalıyım?
Bu genellikle express.raw kullanmadığınız veya imza anahtarınızın (webhook secret) yanlış olduğu anlamına gelir. stripe listen komutu ile aldığınız anahtarı kullandığınızdan emin olun.
React tarafında neden doğrudan Stripe'a bağlanmıyorum?
Frontend tarafı manipülasyona açıktır. Webhook doğrulama anahtarları gizli tutulmalıdır; bu yüzden tüm Stripe etkileşimleri backend üzerinden geçmelidir.
Aynı webhook iki kez gelirse ne olur?
Stripe, aynı olayı tekrar gönderebilir. Veritabanınızda event.id değerini bir "işlenen olaylar" tablosunda tutarak mükerrer kayıtları engelleyebilirsiniz.
Canlı ortamda webhook'ları nasıl yönetirim?
Stripe Dashboard üzerinden webhook endpoint'lerinizi tanımlayın ve üretim ortamı (live) için oluşturulan whsec_ anahtarını ortam değişkenlerine (env) ekleyin.
Sorumluluk Reddi: Bu makalede yer alan kod örnekleri eğitim amaçlıdır. Ödeme sistemlerinde güvenlik, uygulamanın en kritik parçasıdır. Üretim ortamına geçmeden önce Stripe'ın resmi güvenlik dokümantasyonunu inceleyin ve kodunuzu profesyonel bir güvenlik denetiminden geçirin.
Webhook Olaylarını Kuyruğa Alma ve Ölçeklenebilirlik
Stripe webhook'ları bazen yoğun trafik altında sunucunuzu zorlayabilir. Özellikle aynı anda yüzlerce ödeme gerçekleştiğinde, webhook endpoint'inizin hızlı cevap vermesi (200 OK dönmesi) kritik önem taşır. Eğer veritabanı işlemleriniz uzun sürüyorsa, webhook'u işlemek yerine bir mesaj kuyruğuna (Redis, BullMQ veya RabbitMQ) atmak en iyi pratiktir.
İşte bir webhook'u asenkron işlemek için temel mantık:
// Express.js tarafında kuyruk kullanımı örneği
app.post('/webhook', express.raw({type: 'application/json'}), async (req, res) => {
const sig = req.headers['stripe-signature'];
let event;
try {
event = stripe.webhooks.constructEvent(req.body, sig, endpointSecret);
} catch (err) {
return res.status(400).send(`Webhook Hatası: ${err.message}`);
}
// İşlemi kuyruğa ekle ve hemen 200 dön
await paymentQueue.add('process-payment', { event });
res.json({ received: true });
});
Webhook Hata Ayıklama (Debugging) İçin İleri Teknikler
Canlı ortamda webhook'ların neden başarısız olduğunu anlamak bazen zor olabilir. Stripe Dashboard'u üzerinden "Developers > Webhooks" sekmesine giderek başarısız olan isteklerin ham verisini (request body) ve dönen hata mesajını inceleyebilirsiniz. Ancak kendi sisteminizde bir "Webhook Log" tablosu tutmak, uzun vadeli hata takibi için vazgeçilmezdir.
Veritabanınızda şu yapıyı kullanarak gelen tüm olayları izleyebilirsiniz:
| Alan Adı | Açıklama |
|---|---|
| id | Stripe event ID (tekil) |
| type | Örn: checkout.session.completed |
| status | processed, failed, pending |
| payload | Ham JSON verisi |
Başarısız Webhook'ları Yeniden İşleme
Eğer bir webhook işlemi veritabanı hatası veya ağ kesintisi nedeniyle başarısız olursa, Stripe'ın "Retry" mekanizmasını kullanabilir veya kendi sisteminizde başarısız olanları tekrar tetikleyen bir cron job yazabilirsiniz. Aşağıdaki kod bloğu, veritabanına kaydedilen başarısız webhook'ları tekrar denemek için basit bir mantık sunar:
// Başarısız olan webhook'ları tekrar işleme mantığı
async function retryFailedWebhooks() {
const failedEvents = await db.webhooks.find({ status: 'failed' });
for (const event of failedEvents) {
try {
await processEvent(event.payload);
await db.webhooks.update(event.id, { status: 'processed' });
} catch (error) {
console.error(`Tekrar deneme başarısız: ${event.id}`);
}
}
}
Performans İçin Webhook Filtreleme
Sunucunuzun gereksiz yere yorulmaması için sadece ihtiyacınız olan olay türlerini Stripe Dashboard üzerinden seçmelisiniz. Tüm olayları dinlemek yerine, sadece checkout.session.completed, invoice.payment_succeeded gibi kritik olayları dinlemek uygulamanızın yanıt süresini optimize eder.
İpucu: Webhook endpoint'inizde karmaşık iş mantığı (örneğin e-posta gönderme veya PDF oluşturma) çalıştırmayın. Bu tür görevleri arka plan işlerine (background jobs) devredin.
Sonuç
React ile Stripe webhook kullanarak ödeme bildirimlerini izlemek, başlangıçta karmaşık görünse de doğru yapılandırıldığında oldukça güvenli bir süreçtir. Backend tarafında imza doğrulamayı doğru yapmak ve frontend tarafında kullanıcıya durumu anlık yansıtmak, profesyonel bir e-ticaret deneyimi için şarttır. Bir sonraki adım olarak, Stripe'ın sunduğu "Event Types" dokümantasyonunu inceleyerek abonelik (subscription) iptalleri veya ödeme başarısızlıkları gibi farklı senaryoları da sisteminize entegre edebilirsiniz.


Yorumlar (0)
Yorum Yaz