Çeşitli Konular
 
Üye Girişi
E-mail:

Şifre:



 
Blog Arama Motoru
 
19 Mayıs 2012
Mustafa Kemal Atatürk
 
E-mail Aboneliği
Yeni yazılar yazıldığında e-mail adresinize bildirim gelmesini isterseniz aşağıdaki kutucuğa e-mail adresinizi girip 'Abone Ol'a tıklayabilirsiniz.

E-mail:

 
 
PayPal IPN (Anlık Ödeme Bildirimi)
   PayPal az bir kısmımızın kullandığı, çoğumuzun belki sadece adını duymuş olduğu bir para aktarım sistemi. Sistemin web üzerinde işliyor ve güvenliğin gerçekten ön planda tutuluyor olması onu çok kullanışlı bir para aktarım aracı haline getiriyor.

   IPN(Instant Payment Notification, anlık ödeme bildirimi) ise ödemeler ile ilgili bildirimlerin anında bir web sitesine gönderilebilmesini sağlayan bir servis. IPN sayesinde kullanıcı, sunduğunuz bir ürün veya hizmet için ödeme yaptığında, siz sitenize gönderilen bildirimi aldıktan sonra ödemeyi anında kayıt altına alıp işleyebiliyor ve karşılık gelen ürünü/hizmeti eğer mümkünse yine web üzerinden otomatik olarak kullanıcıya gönderebiliyorsunuz. Bu yazıda da PayPal ödeme sisteminin php dili ile bir web sitesine nasıl entegre edilebileceğini ve IPN'nin amacını bir örnek senaryo yardımıyla anlamaya çalışacağız.

   Senaryomuz şöyle; bir program yazdınız ve programınızın lisans anahtarlarını web üzerinden satışa sunmak istediniz. Bir kullanıcı siteniz üzerinden ödeme gerçekleştirir gerçekleştirmez lisans anahtarını ona yollamanız gerekiyor. Burada problem şu; ödemenin başarıyla gerçekleşip gerçekleşmediğini nasıl anlayacaksınız?

   Öncelikle ödeme için nasıl bir form hazırlanması gerekiyor, oradan başlayalım. PayPal, önceleri gerekli verilerin tümünü gizli html giriş elemanlarından alıyordu. Fakat elemanların içerikleri dışarıdan değiştirilebiliyor. Muhtemel dolandırma girişimlerinin engellenmesi için bildirim geldiğinde girişlerde bir değişiklik olup olmadığı kontrol edilebilse de PayPal daha sonraları gizli alanlarda tutulan ve değiştiğinde ödemeyi etkileyebilen bilgilerin kendi sunucularında saklanabilmesine imkan sağlamaya başladı...

Ödeme Alımı İçin Form Kodları
   Aşağıda 0000000000000 kimlikli buton bilgilerinin içerdiği miktarın ödenebilmesini sağlayan kod örneği var. Bu kodlar PayPal'deki bir araç sayesinde otomatik olarak hazırlanabiliyor.
<form method="post" action="https://www.paypal.com/cgi-bin/webscr">
    <input type="hidden" name="cmd" value="_s-xclick">
    <input type="hidden" name="hosted_button_id" value="0000000000000">
    <input type="submit" id="buton" value="PayPal İle Öde">
</form>

Gelişmiş Ayarlar ve Değişkenler
   PayPal'in hazır aracı ile buton oluşturulurken "Gelişmiş Özellikler" kısmını doldurarak satın alma işlemi iptal edildiğinde veya tamamlandığında kullanıcının hangi sayfalara yönlendirileceğini ayarlamak mümkün. Ek olarak ödeme bildiriminin yapılacağı adresin belirtilebilmesi için gelişmiş değişkenlere "notify_url=ödeme_bildiriminin_yapılacağı_url" ifadesinin eklenmesi gerekiyor.

   Form elemanı içerisine veya "Gelişmiş değişkenler" kutusuna farklı amaçlar ile bir sürü değişken daha eklenebilir. Örneğin kullanıcıdan almanız gereken bir bilgi varsa bunu form elemanına os0 isimli bir giriş elemanı ekleyerek yapabiliyorsunuz.<input type="text" name="os0" ... Bu değişkenlerin listesinin verildiği ve işlevlerinin açıklandığı sayfaya şuradan ulaşabilirsiniz.

