Laravel Paytr Entegrasyonu

Laravel Paytr Entegrasyonu

Laravel ile PayTR entegrasyonu yapmak için öncelikle PayTR'nin resmi dökümantasyonunu incelemeniz önemlidir. Burada Laravel için temel bir PayTR entegrasyonu örneği verilmiştir, ancak her zaman resmi dökümantasyonu kontrol edin ve uygun API sürümüne göre güncellemeler yapın.

  1. Öncelikle PayTR hesabınızdan API anahtarlarını (merchant ID, merchant key, merchant salt) alın.

  2. Laravel projenizde bir controller oluşturun

php artisan make:controller PaytrController
  1. PaytrController dosyasını açın ve aşağıdaki kodları ekleyin:
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class PaytrController extends Controller
{
    private $merchantId = 'MERCHANT_ID';
    private $merchantKey = 'MERCHANT_KEY';
    private $merchantSalt = 'MERCHANT_SALT';

    public function createPayment(Request $request)
    {
        // Ödeme bilgilerini alın
        $amount = $request->input('amount');
        $email = $request->input('email');

        // Token oluşturun
        $token = $this->generateToken($amount, $email);

        // Ödeme formunu döndürün
        return view('payment_form', ['token' => $token]);
    }

    private function generateToken($amount, $email)
    {
        // Parametreleri hazırlayın
        $params = [
            'merchant_id' => $this->merchantId,
            'user_ip' => $_SERVER['REMOTE_ADDR'],
            'merchant_oid' => time(),
            'email' => $email,
            'payment_amount' => $amount * 100, // Kuruş cinsinden
            'user_basket' => base64_encode(json_encode([])),
            'debug_on' => 1,
            'no_installment' => 1,
            'max_installment' => 1,
            'currency' => 'TL',
            'test_mode' => 0,
        ];

        // Hash oluşturun
        $hash = base64_encode(hash_hmac('sha256', implode('|', $params) . $this->merchantSalt, $this->merchantKey, true));
        $params['paytr_token'] = $hash;

        // Token isteği gönderin
        $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, $params);

        $response = curl_exec($ch);
        curl_close($ch);

        $result = json_decode($response);

        if ($result->status == 'success') {
            return $result->token;
        } else {
            throw new \Exception('Token oluşturma başarısız: ' . $result->reason);
        }
    }
}
  1. Ödeme formunu oluşturun (resources/views/payment_form.blade.php):
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Ödeme Formu</title>
</head>
<body>
    <form method="post" action="https://www.paytr.com/odeme/guvenli">
        <input type="hidden" name="merchant_id" value="{{ MERCHANT_ID }}" />
        <input type="hidden" name="user_ip" value="{{ $_SERVER['REMOTE_ADDR'] }}" />
        <input type="hidden" name="merchant_oid" value="{{ time() }}" />
        <input type="hidden" name="email" value="{{ $email }}" />
        <input type="hidden" name="payment_amount" value="{{ $amount * 100 }}" />
        <input type="hidden" name="user_basket" value="{{ base64_encode(json_encode([])) }}" />
        <input type="hidden" name="debug_on" value="1" />
        <input type="hidden" name="no_installment" value="1" />
        <input type="hidden" name="max_installment" value="1" />
        <input type="hidden" name="currency" value="TL" />
        <input type="hidden" name="test_mode" value="0" />
        <input type="hidden" name="paytr_token" value="{{ $token }}" />

        <button type="submit">Ödemeyi Tamamla</button>
    </form>
</body>
</html>

Bu örnek formda, kullanıcı ödemeyi tamamlamak için "Ödemeyi Tamamla" düğmesine tıkladığında, PayTR'nin güvenli ödeme sayfasına yönlendirilir. Ödeme süreci tamamlandığında, PayTR kullanıcıyı sitenize yönlendirecektir.

Formdaki MERCHANT_ID, MERCHANT_KEY ve MERCHANT_SALT değerlerini, PayTR hesabınızdan aldığınız gerçek değerlerle değiştirin.

Not: Bu örnek temel bir ödeme formunu ve entegrasyonunu gösterir. Gerçek projelerde, sepet detaylarını, sipariş numarasını ve diğer gerekli bilgileri uygun şekilde doldurun. Ayrıca, ödeme işlemi tamamlandığında PayTR tarafından gönderilen bildirimleri (IPN) doğrulamak için bir IPN işleyici de eklemelisiniz.

IPN (Instant Payment Notification) işleyiciyi Laravel uygulamanızda kullanmak için aşağıdaki adımları takip edin:

  1. routes/web.php dosyasında IPN işleyici için bir rota oluşturun:
    use App\Http\Controllers\PaytrController;
    
    Route::post('/paytr-ipn', [PaytrController::class, 'handleIpn']);
    
  1. PaytrController dosyasına IPN işleyiciyi ekleyin:
