Payment Gateway

E-Ticaret Ödeme Sistemleri ve Entegrasyonu

iyzico, PayTR, PayU payment gateway entegrasyonu. 3D Secure, sanal pos, taksit seçenekleri, PCI-DSS uyumluluğu ve ödeme güvenliği.

💳Ödeme Sistemleri Altyapısı

Payment Gateway (Ödeme Ağ Geçidi), müşteri ile banka arasında güvenli ödeme işlemini sağlar. PCI-DSS sertifikalı olmalıdır.

iyzico

Komisyon: %2.49 + 0.25 TL
Taksit: 12 aya kadar
Alternatif: BKM Express, Masterpass
Ödeme: T+2 iş günü

PayTR

Komisyon: %2.79 + 0.25 TL
Taksit: 12 aya kadar
Alternatif: Kredi kartı, havale
Ödeme: T+1 iş günü

PayU

Komisyon: %3.2 + 0.30 TL
Taksit: 9 aya kadar
Alternatif: Kredi, Bankamatik
Ödeme: T+3 iş günü

iyzico Entegrasyonu

# Python ile iyzico ödeme entegrasyonu
import iyzipay

# API ayarları
options = {
    'api_key': 'sandbox-your-api-key',
    'secret_key': 'sandbox-your-secret-key',
    'base_url': iyzipay.SANDBOX_BASE_URL  # Canlı: iyzipay.BASE_URL
}

# Ödeme isteği
payment_request = {
    'locale': 'tr',
    'conversationId': 'order-12345',
    'price': '1000.00',  # Toplam tutar
    'paidPrice': '1050.00',  # Ödenen tutar (taksit farkı dahil)
    'currency': 'TRY',
    'installment': '3',  # Taksit sayısı (1: peşin)
    'basketId': 'basket-12345',
    'paymentChannel': 'WEB',
    'paymentGroup': 'PRODUCT',

    # Kredi kartı bilgileri
    'paymentCard': {
        'cardHolderName': 'Ahmet Yılmaz',
        'cardNumber': '5528790000000008',  # Test kartı
        'expireMonth': '12',
        'expireYear': '2030',
        'cvc': '123',
        'registerCard': '0'  # Kartı kaydet: 0 (hayır), 1 (evet)
    },

    # Alıcı bilgileri
    'buyer': {
        'id': 'user-123',
        'name': 'Ahmet',
        'surname': 'Yılmaz',
        'gsmNumber': '+905551234567',
        'email': 'ahmet@example.com',
        'identityNumber': '12345678901',
        'registrationAddress': 'Atatürk Cad. No:1 Kadıköy',
        'ip': '85.34.78.112',
        'city': 'İstanbul',
        'country': 'Türkiye',
        'zipCode': '34000'
    },

    # Teslimat adresi
    'shippingAddress': {
        'contactName': 'Ahmet Yılmaz',
        'city': 'İstanbul',
        'country': 'Türkiye',
        'address': 'Atatürk Cad. No:1 Kadıköy',
        'zipCode': '34000'
    },

    # Fatura adresi
    'billingAddress': {
        'contactName': 'Ahmet Yılmaz',
        'city': 'İstanbul',
        'country': 'Türkiye',
        'address': 'Atatürk Cad. No:1 Kadıköy',
        'zipCode': '34000'
    },

    # Sepet ürünleri (alt işyeri komisyonu için)
    'basketItems': [
        {
            'id': 'product-001',
            'name': 'Laptop',
            'category1': 'Elektronik',
            'category2': 'Bilgisayar',
            'itemType': 'PHYSICAL',
            'price': '1000.00'
        }
    ]
}

# 3D Secure ile ödeme
payment = iyzipay.ThreedsInitialize().create(payment_request, options)

if payment.status == 'success':
    # 3D Secure sayfasına yönlendir
    print(payment.threeds_html_content)  # HTML formu
    # Bu HTML'i müşteriye göster → 3D doğrulama → callback
else:
    print(f"Hata: {payment.error_message}")
