IHS Strategic
Tüm Blog Yazıları
HowTo09 Eylül 2026•3 dk okuma

Stripe, PayTR ve İyzico ile Güvenli Online Ödeme Altyapısı Entegrasyonu Rehberi

Modern web projelerinde Stripe, PayTR ve İyzico API entegrasyonu için teknik adımlar, webhook imza doğrulaması ve PCI-DSS güvenlik standartları.

S

Sistem Yöneticisi

Kıdemli Yazılım Mimarı

Ödeme Ağ Geçidi Mimarisi: Stripe, PayTR ve İyzico Karşılaştırması

Modern web uygulamalarında ve dijital ajans projelerinde doğru ödeme altyapısı seçimi iş modeline ve hedef pazara bağlıdır:

  • Stripe: Global ödemeler, çoklu para birimi desteği, abonelik (recurring billing) modelleri için endüstri standardı API. Türkiye doğrudan şirket hesabı açılışını desteklemez; Stripe Atlas veya yurtdışı varlığı gerektirir.
  • İyzico (iyzico Checkout Form & Sub-merchant API): Türkiye pazarında pazaryeri modelleri, taksitli satışlar ve kurumsal e-ticaret siteleri için optimize edilmiş REST mimarisi.
  • PayTR (iFrame API & Direkt API): Düşük komisyon oranları, hızlı onay süreçleri ve tokenize kart saklama çözümleri sunan yerli ödeme sağlayıcısı.

Adım 1: API Kimlik Doğrulama ve Ortam Değişkenleri

Ödeme anahtarları asla istemci kodunda (client-side) saklanamaz. Güvenlik için .env yapılandırması:

# Stripe
STRIPE_SECRET_KEY=sk_test_51...
STRIPE_WEBHOOK_SECRET=whsec_...

# PayTR
PAYTR_MERCHANT_ID=123456
PAYTR_MERCHANT_KEY=xxxxxx
PAYTR_MERCHANT_SALT=yyyyyy

# İyzico
IYZICO_API_KEY=sandbox-...
IYZICO_SECRET_KEY=sandbox-...
IYZICO_BASE_URL=https://sandbox-api.iyzipay.com

Adım 2: Sunucu Taraflı Ödeme Oturumu Başlatma

Kart verisi doğrudan uygulama sunucusuna temas etmemelidir (PCI-DSS Scope küçültme). Akış: Sunucu ödeme token'ı üretir, istemciye döner, istemci iframe veya modal açar.

Stripe (PaymentIntent API)

Sunucuda PaymentIntent oluşturma örneği:

// Node.js
import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);

const paymentIntent = await stripe.paymentIntents.create({
  amount: 15000, // Kuruş/Cent cinsinden (150.00 TL)
  currency: 'try',
  payment_method_types: ['card'],
  metadata: { order_id: 'TR-9821' }
});
// paymentIntent.client_secret istemciye döndürülür.

PayTR (iFrame Token Üretimi)

PayTR token üretimi HMAC-SHA256 hash mekanizmasına dayanır:

// HMAC-SHA256 Token Üretimi (Node.js)
import crypto from 'crypto';

const hashStr = `${merchant_id}${user_ip}${merchant_oid}${email}${payment_amount}${user_basket}${no_installment}${max_installment}${currency}${test_mode}`;
const paytr_token = crypto
  .createHmac('sha256', merchant_key)
  .update(hashStr + merchant_salt)
  .digest('base64');

Adım 3: 3D Secure Doğrulaması ve İstemci Yönetimi

Türkiye'de BDDK ve TCMB mevzuatları gereği 3D Secure kullanımı zorunludur. İşlem adımları:

  1. Kullanıcı form girdilerini tamamlar.
  2. Banka SMS OTP / Mobil Onay ekranı iframe veya yönlendirme URL'i ile açılır.
  3. Banka onayı sonrası sağlayıcı, sunucunuzun callback_url adresine POST isteği atar.
  4. İstemci tarafında polling veya websocket ile ödeme durumu dinlenir, başarı ekranı gösterilir.

Adım 4: Güvenli Webhook İmza Doğrulama

Ağ kopmaları veya tarayıcı kapanmaları durumunda sipariş kaydı yalnızca webhook ile kesinleştirilir. Gelen isteklerin yetkisiz kaynaklardan gelmediğini doğrulamak için imza (signature) kontrolü şarttır.

Kritik Güvenlik Uyarısı: Webhook uç noktalarında CSRF ve CORS korumalarını bu endpoint özelinde devre dışı bırakın, ham gövdeyi (raw body) hash doğrulaması için saklayın. JSON parse edilmiş gövde imza hatasına yol açar.

Stripe Webhook İmza Doğrulama

// Express.js / Node.js
app.post('/webhook/stripe', express.raw({ type: 'application/json' }), (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 Error: ${err.message}`);
  }

  if (event.type === 'payment_intent.succeeded') {
    const paymentIntent = event.data.object;
    // DB sipariş durumunu 'paid' olarak güncelle
  }
  res.json({ received: true });
});

PayTR Webhook Bildirim Doğrulama

// PayTR Callback Handler
app.post('/webhook/paytr', express.urlencoded({ extended: true }), (req, res) => {
  const { merchant_oid, status, total_amount, hash } = req.body;
  const expectedHash = crypto
    .createHmac('sha256', process.env.PAYTR_MERCHANT_KEY)
    .update(`${merchant_oid}${process.env.PAYTR_MERCHANT_SALT}${status}${total_amount}`)
    .digest('base64');

  if (hash !== expectedHash) {
    return res.status(400).send('PAYTR notification failed: bad hash');
  }

  if (status === 'success') {
    // Siparişi onayla
  }
  res.send('OK'); // PayTR 'OK' yanıtı bekler
});

Modern Web Trendleri ve PCI-DSS SAQ-A Uyumu

Dijital ajanslar ve kurumsal geliştiriciler için modern web standartlarında ödeme güvenliği checklist'i:

  • PCI-DSS SAQ-A Seviyesi: Kart numarası (PAN), CVC ve SKT verisini asla sunucu belleklerine veya log dosyalarına almayın. Stripe Elements veya İyzico Hosted Form kullanarak sorumluluğu sağlayıcıya devredin.
  • Idempotency (Tekilleştirme): Ağ gecikmelerinde mükerrer çekimleri önlemek için isteklerde Idempotency-Key başlığı kullanın.
  • TLS 1.3 ve HSTS: Tüm API ve webhook haberleşmelerinde güncel şifreleme protokollerini zorunlu kılın.
  • Veritabanı Koruması: Yanıtlardan dönen kart bilgilerinin yalnızca maskelenmiş son 4 hanesini (last4) ve kart markasını (Visa/Mastercard) kaydedin.