Node.js ve Express ile Stripe Ödemelerine Giriş
Stripe, modern web uygulamalarında ödeme işlemlerini entegre etmek için en popüler ve güçlü platformlardan biridir. Geliştiricilere sunduğu esneklik, kapsamlı API’ler ve güçlü güvenlik özellikleriyle, e-ticaret sitelerinden abonelik tabanlı hizmetlere kadar geniş bir yelpazede finansal işlemleri kolayca yönetmeyi sağlar. Bu makalede, Node.js ve Express kullanarak bir web uygulamasında Stripe ödemelerini nasıl entegre edeceğimizi adım adım inceleyeceğiz. Temel bir ödeme akışından başlayarak, güvenlik ipuçlarına ve en iyi uygulamalara kadar birçok konuya değineceğiz.
Stripe Nedir ve Neden Kullanmalıyız?
Stripe, işletmelerin çevrimiçi ödeme almasını sağlayan bir finansal altyapı platformudur. Kredi kartı işlemleri, mobil ödemeler, banka transferleri ve diğer birçok ödeme yöntemini destekler. Geliştiriciler için tasarlanmış güçlü API’leri ve SDK’ları sayesinde, özel ödeme deneyimleri oluşturmak oldukça basittir.
Stripe’ın Başlıca Avantajları:
* Geliştirici Dostu: Kapsamlı dokümantasyon, zengin API’ler ve çeşitli programlama dilleri için SDK’lar sunar. Node.js için özel bir stripe paketi bulunur.
* Küresel Destek: Dünya genelinde birçok para birimini ve ödeme yöntemini destekler.
* Güvenlik: PCI DSS uyumluluğu, gelişmiş sahtekarlık tespiti (Radar) ve tokenizasyon gibi özelliklerle ödeme verilerini güvende tutar. Hassas kart bilgileri hiçbir zaman sunucunuzda tutulmaz.
* Esneklik: Tek seferlik ödemelerden aboneliklere, pazar yeri çözümlerinden iadelere kadar geniş bir yelpazede finansal işlemi destekler.
* Ölçeklenebilirlik: Küçük başlangıçlardan büyük kurumsal uygulamalara kadar her ölçekteki işletme için uygundur.
* Kullanıcı Deneyimi: Özelleştirilebilir ödeme formları (Stripe Elements) ile sorunsuz bir kullanıcı deneyimi sunar.
Bu makalede, Stripe’ın temel ödeme akışını Node.js ve Express ile nasıl kuracağımızı öğreneceğiz.
Başlarken: Gerekli Ön Hazırlıklar
Stripe ile entegrasyona başlamadan önce bazı temel adımları tamamlamamız gerekiyor.
Stripe Hesabı Oluşturma ve API Anahtarları
İlk olarak, bir Stripe hesabına ihtiyacınız var. Stripe’ın web sitesine giderek (stripe.com) kolayca bir hesap oluşturabilirsiniz. Hesap oluşturduktan sonra, geliştirici panelinize erişeceksiniz.
Geliştirici panelinde, “Developers” (Geliştiriciler) menüsü altında “API keys” (API anahtarları) bölümünü bulacaksınız. Burada iki tür anahtar bulunur:
* Publishable Key (Yayınlanabilir Anahtar): pk_test_... ile başlar. Bu anahtar, istemci tarafında (tarayıcıda) Stripe.js kütüphresi ile kullanılır. Güvenli bir şekilde herkese açık olabilir.
* Secret Key (Gizli Anahtar): sk_test_... ile başlar. Bu anahtar, sunucu tarafında (Node.js uygulamanızda) Stripe API çağrıları yapmak için kullanılır. Bu anahtar kesinlikle gizli tutulmalı ve asla istemci tarafına ifşa edilmemelidir.
Geliştirme aşamasında test anahtarlarını kullanacağız. Canlıya geçtiğinizde, canlı anahtarları kullanmanız gerekecektir.
Geliştirme Ortamı Kurulumu
Node.js ve Express tabanlı bir uygulama geliştireceğimiz için aşağıdaki araçların sisteminizde kurulu olması gerekir:
1. Node.js ve npm: Node.js’in resmi web sitesinden (nodejs.org) indirip kurabilirsiniz. npm (Node Package Manager) Node.js ile birlikte gelir.
2. Metin Düzenleyici/IDE: VS Code, Sublime Text gibi bir düzenleyici kullanabilirsiniz.
Şimdi projemizi oluşturalım:
mkdir stripe-payment-app
cd stripe-payment-app
npm init -y
Bu komutlar, projemiz için bir dizin oluşturacak ve package.json dosyasını başlatacaktır.
Gerekli paketleri kuralım:
npm install express stripe dotenv
* express: Web sunucumuzu oluşturmak için.
* stripe: Stripe API ile etkileşim kurmak için resmi Node.js kütüphanesi.
* dotenv: API anahtarlarımızı ve diğer hassas bilgileri güvenli bir şekilde yönetmek için ortam değişkenlerini kullanmamızı sağlar.
Temel Stripe Ödeme Akışı
Stripe ile tek seferlik bir ödeme işlemi genellikle aşağıdaki adımları içerir:
1. Müşteri Tarafı (Frontend):
* Müşteri, uygulamanızdaki bir ödeme formuna kart bilgilerini girer.
* Stripe.js kütüphanesi, bu kart bilgilerini doğrudan Stripe’a gönderir ve hassas bilgileri sunucunuza asla dokundurmadan bir “Payment Method” veya “Token” oluşturur.
* Bu güvenli referans (Payment Method ID veya Token ID) sunucunuza gönderilir.
2. Sunucu Tarafı (Backend):
* Sunucunuz, istemciden gelen Payment Method ID’sini alır.
* Stripe Node.js kütüphanesini kullanarak, bu Payment Method ID’si ve ödeme miktarı ile bir “Payment Intent” (Ödeme Niyeti) oluşturur.
* Stripe, ödeme işlemini gerçekleştirmeye çalışır. Bazı durumlarda ek kimlik doğrulama (3D Secure gibi) gerekebilir.
* Sunucunuz, ödeme işleminin sonucunu (başarılı, başarısız, ek doğrulama gerekli) istemciye bildirir.
3. Müşteri Tarafı (Frontend – Devam):
* Eğer ek doğrulama gerekiyorsa, Stripe.js bu doğrulamayı yönetir ve ödeme akışını tamamlar.
* Ödeme başarılı olduktan sonra, müşteriye onay mesajı gösterilir.
Müşteri Tarafı Entegrasyonu (Frontend)
Müşteri tarafında, ödeme formunu oluşturmak ve kart bilgilerini güvenli bir şekilde Stripe’a göndermek için Stripe.js kütüphanesini kullanırız.
Stripe.js Yükleme ve Elemanlar
index.html adında bir dosya oluşturalım (veya React, Vue gibi bir frontend framework kullanıyorsanız ilgili bileşeninizde).
Stripe Ödeme Sayfası
Yukarıdaki kodda YOUR_STRIPE_PUBLISHABLE_KEY kısmını kendi Stripe yayınlanabilir anahtarınızla değiştirmeniz gerekmektedir.
Açıklamalar:
* Stripe(YOUR_STRIPE_PUBLISHABLE_KEY): Stripe.js kütüphanesini yayınlanabilir anahtarınızla başlatır.
* elements.create('card'): Kart numarası, son kullanma tarihi ve CVC alanlarını içeren entegre bir UI bileşeni olan “Card Element” oluşturur. Bu, PCI DSS uyumluluğunu sağlamanın en kolay yoludur, çünkü hassas kart bilgileri doğrudan Stripe’a gönderilir.
* card.mount('#card-element'): Oluşturulan Card Element’i HTML’deki belirli bir div elementine bağlar.
* form.addEventListener('submit'): Form gönderildiğinde tetiklenen bir olay dinleyicisi ekler.
* fetch('/create-payment-intent', ...): Ödeme işlemi için sunucumuza bir istek gönderir. Bu istek sonucunda sunucu, Stripe API’yi kullanarak bir Payment Intent oluşturur ve clientSecret değerini geri döndürür.
* stripe.confirmCardPayment(clientSecret, { payment_method: { card: card, ... } }): Stripe.js’in en kritik fonksiyonlarından biridir. Sunucudan alınan clientSecret ve Card Element’ten alınan kart bilgileri ile ödeme işlemini onaylamaya çalışır. Gerekirse 3D Secure gibi ek doğrulamaları otomatik olarak yönetir.
Sunucu Tarafı Entegrasyonu (Backend – Node.js/Express)
Şimdi sıra sunucu tarafına geldi. Burada express ile bir web sunucusu kuracak, dotenv ile API anahtarlarımızı güvenli bir şekilde yönetecek ve stripe paketi ile Stripe API çağrıları yapacağız.
server.js adında bir dosya oluşturalım:
require('dotenv').config(); // Ortam değişkenlerini .env dosyasından yükle
const express = require('express');
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY); // Gizli anahtarımızı .env'den al
const path = require('path');
const app = express();
const PORT = process.env.PORT || 3000;
// Middleware'ler
app.use(express.json()); // JSON istek gövdelerini ayrıştırmak için
app.use(express.static('public')); // Frontend dosyalarımızı sunmak için (index.html)
// Ana dizine yapılan isteklerde index.html dosyasını gönder
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'public', 'index.html'));
});
// Ödeme niyeti (Payment Intent) oluşturma endpoint'i
app.post('/create-payment-intent', async (req, res) => {
const { amount } = req.body; // İstemciden gelen miktar (kuruş cinsinden)
try {
const paymentIntent = await stripe.paymentIntents.create({
amount: amount, // Ödeme miktarı (en küçük birim, örn. 1000 kuruş = 10 TL)
currency: 'try', // Türk Lirası
payment_method_types: ['card'], // Desteklenen ödeme yöntemleri
// description: 'Test ürün satın alma', // Opsiyonel
// metadata: { order_id: '12345' }, // Opsiyonel: Kendi verilerinizi ekleyebilirsiniz
});
res.status(200).json({
clientSecret: paymentIntent.client_secret
});
} catch (error) {
console.error('Error creating payment intent:', error);
res.status(500).json({ error: { message: error.message } });
}
});
// Webhook endpoint'i (Opsiyonel ama önemlidir)
// Stripe, ödeme durumu güncellemelerini bu endpoint'e gönderir
app.post('/webhook', express.raw({type: 'application/json'}), async (req, res) => {
const sig = req.headers['stripe-signature'];
let event;
try {
// Webhook imzasını doğrulayarak isteğin Stripe'tan geldiğinden emin ol
event = stripe.webhooks.constructEvent(req.body, sig, process.env.STRIPE_WEBHOOK_SECRET);
} catch (err) {
console.error('Webhook signature verification failed.', err.message);
return res.status(400).send(Webhook Error: ${err.message});
}
// Olay türüne göre işlem yap
switch (event.type) {
case 'payment_intent.succeeded':
const paymentIntentSucceeded = event.data.object;
console.log(PaymentIntent for ${paymentIntentSucceeded.amount} was successful!);
// Siparişinizi veritabanında güncelleyin, müşteriye e-posta gönderin vb.
break;
case 'payment_intent.payment_failed':
const paymentIntentFailed = event.data.object;
console.log(PaymentIntent for ${paymentIntentFailed.amount} failed! Reason: ${paymentIntentFailed.last_payment_error?.message});
// Müşteriye hata bildirimi yapın, sipariş durumunu güncelleyin vb.
break;
// Diğer olay türlerini burada işleyebilirsiniz (örn. charge.refunded)
default:
console.log(Unhandled event type ${event.type});
}
// Stripe'a başarılı yanıt gönder
res.status(200).json({ received: true });
});
// Sunucuyu başlat
app.listen(PORT, () => {
console.log(Sunucu http://localhost:${PORT} adresinde çalışıyor.);
});
public adında bir klasör oluşturun ve index.html dosyasını bu klasörün içine taşıyın.
Şimdi bir .env dosyası oluşturalım ve Stripe API anahtarlarımızı buraya ekleyelim:
STRIPE_SECRET_KEY=sk_test_YOUR_SECRET_KEY
STRIPE_PUBLISHABLE_KEY=pk_test_YOUR_PUBLISHABLE_KEY
STRIPE_WEBHOOK_SECRET=whsec_YOUR_WEBHOOK_SECRET
PORT=3000
STRIPE_SECRET_KEY ve STRIPE_PUBLISHABLE_KEY yerine kendi anahtarlarınızı girin. STRIPE_WEBHOOK_SECRET anahtarını daha sonra Stripe panelinden alacağız.
Açıklamalar:
* require('dotenv').config(): .env dosyasındaki değişkenleri process.env objesine yükler.
* stripe = require('stripe')(process.env.STRIPE_SECRET_KEY): Stripe kütüphanesini gizli anahtarımızla başlatır.
* app.use(express.json()): Express’in gelen JSON istek gövdelerini ayrıştırmasını sağlar.
* app.use(express.static('public')): public klasöründeki statik dosyaları (örn. index.html) sunucudan erişilebilir hale getirir.
* /create-payment-intent endpoint’i:
* İstemciden gelen amount değerini alır.
* stripe.paymentIntents.create() fonksiyonu ile bir Payment Intent oluşturur. amount değeri, Stripe API’sinde en küçük para birimi cinsinden (örn. 1000 kuruş = 10 TL) belirtilmelidir.
* Oluşturulan Payment Intent’in client_secret değerini istemciye geri gönderir. Bu değer, istemcinin ödeme işlemini tamamlaması için gereklidir.
* /webhook endpoint’i:
* Bu endpoint, Stripe tarafından ödeme durum güncellemelerini almak için kullanılır.
* stripe.webhooks.constructEvent() fonksiyonu ile gelen isteğin Stripe’tan geldiği doğrulanır. Bu, güvenlik için kritik bir adımdır.
* event.type‘a göre farklı işlemler yapılır. Örneğin, payment_intent.succeeded olayı tetiklendiğinde, veritabanınızdaki siparişin durumunu güncelleyebilir, müşteriye onay e-postası gönderebilirsiniz.
Webhooks Kurulumu:
Webhook’lar, uygulamanızın ödeme akışındaki asenkron olayları (örn. ödemenin başarılı olması, iade edilmesi) güvenilir bir şekilde takip etmesi için hayati öneme sahiptir.
Geliştirme ortamında webhook’ları test etmek için stripe listen komutunu kullanabilirsiniz.
1. Stripe CLI’ı Kurun: [https://stripe.com/docs/stripe-cli](https://stripe.com/docs/stripe-cli) adresinden Stripe CLI’ı indirip kurun.
2. Giriş Yapın: Terminalinizde stripe login komutunu çalıştırın ve talimatları izleyerek Stripe hesabınıza giriş yapın.
3. Webhook Dinlemeye Başlayın: server.js dosyanızın çalıştığı dizinde yeni bir terminal açın ve aşağıdaki komutu çalıştırın:
stripe listen --forward-to localhost:3000/webhook
Bu komut, Stripe’tan gelen webhook olaylarını localhost:3000/webhook adresine iletecektir. Komut çalıştıktan sonra size bir whsec_... ile başlayan “Webhook secret” verecektir. Bu anahtarı .env dosyanızdaki STRIPE_WEBHOOK_SECRET değişkenine ekleyin.
Artık her şey hazır! Projenizi çalıştırmak için terminalde node server.js komutunu kullanabilirsiniz. Ardından tarayıcınızdan http://localhost:3000 adresine gidin.
Test Kartları:
Stripe, test ortamında kullanabileceğiniz özel kart numaraları sağlar. Bu kartlarla gerçek para harcamadan ödeme akışını test edebilirsiniz.
Örneğin:
* Başarılı bir ödeme için: 4242 4242 4242 4242 (herhangi bir gelecek tarih ve CVC ile)
* Başarısız bir ödeme için: 4000 0000 0000 0002 (yetersiz bakiye)
Daha fazla test kartı için Stripe dokümantasyonuna bakabilirsiniz.
Gelişmiş Konular ve En İyi Uygulamalar
Temel ödeme akışını kurduktan sonra, uygulamanızın daha sağlam ve kullanıcı dostu olması için bazı gelişmiş konuları ve en iyi uygulamaları göz önünde bulundurmalısınız.
Müşteri Yönetimi (Customers API)
Tekrar eden müşteriler için her ödemede kart bilgilerini tekrar istemek yerine, Stripe’ın Müşteri API’sini kullanabilirsiniz. Bir müşteri ilk kez ödeme yaptığında, onun için bir Customer objesi oluşturabilir ve ödeme yöntemini bu müşteriye bağlayabilirsiniz. Gelecekteki ödemelerde sadece Customer ID ve kayıtlı ödeme yöntemini kullanarak hızlıca işlem yapabilirsiniz.
// Örnek: Müşteri oluşturma ve ödeme yöntemini bağlama
const customer = await stripe.customers.create({
email: 'customer@example.com',
name: 'Deneme Müşteri',
payment_method: 'pm_card_visa', // İstemciden gelen Payment Method ID
invoice_settings: { default_payment_method: 'pm_card_visa' },
});
// Örnek: Kayıtlı müşteriden ödeme alma
const paymentIntent = await stripe.paymentIntents.create({
amount: 2000,
currency: 'try',
customer: customer.id, // Kayıtlı müşterinin ID'si
payment_method: 'pm_card_visa', // Müşteriye bağlı ödeme yöntemi ID'si
off_session: true, // Müşteri oturum dışı ödeme yapıyor
confirm: true,
});
Abonelikler (Subscriptions)
Stripe, abonelik tabanlı hizmetler için güçlü bir API sunar. Ürünler (Products) ve Fiyatlandırmalar (Prices) tanımlayarak, müşterileri belirli bir plana abone edebilir ve düzenli ödemeleri otomatik olarak tahsil edebilirsiniz.
// Örnek: Abonelik oluşturma
const subscription = await stripe.subscriptions.create({
customer: 'cus_xyz', // Müşteri ID'si
items: [{ price: 'price_abc' }], // Fiyatlandırma ID'si
expand: ['latest_invoice.payment_intent'],
});
İade İşlemleri (Refunds)
Müşteri memnuniyeti için iade işlemleri de önemlidir. Stripe API üzerinden kolayca iade yapabilirsiniz.
// Örnek: Tam iade
const refund = await stripe.refunds.create({
payment_intent: 'pi_xyz', // İade edilecek Payment Intent ID'si
});
// Örnek: Kısmi iade
const partialRefund = await stripe.refunds.create({
payment_intent: 'pi_xyz',
amount: 500, // 5 TL iade
});
Güvenlik İpuçları
* API Anahtarlarını Güvende Tutun: Gizli anahtarlarınızı asla istemci tarafına ifşa etmeyin ve ortam değişkenleri (.env) kullanarak yönetin. Git’e .env dosyasını dahil etmeyin (.gitignore kullanın).
* HTTPS Kullanın: Canlı ortamda tüm iletişim HTTPS üzerinden yapılmalıdır.
* Webhook İmza Doğrulaması: Webhook endpoint’inize gelen isteklerin gerçekten Stripe’tan geldiğini doğrulamak için imza kontrolünü mutlaka kullanın. Bu, kötü niyetli kişilerin sahte olaylar göndererek uygulamanızı manipüle etmesini engeller.
* PCI DSS Uyumluluğu: Stripe.js Elemanları’nı kullanarak hassas kart bilgilerini doğrudan Stripe’a gönderdiğinizden emin olun. Kendi sunucunuzda kart bilgileri depolamaktan kaçının.
* Idempotency Keys: Özellikle ödeme oluşturma gibi işlemlerde, aynı isteğin birden fazla kez işlenmesini önlemek için Idempotency Keys kullanın. Bu, ağ sorunları veya zaman aşımı durumunda aynı işlemi tekrar göndermeniz gerektiğinde, işlemin sadece bir kez gerçekleşmesini sağlar.
// Örnek: Idempotency Key kullanımı
const paymentIntent = await stripe.paymentIntents.create({
amount: 1000,
currency: 'try',
// ... diğer parametreler
}, {
idempotencyKey: 'unique_order_id_123' // Her istek için benzersiz bir anahtar
});
Test Süreci
* Test Anahtarları: Geliştirme ve test aşamasında daima test anahtarlarınızı kullanın.
* Test Kartları: Stripe’ın sağladığı çeşitli test kartlarını kullanarak başarılı, başarısız, 3D Secure gerektiren senaryoları test edin.
* Stripe CLI ve Webhook’lar: Webhook’larınızın doğru çalıştığından emin olmak için Stripe CLI’ı kullanarak olayları simüle edin.
* Stripe Dashboard: Geliştirici panelindeki günlükleri ve olayları inceleyerek işlemlerinizi takip edin ve hataları ayıklayın.
Sonuç
Bu makalede, Node.js ve Express kullanarak Stripe ödemelerini bir web uygulamasına nasıl entegre edeceğinizi adım adım öğrendik. Stripe.js ile istemci tarafı entegrasyonundan, Node.js ile sunucu tarafında Payment Intent oluşturmaya ve webhook’ları işlemeye kadar temel bir ödeme akışını başarılı bir şekilde kurduk.
Stripe, sunduğu zengin API’ler, güçlü güvenlik önlemleri ve kapsamlı dokümantasyon ile geliştiricilerin ödeme çözümleri oluşturmasını son derece kolaylaştırır. Tek seferlik ödemelerin ötesinde, abonelikler, müşteri yönetimi, iadeler ve çok daha fazlası için geniş olanaklar sunar. Uygulamanızın gereksinimlerine göre bu gelişmiş özellikleri keşfetmek, daha sağlam ve esnek bir ödeme sistemi oluşturmanıza yardımcı olacaktır.
Unutmayın, canlıya geçmeden önce tüm güvenlik önlemlerini aldığınızdan, test senaryolarınızı titizlikle uyguladığınızdan ve PCI DSS uyumluluğunu sağladığınızdan emin olun. İyi kodlamalar!