# 3D Secure callback işlemi
def iyzico_callback(request):
    """
    3D Secure doğrulaması sonrası iyzico bu endpoint'i çağırır
    """
    # Callback verilerini al
    callback_data = {
        'locale': 'tr',
        'conversationId': request.POST.get('conversationId'),
        'paymentId': request.POST.get('paymentId'),
        'conversationData': request.POST.get('conversationData')
    }

    # Ödeme sonucunu kontrol et
    payment_result = iyzipay.ThreedsPayment().create(callback_data, options)

    if payment_result.status == 'success':
        # Ödeme başarılı
        order_id = payment_result.conversation_id
        payment_id = payment_result.payment_id

        # Sipariş durumunu güncelle
        update_order_status(order_id, 'paid', payment_id)

        return redirect('/order/success')
    else:
        # Ödeme başarısız
        error = payment_result.error_message
        return redirect(f'/order/failed?error={error}')

PayTR Entegrasyonu

# PHP ile PayTR ödeme entegrasyonu
<?php
$merchant_id    = 'XXXXXX';
$merchant_key   = 'your-merchant-key';
$merchant_salt  = 'your-merchant-salt';

// Sipariş bilgileri
$merchant_oid = "order-" . uniqid();
$email = "musteri@example.com";
$payment_amount = 10000;  // Kuruş cinsinden (100.00 TL)
$user_basket = base64_encode(json_encode([
    ["Laptop ASUS", "1000.00", 1],
    ["Mouse", "50.00", 1]
]));

$user_name = "Ahmet Yılmaz";
$user_address = "Atatürk Cad. No:1 Kadıköy/İstanbul";
$user_phone = "05551234567";

// Başarılı/başarısız dönüş URL'leri
$merchant_ok_url = "https://example.com/payment/success";
$merchant_fail_url = "https://example.com/payment/fail";

// Hash oluştur (güvenlik)
$hash_str = $merchant_id . $user_basket . $merchant_oid .
            $payment_amount . 'TL' .
            $merchant_ok_url . $merchant_fail_url .
            $merchant_salt;
$paytr_token = base64_encode(hash_hmac('sha256', $hash_str, $merchant_key, true));

// PayTR'ye gönderilecek form
$post_vals = [
    'merchant_id'       => $merchant_id,
    'user_ip'           => $_SERVER['REMOTE_ADDR'],
    'merchant_oid'      => $merchant_oid,
    'email'             => $email,
    'payment_amount'    => $payment_amount,
    'paytr_token'       => $paytr_token,
    'user_basket'       => $user_basket,
    'debug_on'          => 0,  // Canlıda: 0
    'no_installment'    => 0,  // Taksit var
    'max_installment'   => 9,
    'user_name'         => $user_name,
    'user_address'      => $user_address,
    'user_phone'        => $user_phone,
    'merchant_ok_url'   => $merchant_ok_url,
    'merchant_fail_url' => $merchant_fail_url,
    'timeout_limit'     => 30,
    'currency'          => 'TL',
    'test_mode'         => 0,  // Canlıda: 0
    'lang'              => 'tr'
];

// PayTR API'sine istek gönder
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://www.paytr.com/odeme/api/get-token");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_vals));
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_TIMEOUT, 20);

$result = @curl_exec($ch);
curl_close($ch);

$result = json_decode($result, true);

if ($result['status'] == 'success') {
    $iframe_token = $result['token'];
    ?>
    <!-- PayTR ödeme iframe'i -->
    <script src="https://www.paytr.com/js/iframeResizer.min.js"></script>
    <iframe src="https://www.paytr.com/odeme/guvenli/<?=$iframe_token?>"
            id="paytriframe"
            frameborder="0"
            scrolling="no"
            style="width: 100%;"></iframe>
    <script>iFrameResize({},'#paytriframe');</script>
    <?php
} else {
    echo "Hata: " . $result['reason'];
}
?>

Ödeme Güvenliği (PCI-DSS)

PCI-DSS Gereksinimleri:

