İçeriğe geç
Muhammet Şafak
Günlük 2 dk okuma

Laravel ile ödeme entegrasyonu (iyzico) deneyimi

Laravel projelerinde iyzico ödeme entegrasyonu yaparken karşılaşılan gerçek sorunlar ve çözümleri; deneyim anlatısı.


Ödeme entegrasyonu yapmak, teoride basit görünüyor: API belgelerini oku, gerekli parametreleri gönder, yanıtı işle. Ama gerçekte bunun her adımında beklenmedik şeyler çıkıyor. Bu yazıda bir e-ticaret projesine iyzico entegrasyonu yaparken öğrendiklerimi paylaşıyorum — belgelerde olmayan, ancak uygulamada karşılaştığım şeyler.

Neden iyzico?

Türkiye’de kart ödemeleri için birkaç seçenek var. iyzico’yu tercih etmemin nedeni Türk geliştiriciler için hazırlanmış PHP SDK’sının olması ve sandbox ortamının gerçekten işlevsel olmasıydı. Stripe gibi uluslararası alternatiflerin o dönemde Türk bankaları ile entegrasyonu daha karmaşıktı.

SDK’yı Composer ile kurmak kolay:

composer require iyzipay/iyzipay-php

Ödeme akışı

iyzico’nun temel ödeme akışı şu adımlardan oluşuyor:

  1. Ödeme formu oluşturmak (istemciye iframe veya redirect).
  2. Kullanıcının kart bilgisini girmesi (iyzico’nun arayüzü).
  3. Ödeme sonucunu token ile doğrulamak.

3D Secure akışında işlem tamamlandığında iyzico bir callbackUrl’e POST göndiyor. Bu noktada uygulamanızın o isteği doğru karşılaması gerekiyor.

use Iyzipay\Options;
use Iyzipay\Model\Payment;
use Iyzipay\Request\CreatePaymentRequest;

$options = new Options();
$options->setApiKey(config('services.iyzico.api_key'));
$options->setSecretKey(config('services.iyzico.secret_key'));
$options->setBaseUrl(config('services.iyzico.base_url'));

$request = new CreatePaymentRequest();
$request->setLocale('tr');
$request->setConversationId((string) $order->id);
$request->setPrice($order->subtotal);
$request->setPaidPrice($order->total);
$request->setCurrency('TRY');

conversationId alanı kritik: kendi sipariş ID’nizi buraya yazıyorsunuz. iyzico bu değeri callback’te geri gönderiyor; böylece hangi siparişin ödendiğini eşleştirebiliyorsunuz.

Callback: en dikkat gerektiren yer

3D Secure akışında, kullanıcı bankasının doğrulama ekranını geçtikten sonra iyzico uygulamanızdaki callbackUrl’e POST isteği gönderiyor. Bu noktada yapmanız gereken:

  1. paymentId ile ödeme sonucunu iyzico API’sinden doğrulamak.
  2. Siparişi güncellemek.
  3. Kullanıcıyı uygun sayfaya yönlendirmek.

Burada öğrendiğim en önemli şey şu: callback URL’iniz güvenilir olmak zorunda. Kullanıcı tarayıcıyı kapayabilir, bağlantı kopabilir — bu durumlarda ödeme gerçekleşmiş ama sipariş güncellenememiş olabilir. Bu yüzden callback handler’ı queue’ya atmak yerine senkron tutmak ve olabildiğince kısa tutmak önemli. Sadece ödeme durumunu kaydedin; e-posta ve diğer işlemler queue’da bekleyebilir.

public function callback(Request $request)
{
    $token = $request->input('token');

    $retrieve = new RetrieveCheckoutFormResultRequest();
    $retrieve->setToken($token);
    $retrieve->setLocale('tr');

    $result = CheckoutForm::retrieve($retrieve, $this->options);

    if ($result->getPaymentStatus() === 'SUCCESS') {
        $order = Order::where('iyzico_token', $token)->firstOrFail();
        $order->markAsPaid($result->getPaymentId());
    }

    return redirect()->route('orders.show', $order);
}

Sandbox ile gerçek ortam farkı

Sandbox ortamı genel olarak iyi çalışıyor ama iki fark gördüm:

Yanıt süreleri: Sandbox bazen gerçek ortamdan yavaş davranıyor. Timeout değerlerini buna göre belirlemek gerekiyor; sandbox’ta çalışan bir şey gerçek ortamda farklı davranabilir.

3D Secure testi: Sandbox’ta 3D Secure akışını test etmek için iyzico’nun test kart numaraları kullanılıyor. Bu kartlar her zaman belgelenmiş şekilde davranmıyor; test etmek istediğiniz senaryoyu (başarılı, başarısız, yetersiz bakiye) doğru kart numarasıyla kurmak bazen zaman alıyor.

Hata mesajlarını loglayın

iyzico’nun yanıtlarındaki hata kodları bazen yeterince açıklayıcı olmuyor. Entegrasyon sürecinde, hem istek hem yanıtı loglayan bir yapı kurmak çok zaman kazandırdı. Üretimde hassas kart verisi loglara girmemeli ama ödeme ID’si, sipariş ID’si ve iyzico’nun döndürdüğü hata kodu loglarda olursa sorun tespiti kolaylaşıyor.

Ödeme entegrasyonu sabır isteyen bir iş. Temel akış iki günde kuruldu; ama edge case’leri (tekrarlanan callback, çift ödeme, zaman aşımı) kapatmak bir haftayı buldu. O haftayı geçirmeden önce belirli senaryolar için testler yazmamış olmak zamanla ortaya çıktı — sonraki entegrasyonlarda bu ders işe yaradı.

Etiketler: #Laravel
Paylaş:

İlgili Yazılar

Sitede Ara

Yazı, proje ve sayfalarda arama yapmak için yazmaya başlayın.

Esc ile kapat Pagefind ile güçlendirildi