Ödeme Bildiriminin Alınması Ve İşlenmesi

   Formunuzu hazırladınız, sitenize koydunuz. İlk müşteriniz geldi ve ödemesini yaptı. Eğer PayPal'de buton oluştururken gelişmiş değişkenlere "notify_url" değişkenini de eklediyseniz PayPal, ödeme ile ilgili tüm verileri post metodu ile belirttiğiniz sayfaya gönderir. Bildirimi alan sayfa, aldığı tüm değişkenleri "cmd=_notify-validate" ifadesini de ekleyerek /cgi-bin/webscr adresine geri gönderir ve bu adresten yanıt bekler. Amaç bilgilerin doğruluğunun onaylanmasını sağlamaktır. Sistem geri gelen verileri kontrol eder ve geçerlilerse komut beklemekte olan sayfaya "VERIFIED" bilgisini gönderir. Böylece ödeme onaylanmış olur ve bilgiler veritabanına işlenebilir. Örneğimize dönersek, artık lisans anahtarını kullanıcının e-mail adresine gönderebiliriz.

   Herhangi bir sorun yaşanması halinde sorunun anlaşılmasını kolaylaştırmak için yapılan tüm hareketlerin ve problemin nerede çıktığının kayıt altına alınması önerilir.

   Şimdi bu anlattıklarımızı kodlara dökelim:
<?php
if(!isset($_POST['payer_email'])) die(); // Sayfa direkt çağrılmışsa birşey yapma.

$ppSunucusu="www.paypal.com";
$ppAlici='alıcının mail adresi';
$fiyat='10'; // Mesela 10 dolar

function kayitTut($tutulacak) // Herşeyi kayıt altına almakta fayda var.
{
    $dosya=fopen('8SA4D83.txt','a'); //Log dosyası ismi tahmin edilemeyecek birşeyler olsun.
    fwrite($dosya,date('d/m/Y \- \S\a\a\t H:i')."\n$tutulacak"); // Zaman bilgisi de ekle
    fclose($dosya);
    die(); //kayitTut() çağrılınca iş bitmiş demektir, dur.
}

$geriYollanacak='';
$i=0;
foreach ($_POST as $alan=>$deger) // Tüm değişkenleri geri yollamak için toparla.
{
    $i++;
    $geriYollanacak.=$alan.'='.urlencode(stripslashes($deger)).'&';
    // Çok fazla post değişkeni gönderip sayfayı kilitlemek isteyenler için önlem:
    if($i>100) kayitTut("SALDIRI GIRISIMI\n\n");
}
$geriYollanacak.="cmd=_notify-validate"; // Doğrulama komutunu da ekle.

// Zaman aşımı 20 saniye...
$soket=fsockopen($ppSunucusu, 80, $hataKodu, $hataBilgisi, 20);
if(!$soket) // Bağlanamazsa not et.
    kayitTut("SOKET HATASI\n$hataKodu: $hataBilgisi\n$geriYollanacak\n\n");
else
{
    // Standart bir HTTP post komutu gönderiyoruz.
    fputs($soket, "POST /cgi-bin/webscr HTTP/1.1\r\n");
    fputs($soket, "Host: $ppSunucusu\r\n");
    fputs($soket, "Content-type: application/x-www-form-urlencoded\r\n");
    fputs($soket, "Content-length: ".strlen($geriYollanacak)."\r\n");
    fputs($soket, "Connection: close\r\n\r\n");
    fputs($soket, "$geriYollanacak\r\n\r\n");

    $ipnYaniti='';
    while(!feof($soket)) // Yanıtı oku
        $ipnYaniti.=fgets($soket, 32);

    fclose($soket);
}

