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ı...
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>
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.
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. { //Log dosyası ismi tahmin edilemeyecek birşeyler olsun. $dosya=fopen('8SA4D83.txt','a'); // Zaman bilgisi de ekle fwrite($dosya,date('d/m/Y \- \S\a\a\t H:i')."\n$tutulacak"); fclose($dosya); die(); //kayitTut() çağrılınca iş bitmiş demektir, dur. } $geriYollanacak=''; $i=0; // Tüm değişkenleri geri yollamak için toparlayalım foreach ($_POST as $alan=>$deger) { $i++; $geriYollanacak.=$alan.'='.urlencode(stripslashes($deger)).'&'; // 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); } // Cevapta "VERIFIED" geçiyorsa, onaylandı demektir. if(stripos($ipnYaniti, "VERIFIED")!==false) { // 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"); // Yapay bildirim! } else kayitTut("VERILER ONAYLANMADI\n$geriYollanacak\n\n"); // PayPal verileri onaylamadı. ?>
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...
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?
"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.
merhaba hüseyin bey ..
sizden paypal ile ilgili şöyle bir yardım rica edecektim..
sitemde paypal mevcut ödeme hersey tamam..Fakat ödeme success olduktan sonra paypal sayfasından otomatik olarak geri siteye dönüş olmuyor..Şöyleki.. Paypalda success olan ödeme paypal sayfasında Link to back site şeklinde link oluyor ve ona tıklarsan geliyor.Böylece panele "ödendi" ibaresi düşüyor.
paypal ayarlarından autoreturn url var fakat orada sabit bir link vverilebiliyor. ama öylede bizim ödendi doğrulamasını yapacağımız ürün hangisi bilemeyiz.
bu konuda geniş bilginiz varsa çok yardımınız olacak..
mesela bazı cash ödemelerde yabancı sitelerde gördüm.Paypal ile succes aldıktan sonra Lütfen bekleyin Geri yönlendiriliyorsunuz tarzında yazı cıkıyor ve geldigi sayfaya yonlenio ve doğrulamayı vveriıyor sitede Ödeme başarılı gibisinden.
ihtiyacım olan şey aynen böyle.Yoksa paypaldaki success ekranında siteye geri girmek için tıklayın linkini bekleyecek olursak oooo ödendi bilgisi zor düşer ekranımıza buda sıkıntı yapar.
şimdiden tşkler
Bahsettiğiniz autoreturn kısmını seçin ve adresi boş geçin. Boş geçilmiyorsa herhangi birşey yazın. Çünkü formda return değişkenine yazacağınız değer, profil ayarlarında yazacağınız değerin yok sayılmasını sağlayacak. Bir de geri dönüş anında tüm bilgilerin POST ile geri dönülen sayfaya gönderilmesini isterseniz rm değişkenine 2 değerini vermelisiniz. Böylece hangi ürünün satışından sonra geri dönüldüğünü de anlamanız mümkün. Özetle, autoreturn'ü işaretledikten sonra sitenizdeki form elemanına aşağıdaki eklemeleri yapmanız yeterli:
<input type="hidden" name="return" value="http://geridönüşadresi">
<input type="hidden" name="rm" value="2">
İlgili açıklamaları bulabileceğiniz iki sayfa adresi aşağıda:
https://www.paypal.com/cgi-bin/webscr?cmd=p/pop/express_return_url-outside
https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_html_Appx_websitestandard_htmlvariables
Gerçekten çok yararlı bir yazı olmuş. Ben de ödeme sistemi yapacağım, kod hakkında daha sonra yorum yaparım.
Paypal artık geçersiz. Çünkü,Türkiye'deki faaliyetlerini durdurmuş. Artık Türkiye'de paypal üzerinden para gönderme ve alma işlemi yapılamayacakmış. Paypal müşterileri daha önceden hesaplarında biriken paraları Türkiye'deki banka hesaplarına aktarabilirlermiş. https://www.paypal.com/tr/home
Merhaba ben bir soru sormak istiyorum,
Ben odeme islemlerini hallediyorum fakat geri donuste kontrol sorunu yasiyorum ornek ben kontorulu su sekilde yapiyorum.
Kullanici odeme islemi yapacagi zaman paypal email adresini girmesini istiyorum odeme yapildiktan sonra kontrol ediyorum email esitmi ve islem success mi sonra veritabanina kaydediyorum.
Ama ben istiyorum ki post ederken bir token yollayim o tokeni bana paypal geri post etsin ordan karsilastirayim istiyorum.
İyi calismalar.
Üstünden çok zaman geçti PayPal ile ilgilenmeyeli ama hatırladığım kadarıyla böyle birşey yoktu. Email ile sorgulama yapmaya gerek kalmıyor çünkü zaten ödeme geldiğinde paypal sizin belirlediğiniz sayfaya POST isteği gönderiyor. Bu istekteki değişkenlerin içinde ödeme ile ilgili detaylar mevcut. Normalde bu sayfanın adının bilinmemesi bile kısmen güvenli olmasına yetecekken, olur da sahte bir post atılırsa diye de gönderilen değişkenlerin doğruluğunu onaylamak için yine PayPal'e doğrulama amaçlı bir http isteği gönderebiliyorsunuz. Ödeme kontrolünü bu akışa uygun hale getirebilirsiniz.