Gereksinimler ve Ön Hazırlık
Bu projeye başlamadan önce sisteminizde Node.js (v20+ önerilir) ve bir Stripe hesabı bulunmalıdır. React projenizin yanında, webhook'ları dinleyecek bir backend sunucusuna (Express.js veya Next.js API Routes gibi) ihtiyacınız vardır.
- Stripe CLI: Webhook'ları yerel ortamda test etmek için gereklidir.
- Stripe API Anahtarları: Dashboard üzerinden alacağınız Secret Key ve Webhook Secret.
- Veritabanı: Kullanıcı abonelik durumlarını tutacak bir yapı (PostgreSQL, MongoDB vb.).
Stripe CLI'yı bilgisayarınıza kurmak için terminal üzerinden stripe login komutunu çalıştırmanız ve ardından stripe listen --forward-to localhost:3000/api/webhook komutuyla yerel sunucunuzu dinlemeye başlamanız yeterlidir.
Stripe Webhook Endpoint Oluşturma
Webhook'lar, Stripe'tan gelen POST isteklerini karşılayan özel API uç noktalarıdır. Bu uç noktalar, gelen verinin gerçekten Stripe'tan geldiğini doğrulamak için bir "Webhook Secret" kullanır. Güvenlik için bu anahtarı asla açık kaynak kodunuzda paylaşmamalısınız.
// Express.js kullanarak basit bir webhook endpoint örneği
const express = require('express');
const app = express();
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
app.post('/api/webhook', express.raw({type: 'application/json'}), (request, response) => {
const sig = request.headers['stripe-signature'];
let event;
try {
event = stripe.webhooks.constructEvent(request.body, sig, process.env.STRIPE_WEBHOOK_SECRET);
} catch (err) {
return response.status(400).send(`Webhook Hatası: ${err.message}`);
}
// Olayı işleme
console.log('Olay alındı:', event.type);
response.json({received: true});
});
Burada express.raw kullanmamızın sebebi, Stripe imza doğrulamasının ham veri (raw buffer) gerektirmesidir. JSON olarak parse edilmiş veri, imza doğrulamasını bozacaktır.
Abonelik Olaylarını (Events) Yönetme
Stripe üzerinden gelen her bildirim bir olaydır. Abonelik yönetimi için özellikle customer.subscription.updated ve customer.subscription.deleted olaylarını dinlemeniz gerekir. Bu olaylar, kullanıcının aboneliği iptal edildiğinde veya ödeme başarısız olduğunda veritabanınızı güncellemenizi sağlar.
switch (event.type) {
case 'customer.subscription.updated':
const subscription = event.data.object;
// Veritabanında kullanıcı durumunu güncelle
await updateDatabaseSubscription(subscription);
break;
case 'customer.subscription.deleted':
const deletedSubscription = event.data.object;
// Kullanıcının erişimini kısıtla
await revokeUserAccess(deletedSubscription.customer);
break;
default:
console.log(`İşlenmeyen olay türü: ${event.type}`);
}
Bu kod bloğu, gelen olayın türüne göre veritabanı işlemlerini tetikler. updateDatabaseSubscription fonksiyonunuz, Stripe'tan gelen abonelik ID'sini kullanarak veritabanınızdaki ilgili kaydı bulmalı ve durumunu (active, past_due, canceled) güncellemelidir.
React Arayüzünde Abonelik Durumunu Gösterme
React tarafında, kullanıcının mevcut abonelik durumunu göstermek için bir useEffect kancası ve bir API çağrısı kullanırız. Webhook arka planda veritabanını güncellediği için, React uygulaması bu güncellemeyi bir sonraki sayfa yüklenişinde veya bir SWR/React Query sorgusu ile yakalayacaktır.
import React, { useState, useEffect } from 'react';
const SubscriptionStatus = () => {
const [status, setStatus] = useState('Yükleniyor...');
useEffect(() => {
fetch('/api/user/subscription')
.then(res => res.json())
.then(data => setStatus(data.status));
}, []);
return (
Abonelik Durumunuz
Mevcut Durum: {status}
);
};
Bu bileşen, backend'den gelen abonelik durumunu ekrana basar. Kullanıcı ödemesini tamamladığında veya aboneliğini iptal ettiğinde, Stripe webhook'u tetikler, veritabanı güncellenir ve kullanıcı sayfayı yenilediğinde güncel durumu görür.
Güvenlik ve Performans Karşılaştırması
| Yöntem | Avantaj | Dezavantaj |
|---|---|---|
| Webhook (Önerilen) | Gerçek zamanlı ve güvenli | Sunucu tarafı yapılandırma gerektirir |
| Client-Side Polling | Basit kurulum | Sunucuya gereksiz yük bindirir |
Kritik Güvenlik Uyarısı: Webhook endpoint'lerinizi her zaman HTTPS üzerinden yayınlayın. Stripe imza doğrulamasını (webhook secret) asla atlamayın; aksi takdirde kötü niyetli kişiler sahte "ödeme başarılı" bildirimleri göndererek hizmetinize ücretsiz erişim sağlayabilir.
Sıkça Sorulan Sorular
Webhook neden çalışmıyor?
Öncelikle Stripe CLI'nın çalıştığından ve STRIPE_WEBHOOK_SECRET anahtarının doğru olduğundan emin olun. Ayrıca, yerel sunucunuzun dış dünyaya açık (expose) olduğundan emin olun.
Veritabanı güncellemeleri ne kadar sürer?
Webhook'lar genellikle birkaç saniye içinde ulaşır. Ancak ağ gecikmelerine karşı, React tarafında "Yükleniyor" durumlarını düzgün yönetmelisiniz.
Aynı webhook iki kez gelirse ne olur?
Stripe bazen aynı olayı tekrar gönderebilir. Veritabanı işlemlerinizi "idempotent" (aynı işlem birden fazla kez yapılsa da sonucun değişmemesi) olacak şekilde tasarlayın.
Stripe Webhook'ları React içinde mi dinlemeliyim?
Hayır, asla. Webhook'lar sunucu tarafında (Node.js, Python, PHP vb.) dinlenmelidir. React bir istemci tarafı kütüphanesidir ve webhook anahtarlarını tarayıcıda saklamak büyük bir güvenlik açığıdır.
Üretim ortamında (Production) nelere dikkat etmeliyim?
Üretim ortamında Stripe CLI yerine Stripe Dashboard üzerinden gerçek bir Webhook URL'si tanımlayın ve sunucunuzun hata loglarını dikkatle izleyin.
Stripe CLI ile Yerel Geliştirme Ortamında Webhook Testi
Canlı bir sunucuya geçmeden önce Stripe webhook'larını yerel makinenizde test etmek, hata ayıklama sürecini hızlandırır. Stripe CLI, Stripe'tan gelen gerçek olayları yerel geliştirme ortamınıza (localhost) yönlendirmenize olanak tanır. Bu sayede her değişiklikte sunucuyu canlıya almak zorunda kalmazsınız.
Öncelikle Stripe CLI'ı bilgisayarınıza kurun ve ardından aşağıdaki adımları izleyerek bağlantıyı başlatın:
# Stripe hesabınızla giriş yapın
stripe login
# Webhook'ları yerel portunuza yönlendirin
stripe listen --forward-to localhost:4242/webhook
Bu komutu çalıştırdığınızda size bir webhook signing secret değeri verilecektir. Bu değeri .env dosyanıza eklemeyi unutmayın. Artık Stripe panelinden bir "Test Webhook" tetiklediğinizde, bu olay doğrudan yerel sunucunuza düşecektir.
Ölçeklenebilir Webhook İşleme Stratejileri
Uygulamanız büyüdükçe, webhook uç noktanıza gelen isteklerin sayısı artacaktır. Stripe, webhook isteğine 200 OK yanıtını mümkün olan en kısa sürede dönmenizi bekler. Eğer veritabanı işlemleriniz uzun sürüyorsa, webhook isteği zaman aşımına uğrayabilir ve Stripe tekrar deneme (retry) döngüsüne girebilir.
Bu sorunu aşmak için Kuyruk (Queue) Yapısı kullanmanız önerilir. Gelen webhook isteğini doğrudan işlemek yerine, mesaj kuyruğuna (Redis veya RabbitMQ gibi) atarak işlemi arka planda asenkron olarak gerçekleştirin.
Örnek: Asenkron İşleme Mantığı
Aşağıdaki örnekte, webhook isteği alındığında veritabanı işlemini hemen yapmak yerine bir görev kuyruğuna nasıl aktarabileceğinizi görebilirsiniz:
// Node.js/Express ö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, process.env.STRIPE_WEBHOOK_SECRET);
} catch (err) {
return res.status(400).send(`Webhook Hatası: ${err.message}`);
}
// İşlemi kuyruğa ekle (Örn: BullMQ veya benzeri bir kütüphane ile)
await subscriptionQueue.add('process-subscription', {
event: event.type,
data: event.data.object
});
// Stripe'a hızlıca yanıt dön
res.json({ received: true });
});
Webhook Güvenliği İçin İleri İpuçları
Webhook uç noktanızın dışarıdan erişime açık olması bir güvenlik riskidir. Sadece Stripe'tan gelen istekleri kabul ettiğinizden emin olmak için şu önlemleri almalısınız:
- IP Whitelisting: Eğer mümkünse, sunucunuzun güvenlik duvarında sadece Stripe'ın webhook IP adreslerinden gelen isteklere izin verin.
- Signature Verification:
stripe.webhooks.constructEventmetodunu kullanmayı asla atlamayın. Bu metod, isteğin gerçekten Stripe tarafından gönderildiğini ve yolda değiştirilmediğini doğrular. - Idempotency (Tekrarsızlık): Stripe bazen aynı olayı birden fazla kez gönderebilir. Veritabanı güncellemelerinizde
event.iddeğerini kullanarak, aynı olayın daha önce işlenip işlenmediğini kontrol eden bir "idempotency key" mekanizması kurun.
İpucu: Veritabanınızdaprocessed_eventsadında bir tablo tutarak, gelen herevent.iddeğerini kaydedin. Yeni bir istek geldiğinde bu tabloyu kontrol ederek mükerrer işlemleri engelleyebilirsiniz.
Sonuç
React ile Stripe Webhook kullanarak abonelik yönetimi yapmak, uygulamanızın profesyonelleşmesi için atılacak en önemli adımlardan biridir. Bu rehberde, webhook'ların nasıl kurulacağını, Stripe olaylarının nasıl işleneceğini ve veritabanı ile React arasındaki iletişimin nasıl sağlanacağını öğrendiniz. Bir sonraki adım olarak, Stripe'ın Checkout Session yapısını kullanarak ödeme sayfalarını nasıl özelleştirebileceğinizi araştırmanızı öneririm.
Sorumluluk Reddi: Bu makalede paylaşılan kod örnekleri eğitim amaçlıdır. Uygulamanızda kullanmadan önce güvenlik açıklarını (SQL injection, XSS) göz önünde bulundurarak gerekli doğrulama ve sanitizasyon işlemlerini yapınız. Yazılım güvenliği konusunda uzman görüşü almanız tavsiye edilir.


Yorumlar (0)
Yorum Yaz