Kart bilgileri asla sunucunuzda saklanmamalı
SSL/TLS: Tüm ödeme sayfaları HTTPS olmalı
Tokenization: Kart bilgisi yerine token kullanın
3D Secure: Zorunlu (Türkiye'de kanunen gerekli)
CVV: CVV/CVC kodları kesinlikle saklanmamalı
Loglar: Ödeme loglarında kart bilgisi olmamalı
# Güvenli ödeme işleme örneği (Node.js)
const express = require('express');
const helmet = require('helmet');  // Security headers
const rateLimit = require('express-rate-limit');

const app = express();

// Güvenlik middleware'leri
app.use(helmet());  // XSS, clickjacking koruması
app.use(express.json({ limit: '10kb' }));  // Body size limit

// Rate limiting (DDoS koruması)
const paymentLimiter = rateLimit({
    windowMs: 15 * 60 * 1000,  // 15 dakika
    max: 5,  // Maksimum 5 ödeme denemesi
    message: 'Çok fazla ödeme denemesi. Lütfen 15 dakika sonra tekrar deneyin.'
});

app.post('/api/payment', paymentLimiter, async (req, res) => {
    try {
        // Input validation (SQL injection, XSS koruması)
        const { amount, orderId } = validatePaymentData(req.body);

        // Kart bilgileri asla loglanmamalı
        // YANLIŞ: console.log(req.body.cardNumber)
        // DOĞRU: console.log("Payment attempt for order:", orderId)

        // Payment gateway'e gönder (kartı asla kaydetme)
        const paymentResult = await processPayment({
            amount,
            orderId,
            // Kart bilgileri direkt gateway'e
            cardToken: req.body.cardToken  // Tokenize edilmiş kart
        });

        if (paymentResult.success) {
            // Sadece payment ID ve order ID kaydet
            await savePaymentRecord({
                orderId,
                paymentId: paymentResult.paymentId,
                amount,
                timestamp: new Date()
                // Kart bilgisi YOK!
            });

            res.json({ success: true, paymentId: paymentResult.paymentId });
        } else {
            res.status(400).json({ success: false, error: 'Payment failed' });
        }
    } catch (error) {
        // Hata mesajında hassas bilgi olmamalı
        console.error("Payment error:", error.message);  // Detay loglarda
        res.status(500).json({ error: 'Payment processing error' });  // Kullanıcıya genel mesaj
    }
});

Alternatif Ödeme Yöntemleri

🏦 Havale/EFT

Komisyon: %0
Süre: 1-2 iş günü (manuel onay)
Kullanım: B2B, yüksek tutarlar
Otomatik: IBAN eşleştirme ile

📱 Dijital Cüzdan

BKM Express: %1.5 komisyon
Masterpass: %1.8 komisyon
Papara: %2.2 komisyon
Apple Pay / Google Pay

💵 Kapıda Ödeme

Nakit: Kurye tahsilat
Kredi kartı: POS cihazı
Risk: İade oranı yüksek
Maliyet: Kurye + POS komisyonu

💳 Sanal Kart

Troy: Yerli kart sistemi
Komisyon: %2.0-2.5
Güvenlik: Tek kullanımlık
Limit: İşlem bazlı

Maliyet Karşılaştırması

YöntemKomisyonÖdeme SüresiGüvenlik
iyzico%2.49 + 0.25 TLT+23D Secure + PCI-DSS
PayTR%2.79 + 0.25 TLT+13D Secure + PCI-DSS
PayU%3.2 + 0.30 TLT+33D Secure + PCI-DSS
BKM Express%1.5T+2Banka Güvencesi
Havale/EFT%01-2 gün (manuel)Manuel Kontrol

Örnek Maliyet Hesabı (Aylık 500K TL Ciro):

iyzico: (500K × 2.49%) + (2000 işlem × 0.25) = 12,950 TL
PayTR: (500K × 2.79%) + (2000 işlem × 0.25) = 14,450 TL
BKM Express: 500K × 1.5% = 7,500 TL (en ekonomik)
Havale: 0 TL (ama manuel iş yükü)

Ödeme Sisteminizi Entegre Edelim

Güvenli, hızlı ve çoklu ödeme yöntemi entegrasyonu ile satışlarınızı artırın, müşteri memnuniyetini yükseltin.

Demo İste