Archiwa kategorii: paypal

P??atno??ci online bezwzgl─?dnie bezpieczne? Przeczytaj i przekonaj si─? sam jak uczyni─? je jeszcze bardziej bezpieczne.

Paypal – wst─?p

Do napisania tego oto tutorialu zmotywowa??y mnie wiele rzeczy po pierwsze w polskim internecie nie ma zbyt wiele na temat p??atno??ci paypal’em. Znalaz??em na kilku forach zapytania na ten temat. Z czego sam jedno napisa??em na forum.php.pl. Drug─? przes??ank─? kt??ra u??wiadomi??a, ??e paypal zaczyna zdobywa─? polski rynek p??atno??ci online jest fakt umowy jak─? paypal.com podpisa?? z p??atno??ci.pl i ju?? nied??ugo b─?dziemy mogli si─? cieszy─? p??aceniem za us??ugi i produkty w ten wygodny spos??b. Kolejn─? spraw─?, kt??ra pokaza??a mi jak bardzo szkodliw─? rzecz─? mo??e by─? nieumiej─?tne korzystanie z „Buy Now” (tych nie kodowanych) gdzie wystarczy ze ??r??d??a strony wyci─?─?:

<input type="hidden" name="return" value="url_po_udanej_transakcji" />

by uzyska─? dost─?p do zasobu kt??ry chcemy kupi─?. Nast─?pny fakt wyp??yn─??? na ??wiat??o dzienne gdy sam pisa??em obs??ug─? IPN na Paypal’u i zobaczy??em, ??e nawet tutorial’e i przyk??ady na stronie developer center @ paypal maj─? b??─?dy(mnie szczeg??lnie ineteresowa?? ten do php4). A Koniec ko??c??w w poszukiwaniu gotowych rozwi─?za?? tj. klas, funkcji kt??re mog??y by zaspokoi─? moje potrzeby. Znalaz??em dwa takie rozwi─?zania. Pierwsze z nich na phpclasses.org by??o mocno rozbudowane i zabezpieczone szyfrowaniem. Jednak mia??o jedn─? podstawow─? wad─? wymaga??o „doklejenia” kolejnych 3 du??ych bibliotek. Natomiast drugie z nich po wst─?pnych testach okaza??o si─? nie dzia??a─? tak jak bym chcia??, wi─?c postanowi??em napisa─? co?? w??asnego.
Tyle s??owem wst─?pu teraz przedstawie czego b─?dziemy potrzebowa─? do wdro??enia p??atno??ci paypal’em na naszej stronie.

Po pierwsze do test??w paypal udost─?pnia nam sandbox. ??eby do owej „piaskownicy” uzyska─? dost─?p trzeba za??o??y─? sobie konto na: developer.paypal.com . Po za??o??eniu konta i potwierdzeniu prawdziwo??ci skrzynki e-mail. Mamy mo??liwo??─? za??o??enia kont testowych. B─?d─? nam potrzebne takie dwa: pierwsze buissnes account do testowania p??atno??ci i wygenerowania kodu button??w na, kt??rych b─?dziemy testowali nasze rozwi─?zania, drugie natomiast kupuj─?cego po to by zbada─? sam proces dokonywania p??atno??ci.

Uwaga! wa??ne do testowania p??atno??ci na sandbox’ie wymaga bycia zalogowanym na developer.paypal.com

Aby zrozumie─? temat bardziej sp??jrzmy na poni??szy schemat.

Schemat Dzia??ania IPN w p??atno??ciach paypal.com

Dla klienta zasada jest prosta. Rejestruje si─? na naszej stronie. Op??aca us??ug─? np. abonament na dost─?p do poprzednich wyda?? naszego magazynu w plikach pdf po przez klikni─?cie Buy Now. Jest przekierowany na strone paypal’a gdzie loguje si─? na swoje konto lub p??aci kart─? p??atnicz─?. Po pozytywnym zako??czeniu transakcji wraca na nasz─? stron─? z podzi─?kowaniami tzw „return”. Paypal gubi ka??d─? sesje wi─?c nie ma co liczy─? na jej odzyskanie po powrocie. Rozwi─?zaniem najprostszym jest odes??anie klienta po podzi─?kowaniu do formularza logowania.

Serwer paypala opr??cz tego. ??e przeprowadza ca??─? transakcje i odpowiedzialno??─? za wpisane tam poufne dane takie jak numer karty kredytowej s─? po jego stronie. To jeszcze przekazuje nam dane na temat transakcji za po??rednictwem IPN(instant payment notification). Dzieje si─? to w nast─?puj─?cy spos??b. Po dokonaniu wp??aty na paypalu wysy??a do naszego skryptu na adres podany w:

<input type="hidden" name="notify_url" value="url_do_skryptu_obs??uguj─?cego_ipn"  />

przekazuje nam pule zmiennych metod─? POST min.

$invoice = $_POST['invoice'];

$receiver_email = $_POST['receiver_email'];

$item_name = $_POST['item_name'];

$item_number = $_POST['item_number'];

$quantity= $_POST['invoice'];

$payment_status = $_POST['payment_status'];

$pending_reason = $_POST['pending_reason'];

$payment_date = $_POST['payment_date'];

$payment_gross = $_POST['payment_gross'];

$payment_fee = $_POST['payment_fee'];

$payment_amount = $_POST['mc_gross'];

$payment_currency = $_POST['mc_currency'];

$txn_id = $_POST['txn_id'];

$txn_type = $_POST['txn_type'];

$first_name = $_POST['first_name'];

$last_name = $_POST['last_name'];

$address_street = $_POST['address_street'];

$address_city = $_POST['address_city'];

$address_state = $_POST['address_state'];

$address_zip = $_POST['address_zip'];

