eh... ne stizem, ne stizem :(
Elem, idemo.
Nekoliko napomena, varijable su izmenjene radi zastite ;)
Pocetak komunikacije sa PayPal-om.
order_confirm.php
Code:
$button = "
<form action='SetExpressCheckout.php' method='post'>
<input type = 'hidden' name = 'Price' value = '$totalprice'>
<input type = 'hidden' name = 'PriceMax' value = '$totalprice'>
<input type = 'hidden' name = 'SetOrderDescription' value = 'Package $pname ($paymentname)'>
<input type='image' src='https://www.paypal.com/en_US/i/btn/x-click-but03.gif' border='0' name='submit' alt='Make payments with PayPal - it's fast, free and secure!'>
<input type='hidden' name='encrypted' value='-----BEGIN PKCS7-----Bq0JFkacEHKlEeoNdXv8aRNXg5HoQZr9Gp9mLk1zkoaIUWnLU+==-----END PKCS7-----'>
</form>";
-----BEGIN PKCS7-----
i
-----END PKCS7-----
je napravio sam PayPal, a na osnovu public / private key, koji je smesten na mom i njihovom serveru (sama varijabla je _mnogo_ duza, pa lomi izlged ES-a, te sam je ja skratio). Dugme je takodje od PayPal-a, naravno namerno ga nisam menjao kako bi look & feel PayPal-a ostalo, posto su poznati, te samim tim znace nesto ;)
Kada korisnik klikne na pomenuto dugme, PayPal-u se salju parametri: Price, PriceMax, SetOrderDescription. Te parametre definise moj sajt, a na osnovu onoga sto je korisnik izabrao. Zatim korisnik stize na PayPal sajt, preko SetExpressCheckout.php, koji izgleda ovako:
SetExpressCheckout.php
(vidi kometare u kodu, za sta cemu sluzi! njih sam ja dodao)
Code:
<?php
session_start();
// ucitavanje paypal api-ja, ovo je 1-na-1 stavljeno na server, iz njihovog primera
require_once 'Services/PayPal.php';
require_once 'Services/PayPal/Profile/Handler/File.php';
require_once 'Services/PayPal/Profile/API.php';
// ucitava public key i settings od mog PayPal racuna
// kod mene smesteni u /var/paypal
$handler =& ProfileHandler_File::getInstance(array (
'path' => '/var/paypal',
'charset' => 'iso-8859-1',
));
if (Services_PayPal::isError($handler)) {
var_dump($handler->getMessage());
exit;
}
// ovde PayPal provera moje podatke, saljuci moju identifikaciju PayPal serveru
$profile =& APIProfile::getInstance('dasda78sd8a7sd', $handler);
if (Services_PayPal::isError($profile)) {
var_dump($profile->getMessage());
exit;
}
// saljem sifru, da se identifikuje prethodni API poziv
$profile->setAPIPassword('GDGDSFR545GDGFG');
// ok, to sam ja, kaze PayPal
$caller =& Services_PayPal::getCallerServices($profile);
if (Services_PayPal::isError($caller)) {
var_dump($caller->getMessage());
exit;
}
// Koji servis API-ja koristim
$OrderTotal =& Services_PayPal::getType('BasicAmountType');
if (Services_PayPal::isError($OrderTotal)) {
var_dump($OrderTotal);
exit;
}
// Podesavam sta naplacujem i koliko
// $_POST['Price'] je iz order_confirm.php
$OrderTotal->setattr('currencyID', 'EUR');
$OrderTotal->setval($_POST['Price'], 'iso-8859-1');
$MaxAmount =& Services_PayPal::getType('BasicAmountType');
if (Services_PayPal::isError($MaxAmount)) {
var_dump($MaxAmount);
exit;
}
// Podesavamo drugi parametar - maximalnu cenu koju proizvod moze da dostigne
$MaxAmount->setattr('currencyID', 'EUR');
$MaxAmount->setval($_POST['PriceMax'], 'iso-8859-1');
$SetExpressCheckoutRequestDetails =& Services_PayPal::getType('SetExpressCheckoutRequestDetailsType');
if (Services_PayPal::isError($SetExpressCheckoutRequestDetails)) {
var_dump($SetExpressCheckoutRequestDetails);
exit;
}
// Podesavamo ostale parametre, kod mene konkretno:
// ne treba mi shipping adresa, max cenu, zatim:
// cancellurl - gde da se korisnik 'vrati' na moj sajt ako odustane od kupovine;
// returnurl - gde da se vrati ako potvrdi kupovinu
// ordertotal (ukupna cena, odnosno zbir svih proizvoda)
// poslednje je koja vrsta PayPal servisa je u pitanju (pored ovoga postoji jos recimo Shopping Cart).
$SetExpressCheckoutRequestDetails->setNoShipping('1', 'iso-8859-1');
$SetExpressCheckoutRequestDetails->setMaxAmount($MaxAmount);
$SetExpressCheckoutRequestDetails->setCancelURL('http://www.nekimojdomen.com/signup_cancell.php', 'iso-8859-1');
$SetExpressCheckoutRequestDetails->setReturnURL('http://www.nekimojdomen.com/signup_confirm.php', 'iso-8859-1');
$SetExpressCheckoutRequestDetails->setOrderTotal($OrderTotal);
$SetExpressCheckout =& Services_PayPal::getType('SetExpressCheckoutRequestType');
if (Services_PayPal::isError($SetExpressCheckout)) {
var_dump($SetExpressCheckout);
exit;
}
// Izvrsavanje API-a
$SetExpressCheckout->setSetExpressCheckoutRequestDetails($SetExpressCheckoutRequestDetails);
$result = $caller->SetExpressCheckout($SetExpressCheckout);
if (Services_PayPal::isError($result)) {
var_dump($result);
}
else
{
// uspesno prosao SOAP call, onda se ide na PayPal sajt, sa tokenom, koji je gore kreiran i meni vracen
// SOAP call succeded, let's move on...
$url = "https://www.sandbox.paypal.com...d=_express-checkout&token=";
$token = $result->getToken();
$_SESSION['mycrontab_signup']['token'] = $token;
header("Location: $url$token");
}
?>
U ovom gore kodu, se ukratko desava:
saljem podatke o kupovini PayPal serveru (i tom prilikom se identifikujem). Na ovaj nacin 'spremam' PayPal, da cu poslati musteriju. Ako sve prodje kako treba, PayPal uzvraca sa token-om, koji prosledjujem na kraju u URL-u. Sada, kada korisnik stigne na PayPal sajt, PayPal zna vec o kome se radi, te ispisuje korisniku sve relevantne informacije. Korisnik se ovom prilikom loguje na PayPal sa svojim nalogom. Ako klikne: continue, PayPal vraca korisnika na moj sajt (returnurl), a istovremeno PayPal salje meni informacije o korisniku koje koristim u sledecem fajlu:
signup_confirm.php
(komentar, ponovo u samom kodu)
Code:
<?php
require_once("class2.php");
require_once(HEADERF);
// let's see if they are coming from good page, no direct linking!
if($_SESSION['signup']['page'] != '1')
{
ob_start();
echo "You will be redirected to SignUp page in 10 seconds.<br>
Or, you can click <a href = 'signup'>here</a> to go there immediately.";
sleep(10);
header("Location: http://www.nekimojdomen.com/signup.php");
require_once(FOOTERF);
ob_end_clean();
}
// PayPal API, 1-na-1 kopirano sa PayPal sajta
require_once 'Services/PayPal.php';
require_once 'Services/PayPal/Profile/Handler/File.php';
require_once 'Services/PayPal/Profile/API.php';
session_start();
// Provera ko sam ja (key i ispod password)
$handler =& ProfileHandler_File::getInstance(array (
'path' => '/var/paypal',
'charset' => 'iso-8859-1',
));
if (Services_PayPal::isError($handler)) {
var_dump($handler->getMessage());
exit;
}
$profile =& APIProfile::getInstance('sdfr43rfwetrf534e', $handler);
if (Services_PayPal::isError($profile)) {
var_dump($profile->getMessage());
exit;
}
$profile->setAPIPassword('SDFRT453FDE34');
$caller =& Services_PayPal::getCallerServices($profile);
if (Services_PayPal::isError($caller)) {
var_dump($caller->getMessage());
exit;
}
$GetExpressCheckoutDetails =& Services_PayPal::getType('GetExpressCheckoutDetailsRequestType');
if (Services_PayPal::isError($GetExpressCheckoutDetails)) {
var_dump($GetExpressCheckoutDetails);
exit;
}
// uzimamo token, to nam je identifikacije ove transakcije
$GetExpressCheckoutDetails->setToken($_SESSION['signup']['token'], 'iso-8859-1');
$result = $caller->GetExpressCheckoutDetails($GetExpressCheckoutDetails);
if (Services_PayPal::isError($result)) {
var_dump($result);
}
else
{
/* Success */
//var_dump($result);
// storing all neccessary parameters
// data needed for the payment proccess
// Ovde saznajemo ko nam je korisnik, kako bi korisnik proverio svoje podatke, pre definitivne kupovine!!
$fname = $result->GetExpressCheckoutDetailsResponseDetails->PayerInfo->PayerName->getFirstName();
$lname = $result->GetExpressCheckoutDetailsResponseDetails->PayerInfo->PayerName->getLastName();
$token = $result->GetExpressCheckoutDetailsResponseDetails->getToken();
$custmail = $result->GetExpressCheckoutDetailsResponseDetails->PayerInfo->getPayer();
$custid = $result->GetExpressCheckoutDetailsResponseDetails->PayerInfo->getPayerID();
// data needed for DB
$purchase_time = $result->getTimestamp();
$ack = $result->getAck();
$_SESSION['signup']['first_name'] = $fname;
$_SESSION['signup']['last_name'] = $lname;
$_SESSION['signup']['payer_email'] = $custmail;
$_SESSION['signup']['payer_id'] = $custid;
// Let's show the user details of the transaction
$transtable = "
<form name = 'doexpresschechout' action = 'signup_complete.php' method = 'POST'>
<table width = 80% border = 0>
<tr>
<td colspan = 2><center><b>Order confirmation</b></center></td>
</tr>
<tr>
<td colspan = 2><br></td>
</tr>
<tr>
<td colspan = 2><center><b>Your details</b></center></td>
</tr>
<tr>
<td>First name</td>
<td>$fname</td>
</tr>
<tr>
<td>Last name</td>
<td>$lname</td>
</tr>
<tr>
<td>E-Mail</td>
<td>$custmail</td>
</tr>
<tr>
<td colspan = 2><br></td>
</tr>
<tr>
<td colspan = 2><center><b>Product info</b></center></td>
</tr>
<tr>
<td>Product</td>
<td>".$_SESSION['signup']['product']."</td>
</tr>
<tr>
<td>Contract period</td>
<td>".$_SESSION['signup']['contract']."</td>
</tr>
<tr>
<td>Payment</td>
<td>".$_SESSION['signup']['payment']."</td>
</tr>
<tr>
<td>Price</td>
<td>".$_SESSION['signup']['price']."</td>
</tr>
<tr>
<td colspan = 2><br></td>
</tr>
<tr>
<td colspan = 2><center><input type='image' src='e107_images/x-click-but01.gif' border='0' name='submit' alt='Make payments with PayPal - it's fast, free and secure!'></center></td>
</tr>
<tr>
<td>
<input type = 'hidden' name = 'token' value = '".$_SESSION['signup']['token']."'>
<input type = 'hidden' name = 'payerid' value = '".$custid."'>
<input type = 'hidden' name = 'paymentdetails' value = '".$pdetails."'>
<input type = 'hidden' name = 'ordertotal' value = '".$_SESSION['signup']['price']."'>
</table>
</form>";
// u tabeli imamo 4 hidden polja, koja saljemo na sledecu stranicu jer su potrebna za izvrsenje transakcije
echo $transtable;
}
require_once(FOOTERF);
?>
u ovom fajlu smo primili korisnika nazad od PayPal-a. Sada je korisnik ulogovan u svoj PayPal nalog, te znamo ko je. Nakon sto korisniku jos jednom prikazemo sve podatke o kupovini, nudimo mu opciju da pritiskom na dugme izvrsi transakciju. To se desava u fajlu signup_confirm.php. Zanimljivo je samo to da PayPal salje nekoliko podataka o samom korisniku. Mene je zanimalo samo ovo gore navedeno, ali izmedju ostalog moguce je recimo saznati odakle je korisnik, ima li 'overen' PayPal nalog ili ne itd...
signup_confirm.php
(opet, komentari u samom fajlu)
Code:
<?php
session_start();
// PayPal API
require_once 'Services/PayPal.php';
require_once 'Services/PayPal/Profile/Handler/File.php';
require_once 'Services/PayPal/Profile/API.php';
require_once("class2.php");
require_once(HEADERF);
// let's see if they are coming from good page, no direct linking!
if($_SESSION['signup']['page'] != '1')
{
echo "You will be redirected to SignUp page in 10 seconds.<br>
Or, you can click <a href = 'signup'>here</a> to go there immediately.";
wait(10);
header("Location: http://www.nekimojdomen.com/signup.php");
require_once(FOOTERF);
}
// provera ko sam ja kod PayPal-a (public / private key)
$handler =& ProfileHandler_File::getInstance(array (
'path' => '/var/paypal',
'charset' => 'iso-8859-1',
));
if (Services_PayPal::isError($handler)) {
var_dump($handler->getMessage());
exit;
}
$profile =& APIProfile::getInstance('c8d566788388ad83feda294b69da245a', $handler);
if (Services_PayPal::isError($profile)) {
var_dump($profile->getMessage());
exit;
}
// saljem sifru za moj key
$profile->setAPIPassword('FDMEC9SXW6R7ZXM4');
// PayPal provera ko sam ja
$caller =& Services_PayPal::getCallerServices($profile);
if (Services_PayPal::isError($caller)) {
var_dump($caller->getMessage());
exit;
}
$OrderTotal =& Services_PayPal::getType('BasicAmountType');
if (Services_PayPal::isError($OrderTotal)) {
var_dump($OrderTotal);
exit;
}
// Podesavamo sta treba transakcija da sadrzi
$OrderTotal->setattr('currencyID', 'EUR');
$OrderTotal->setval($_SESSION['signup']['price'], 'iso-8859-1');
$PaymentDetails =& Services_PayPal::getType('PaymentDetailsType');
if (Services_PayPal::isError($PaymentDetails)) {
var_dump($PaymentDetails);
exit;
}
// Saljemo sve potrebne podatke PayPal-u, koji ce se izmedju ostalog pojaviti korisniku u transakciji
$PaymentDetails->setOrderDescription($_SESSION['signup']['product'] ($_SESSION['signup']['contract']), 'iso-8859-1');
$PaymentDetails->setCustom('Nekimojdomen.com first purchase', 'iso-8859-1');
$PaymentDetails->setOrderTotal($OrderTotal);
$DoExpressCheckoutPaymentRequestDetails =& Services_PayPal::getType('DoExpressCheckoutPaymentRequestDetailsType');
if (Services_PayPal::isError($DoExpressCheckoutPaymentRequestDetails)) {
var_dump($DoExpressCheckoutPaymentRequestDetails);
exit;
}
// DoExpressCheckoutPaymentRequestDetails --> ovo govori PayPal-u: izvrsi transakciju
// navedeni parametri su obavezni, a ima jos gomila opcionih koji se mogu slati
$DoExpressCheckoutPaymentRequestDetails->setPaymentDetails($PaymentDetails);
$DoExpressCheckoutPaymentRequestDetails->setPayerID($_POST['payerid'], 'iso-8859-1');
$DoExpressCheckoutPaymentRequestDetails->setToken($_POST['token'], 'iso-8859-1');
$DoExpressCheckoutPaymentRequestDetails->setPaymentAction('Sale', 'iso-8859-1');
$DoExpressCheckoutPayment =& Services_PayPal::getType('DoExpressCheckoutPaymentRequestType');
if (Services_PayPal::isError($DoExpressCheckoutPayment)) {
var_dump($DoExpressCheckoutPayment);
exit;
}
$DoExpressCheckoutPayment->setDoExpressCheckoutPaymentRequestDetails($DoExpressCheckoutPaymentRequestDetails);
// izvrsavanje transakcije
$result = $caller->DoExpressCheckoutPayment($DoExpressCheckoutPayment);
if (Services_PayPal::isError($result)) {
var_dump($result);
}
else
{
// debug version
//echo "<pre>"; print_r($result); echo "</pre>";
//echo "<pre>"; print_r($_SESSION); echo "</pre>";
// transaction has been made; Let's collect all data and present it to the customer.
// sakupljamo podatke potrebne kako za mene samog (za bazu i ostalo), tako i za korsnika, da potvrdimo transakciju
$ack = $result->getAck();
$transid = $result->DoExpressCheckoutPaymentResponseDetails->PaymentInfo->getTransactionID();
$transtype = $result->DoExpressCheckoutPaymentResponseDetails->PaymentInfo->getTransactionType();
$paymenttype = $result->DoExpressCheckoutPaymentResponseDetails->PaymentInfo->getPaymentType();
$paymentdate = $result->DoExpressCheckoutPaymentResponseDetails->PaymentInfo->getPaymentDate();
$status = $result->DoExpressCheckoutPaymentResponseDetails->PaymentInfo->getPaymentStatus();
$reason = $result->DoExpressCheckoutPaymentResponseDetails->PaymentInfo->getPendingReason();
// check if we got error!
// Ovde slede nekoliko mogucih gresaka i odgovarajuca poruka uz iste
if($ack == "Failure")
{
// collect error number from PayPal and match it in database
$errornr = $result->Errors->getErrorCode();
$sql = new db();
$sql->db_Select("paypal_error_codes","*","WHERE errorcode = $errornr",'');
$geterror = $sql->db_Fetch();
// present it in nice table
$error_table = "
<table>
<tr>
<td><center><b>Error!</b></center></td>
</tr>
<tr>
<td>".nl2br($geterror['comment'])."</td>
</tr>
<tr>
<td><a href = 'signup.php'>Sign up again</a></td>
</tr>
</table>";
echo $error_table;
require_once(FOOTERF);
exit;
}
// check status;
// possible values: completed or pending
if($status == "Completed")
{
$status_message = "Your purchase has been successfuly received by PayPal.";
}
if($status == "Pending")
{
// all standard pending message
$status_message = "Your purchase has been sent to PayPal. However, it could not been proccessed immediately
and is now in pending status.<br>";
// scope through pending status and prepare matching information for customer
switch ($_POST['reason'])
{
case "none":
$status_message .= "PayPal did not send any additional information about the pending reason.<br>
As soon as purchase has been proccessed you shall be informed by PayPal and by Nekimojdomen at your email address.";
break;
case "echeck":
$status_message .= "Your payment has been made through eCheck. PayPal needs some time to clear this transactio.
As soon as this has been done, you will receive information by e-mail from Nekimojdomen with your username and password.";
break;
case "other":
$status_message .= "PayPal did not provide any pending reason. If you belive that transaction should be
immediate, you can contact PayPal customer services to clarify pending status. When and if transaction gets proccessed
by PayPal, you shall be immediately notifed.";
break;
}
}
// start creating nice output for the customer
$order_confirmed = "
<table>
<tr>
<td colspan = 2><center><b>Puchase completed</b></center></td>
</tr>
<tr>
<td colspan = 2><br></td>
</tr>
<td colspan = 2>This is the confirmation of your purchase</td>
</tr>
<tr>
<td colspan = 2><br></td>
</tr>
<tr>
<td>Status</td>
<td>$status</td>
</tr>
<tr>
<td colspan = 2>$status_message</td>
</tr>
<tr>
<td colspan = 2><br></td>
</tr>
<tr>
<td>Ordering date</td>
<td>$paymentdate</td>
</tr>
<tr>
<td>Charged ammount</td>
<td>".$_SESSION['signup']['price']."</td>
</tr>
<tr>
<td colspan = 2><br></td>
</tr>
<tr>
<td colspan = 2>You will be receiving shortly your log in information per e-mail</td>
</tr>
<tr>
<td colspan = 2><br></td>
</tr>
<tr>
<td colspan = 2><center><i>Thank you for puchasing Nekimojdomen product!</i></center></td>
</tr>
</table>";
echo $order_confirmed;
// let's store some data into database, so that we can match when payment has been received
$sql2 = new db();
$preorder = $sql2->db_Insert("paypal_orders","'$transid','$transtype','".$_SESSION['signup']['first_name']."','".$_SESSION['signup']['last_name']."','".$_SESSION['signup']['payer_email']."','".$_SESSION['signup']['payer_id']."','
[email protected]','".$_SESSION['signup']['product']."','$paymentdate','','1'");
mail("
[email protected]","Nekimojdomen.com -- order confirmation","You just order something... thanx :)");
//echo "<br><br>".$_SESSION['signup']['first_name']."','".$_SESSION['signup']['last_name']."','".$_SESSION['signup']['payer_email']."','".$_SESSION['signup']['payer_id']."','$paypalmail','".$_SESSION['signup']['package']."','".$_SESSION['signup']['payer_id']."','$paymentdate','','1'";
}
session_destroy();
require_once(FOOTERF);
?>
Ovo je poslednje sto korisnik vidi. Ovde mu se prikazuje poruka koju PayPal salje meni, a ja istu (uz manje izmene, jezicke) pruzam korisniku.
Ukoliko je transakcija ok prosla, poslednji korak jeste da PayPal to potvrdi, a to se odradjuje preko IPN (Instant Payment Notification). Naime, PayPal poziva unapred definisani url (koji stoji u mom PayPal nalogu).
autoprocesspayment.php
(komentari u kodu)
Code:
<?php
require_once("../class2.php");
// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-validate';
foreach ($_POST as $key => $value)
{
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}
// post back to PayPal system to validate
$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen ('www.sandbox.paypal.com', 80, $errno, $errstr, 30);
// assign posted variables to local variables
$item_name = $_POST['item_name'];
$item_number = $_POST['item_number'];
$payment_status = $_POST['payment_status'];
$payment_amount = $_POST['mc_gross'];
$payment_currency = $_POST['mc_currency'];
$txn_id = $_POST['txn_id'];
$txn_type = $_POST['txn_type'];
$custom = $_POST['custom'];
$receiver_email = $_POST['receiver_email'];
$payer_email = $_POST['payer_email'];
$payer_first_name = $_POST['first_name'];
$payer_last_name = $_POST['last_name'];
if (!$fp)
{
// HTTP error occured, we shall not log this one, but rather send e-mail. If neccessary, manual log can be done later
$subject = "IPN Failed: connection to paypal not established";
$body = "$txn_id; $txn_type; $custom; $receiver_email; $payer_email; $payment_status; $payment_amount.";
mail("
[email protected]", $subject, $body);
// let's update status of transaction
$sql = new db();
$put = $sql->db_Update("paypal_orders","status = 6 where txn_id = $txn_id");
exit;
}
else
{
// let's log all data first, preparing nicely layout to store files
$date = date("Y-m-d");
$data = "
Received on: $date<br><br>
Transaction ID: $txn_id ($txn_type)<br>
Item purchased: $item_name<br>
Payment status: $payment_status<br>
Payment ammount: $payment_amount $payment_currency<br>
Custom message: $custom<br><br>
Receiver e-mail: $receiver_email<br>
Payer e-mail: $payer_email";
// obozavam logging, te _SVE_ logujem :)
$handle = fopen("/path/to/log/ipn-all.$txn_id","w+");
fwrite($handle, $data);
fputs ($fp, $header . $req);
while (!feof($fp))
{
$res = fgets ($fp, 1024);
if (strcmp ($res, "VERIFIED") == 0)
{
// get data from database, as we will need it
// comparison is Transaction id, so if does not exist, something is wrong!
$sql = new db();
$gettrans = $sql->db_Count("paypal_orders","(txn_id)","where txn_id = '$txn_id'");
if($gettrans <= 0)
{
// no records found in DB! something is not OK!
echo "no records";
exit;
}
// check that receiver_email is your Primary PayPal email
if($receiver_email != "
[email protected]")
{
echo "receiver mail is not correct";
exit;
}
// Status is OK, let's make things
if($payment_status == "Completed")
{
do your stuff here, like create accounts, start billing etc...
exit;
}
if($payment_status == "Denied")
{
echo "payment denied, see paypal 4 more info";
exit;
}
if($payment_status == "Expired")
{
echo "transactin expired, try again";
exit;
}
}
else if (strcmp ($res, "INVALID") == 0)
{
// log for manual investigation
make some logs here
echo "payment proccess call went wrong...";
exit;
}
}
fclose ($fp);
}
?>
Ovaj poslednji fajl hvata sta PayPal kaze o transakciji. Naime, prethodni fajl je poslao zahtev PayPal-u da odradi transakciju, a ovaj sakuplja podatke o transakciji.
Elem, sve ovo gore je sa mog pre-production servera, te nemojte obracati paznju na komentare i slicno :) Ako ima pitanja - tu sam ;)
Poz,
Sale