public function handleIpn(Request $request)
{
    $merchant_oid = $request->input('merchant_oid');
    $status = $request->input('status');
    $total_amount = $request->input('total_amount');
    $hash = $request->input('hash');

    // Gelen hash'i kontrol edin
    $hash_check = base64_encode(hash_hmac('sha256', $this->merchantId . $merchant_oid . $status . $total_amount, $this->merchantKey, true));

    if ($hash_check != $hash) {
        // Hash doğrulanamazsa, hatalı bir bildirim olarak kabul edin
        return response('INVALID_HASH', 400);
    }

    // Ödeme durumunu kontrol edin
    if ($status == 'success') {
        // Ödeme başarılı olduysa, siparişinizi güncelleyin
        // Siparişinizi burada güncelleyin: Ödeme tamamlandı, sipariş durumunu "ödendi" olarak güncelleyin
    } elseif ($status == 'failed') {
        // Ödeme başarısız olduysa, siparişinizi güncelleyin
        // Siparişinizi burada güncelleyin: Ödeme başarısız oldu, sipariş durumunu "ödenmedi" olarak güncelleyin
    } else {
        // Geçersiz bir durum değeri alındığında
        return response('INVALID_STATUS', 400);
    }

    // IPN işlemi başarıyla tamamlandığında "OK" döndürün
    return response('OK', 200);
}

Bu IPN işleyici, PayTR tarafından gönderilen bildirimleri işler ve ödeme durumunu kontrol eder. Gelen bildirimin hash değerini doğrular ve ödeme durumuna göre sipariş durumunu günceller. Ödeme başarılı veya başarısız olduğunda, uygun işlemleri gerçekleştirin, örneğin sipariş durumunu güncelleyin veya müşteriye e-posta gönderin.

Not: Bu örnek, temel IPN işleyici işlevini gösterir ve gerçek projelerde uygun şekilde düzenlemeler yapmanız gerekebilir. IPN işleyiciyi, projenizin gereksinimlerine göre özelleştirin ve veritabanında sipariş durumunu güncellemek için uygun işlemleri gerçekleştirin.

Ödeme durumunu veritabanına kayıt etmek için öncelikle Laravel'in Eloquent ORM ile basit bir Sipariş modeli ve veritabanı migrasyonu oluşturacağız.

  1. Sipariş modelini ve migrasyon dosyasını oluşturun:
php artisan make:model Order -m
  1. Oluşturulan database/migrations/xxxx_xx_xx_xxxxxx_create_orders_table.php dosyasını açın ve tablo yapısını düzenleyin:
public function up()
{
    Schema::create('orders', function (Blueprint $table) {
        $table->id();
        $table->string('merchant_oid');
        $table->unsignedFloat('amount');
        $table->string('email');
        $table->string('status')->default('pending');
        $table->timestamps();
    });
}
  1. Migrasyonu çalıştırarak veritabanı tablosunu oluşturun:
php artisan migrate
  1. Şimdi, IPN işleyicisinde ödeme durumunu güncelleyerek veritabanına kaydedeceğiz. PaytrController dosyasında, handleIpn() metodunu şu şekilde güncelleyin:
use App\Models\Order;

public function handleIpn(Request $request)
{
    // ... Diğer kodlar

    // Ödeme durumunu kontrol edin
    if ($status == 'success') {
        // Ödeme başarılı olduysa, siparişinizi güncelleyin
        $order = Order::where('merchant_oid', $merchant_oid)->first();
        if ($order) {
            $order->status = 'paid';
            $order->save();
        }
    } elseif ($status == 'failed') {
        // Ödeme başarısız olduysa, siparişinizi güncelleyin
        $order = Order::where('merchant_oid', $merchant_oid)->first();
        if ($order) {
            $order->status = 'unpaid';
            $order->save();
        }
    } else {
        // Geçersiz bir durum değeri alındığında
        return response('INVALID_STATUS', 400);
    }

    // IPN işlemi başarıyla tamamlandığında "OK" döndürün
    return response('OK', 200);
}

Bu kodlar sayesinde, PayTR tarafından gönderilen IPN bildirimine göre ödeme durumunu güncelleyip veritabanında kaydediyoruz. Başarılı ödemelerde sipariş durumunu 'paid' (ödendi) olarak, başarısız ödemelerde 'unpaid' (ödenmedi) olarak güncelliyoruz.

Not: Bu örnek, temel bir Sipariş modeli ve IPN işleyici işlevini gösterir. Gerçek projelerde, sepet detaylarını, kullanıcı bilgilerini ve diğer gerekli alanları da eklemeyi düşünün. Ayrıca, kodları projenizin gereksinimlerine göre özelleştirin ve gerekli durumlarda veritabanı işlemlerini gerçekleştirin.