$address_country = $_POST['address_country'];

$payer_email = $_POST['payer_email'];

$address_status = $_POST['address_status'];

$payment_type = $_POST['payment_type'];

$notify_version = $_POST['notify_version'];

$verify_sign =$_POST['verify_sign'];

Dzi─?ki tym zmiennym mo??emy po pierwsze rozpozna─? czy p??atno??─? zosta??a zako??czona powodzeniem:

$_POST['payment_status'] == "succes"

Oraz pozna─? bli??ej dane naszego klienta. Jego dane jakie poda?? na naszej stronie mog─? si─? r????ni─? od tych danych jakie widniej─? na paypalu. Mo??emy je wykorzysta─? jako powi─?kszenie naszej bazy do mailing??w z promocjami, b─?d?? zachowa─? je tylko po to by rejestrowa─? sprzeda?? prowadzon─? na naszej stronie.

Jednak zanim obs??u??ymy otrzymane ??─?danie musimy sprawdzi─? czy aby na pewno pochodzi z paypal’a. Wystarczy z??o??y─? wszystkie zmienne przekazane postem w ci─?g znak??w typu zmienna1=5&zmienna2=6&….. itd. Jednak zanim to jednak zrobimy musimy doda─? na samym pocz─?tku komend─?, kt??ra poinformuje paypal, ??e chcemy dokona─? potwierdzenia czy takie ??─?danie zosta??o wys??ane przez paypal czy te?? nie. Zrobimy to nast─?puj─?cym kodem:

$req = 'cmd=_notify-validate'; //dok??adamy komend─? z pro??b─? o potwierdzenie tego powiadomienia o p??atno??ci
foreach ($_POST as $key => $value) {
$value = urlencode($value);
$req .= "&$key=$value";

}

//zmienna req teraz przechowuje wszystkie zmienne z $_POST w postaci kt??r─? opisywa??em wcze??niej

Nast─?pnie wystarczy wys??a─? takie zapytanie do serwera paypala. S─? dwie szko??y wysy??ania, albo fsockopen() albo za pomoc─? klasy cURL. Oba s─? poprawne. Ja zaprezentuje fragment kodu wykorzystuj─?cy pierwsz─? z nich.

$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n"; // ustawiamy nag????wki zapytania.

$header .= "Content-Type: application/x-www-form-urlencoded\r\n";

$header .= "Content-Length: " . strlen($req) . "\r\n\r\n"; // w tej linii zamieszczamy d??ugo??─? naszego zapytania

$fp = fsockopen (paypal_adr, 80, $errno, $errstr, 30); //sta??a paypal_adr jest adresem na kt??ry wysy??amy nasze zapytanie z pro??b─? o validacje

Sta??a paypal_adr mo??e mie─? dwie warto??ci: pierwsz─? testow─? https://www.sandbox.paypal.com lub drug─? ju?? w pe??ni funkcjonaln─? https://www.paypal.com czasami pojawia si─? problem z https:// poniewa?? niekt??re serwery nie maj─? skonfigurowanego portu.

Otwarli??my deskryptor portu $fp. Teraz musimy wys??a─? nasze dane do validacji.

if (!$fp) { // sprawdzamy czy wszystko ok z naszym po??─?czeniem je??eli nie jest to deskryptor przyjmuje warto??─? false
	// tutaj mo??emy napisa─? obs??ug─? HTTP ERROR
} else {
	fputs ($fp, $header . $req); // je??eli deskryptor jest ok to wysy??amy mu nasze nag????wki po??─?czone z zapytaniem o validacje powiadomienia

Je??eli ju?? wys??ali??my nasz─? pro??be o potwierdzenie ??─?dania teraz musimy obs??u??y─? odpowied?? serwera paypal, kt??ry zwr??ci nam string z informacj─? czy wszystko posz??o tak jak powinno czy te?? to odwo??anie by??o tylko pr??b─? wy??udzenia od nas towaru.
Zatem zaczynamy od odczytania odpowiedzi do p??ty do p??ki nie dostaniemy znaku ko??ca pliku. Kod kt??ry si─? tym zajmie mo??e wygl─?da─? tak:

while (!feof($fp)) {
	$res = fgets ($fp, 1024);

Otrzymali??my wi─?c ju?? ca??─? zawarto??─? odpowiedzi i przechowujemy j─? w zmiennej $res. Teraz trzeba by by??o sprawdzi─? czy ta p??atno??─? jest potwierdzona czy te?? nie. Do tego pos??u??y nam funkcja kt??ra por??wnuje binarnie dwa ci─?gi znak??w strcmp(). Je??eli oba por??wnywane ci─?gi s─? identyczne to funkcja zwraca 0. Kod, kt??ry sprawdzi odpowied?? m??g?? by wygl─?da─? tak:

if (strcmp($res, "VERIFIED")==0) {
	//Sprawdzamy czy transakcja ma status jako zako??czona
	if (strcmp ($payment_status, "Completed") == 0) {
		//je??eli tak to mo??emy spokojnie dalej przetwarza─? dane
	}
}else if(strcmp($res, "INVALID")==0){
	// mo??emy zarejstrowa─? do pliku wszystkie pr??by atak??w na nasz serwis np. tak:
	$fplog = fopen('ipnlog.txt','a');
	fwrite($fplog, gmstrftime ("%b %d %Y %H:%M:%S", time())." -- ".$res." -- ".$req."\n");
	fclose($fplog);
}

Zatem wiecie ju?? na jakiej zasadzie mo??na obs??ugiwa─? IPN otrzymany od paypal’a. Nie taki diabe?? straszny jak si─? okazuje. Jednak mi on napsu?? sporo krwi. Ci─?g dalszy wkr??tce nast─?pi jak tylko znajd─? troch─? czasu.