if(stripos($ipnYaniti, "VERIFIED")!==false) // Cevapta "VERIFIED" geçiyorsa, onaylandı demektir.
{
    // Yine de değişkenlerin beklediğimiz değerleri taşıdığından emin olalım.
    if(
    $_POST['payment_status']=='Completed' &&
    $_POST['receiver_email']==$ppAlici &&
    $_POST['mc_gross']==$fiyat &&
    $_POST['quantity']=='1' &&
    $_POST['mc_currency']=='USD'
    )
    {
        // Paypal, tekrarları önlemek için işlem kimliğinin (transaction id, $_POST['txn_id'])
        // daha önce işlenmediğinden emin olunmasını öneriyor. Yani veritabanı kullanılması şart.
       
        // Mesela aşağıdakileri de veritabanına kaydetmek isteyebilirsiniz:
        $islemk=mysql_real_escape_string($_POST['txn_id'],$baglanti);
        $pid=mysql_real_escape_string($_POST['payer_id'],$baglanti);
        $ad=mysql_real_escape_string(stripslashes($_POST['first_name']),$baglanti);
        $soyad=mysql_real_escape_string(stripslashes($_POST['last_name']),$baglanti);
        $email=mysql_real_escape_string($_POST['payer_email'],$baglanti);
        // Diğer değişkenlerin listesini içeren sayfanın linki yukarıda...
       
        // Şimdi kullanıcıya teşekkür maili gibi birşey atabilirsiniz. Örneğin ödemeyi aldık,
        // veya lisans kodunuz şudur gibi birşeyler yazabilirsiniz...

        kayitTut("HERSEY TAMAM\n$geriYollanacak\n\n");
    }
    else
        kayitTut("DOLANDIRMA GIRISIMI\n$geriYollanacak\n\n"); // Demek ki biri yapay bildirim yollamış.
}
else
    kayitTut("VERILER ONAYLANMADI\n$geriYollanacak\n\n"); // PayPal verileri onaylamadı.
?>

PayPal Test Ortamı (Sandbox)
   Scripti yazdıktan hemen sonra direkt olarak kullanıma koymak biraz riskli olabilir. Herşeyin doğru olduğundan emin olmak için önce scripti test etmek isteyebilirsiniz. PayPal'in bu amaçla sunduğu test ortamı, gerçekte işlemeyen sanal hesaplar yaratabilmenizi ve alışveriş işlemlerini bu hesaplar ile taklit edilebilmenizi sağlıyor. Ortama http://www.sandbox.paypal.com adresi ile erişebilirsiniz. Scripti test ortamında denemek için hem formlarda hem de scriptte www.paypal.com adresi yerine www.sandbox.paypal.com adresini kullanmanız gerekiyor...
Yayınlanma Tarihi: 10 Ekim 2011 Pazartesi - 17:50
Anahtar Kelimeler: paypal ipn, anlık ödeme bildirimi, instant payment notification, web sitesi entegrasyonu, ödemeyi alma, paypal ile ödeme
Yorumlar ( 2 )
İstanbul KAdıköy
#1

18/02/2012, 20:54

teşekkür ederim, iyi bir bilgi olmuş.. yeni kodlara göre bir seçeneğimiz var mı bu kodların geçerlilik tarihi nedir?
Hüseyin Atasoy
#2

19/02/2012, 16:06

"yeni kodlara göre" derken neyi kastettiğinizi anlayamadım ama çok kısa bir süre öncesine kadar kullanıyordum. Bir değişiklik olduğunu zannetmiyorum.
Yorum/Görüş Bildir
Yorumları html kodu veya özel karakter kullanmadan, yazım kurallarına
dikkat ederek ve düzgün bir Türkçe kullanarak yazalım...
 
Atasoy Blog v3.0 © 2009-2012 Hüseyin Atasoy | Tema Tasarımı: Hüseyin Atasoy