ExpressCheckout is used to make secure sales / purchases on the PayPal website and at the end of the purchase the customer returns to the user or company's website.
To understand how PayPal ExpressCheckout works, you have to understand how it works.
Shop - > (SetExpressCheckout) - > Server Responds With Token - > HTTP redirection with & token = - > -> Return URL + TOKEN - > Request (GetExpressCheckoutDetails) - > Answer - > Order (DoExpressCheckoutPayment) - > Success / Failure - > Complete Order
Connecting with the PayPal API.
<?php
class paypal{
//Função de conexão com a API
function api($comando,$param){
$api = 'https://api-3t.sandbox.paypal.com/nvp'; # URL para o modo sandbox
$api_user = urlencode('<API_USUARIO>');
$api_senha = urlencode('<API_SENHA>');
$api_assinatura = urlencode('<API_ASSINATURA>');
$api_versao = urlencode('109.0'); # Esta é a versão da API a ser utilizada
$i = curl_init();
# Definimos uma cabeçalho para a requisição
curl_setopt($i, CURLOPT_URL, $api);
curl_setopt($i, CURLOPT_VERBOSE, 1);
#Desactivar a verificação do servidor e do peer
curl_setopt($i, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($i, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($i, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($i, CURLOPT_POST, 1);
//Passando os parâmetros da API
$nvp = "METHOD=$comando&VERSION=$api_versao&PWD=$api_senha&USER=$api_user&SIGNATURE=$api_assinatura$param";
//Definindo o nvp como campo POST do cURL
curl_setopt($i, CURLOPT_POSTFIELDS, $nvp);
$resposta = curl_exec($i);
curl_close($i);
if(!$resposta){
exit("Erro do $comando ".curl_error($i)."(".curl_errno($i).")");
}
#Aqui transformamos a nossa URL numa array associativa
$respostaP = $this->nvp($resposta);
if(0 == sizeof($respostaP) || !array_key_exists('ACK',$respostaP)){
exit("HTTP resposta inválida do servidor($nvp) para $api");
}
return $respostaP;
}
// função para converter a resposta da cURL em array
function nvp($resposta){
$i = explode('&',$resposta);
$respostaP = array();
foreach($i as $key=>$value){
$d = explode('=',$value);
if(sizeof($d)>1){
$respostaP[$d[0]] = $d[1];
}
}
return $respostaP;
}
}
? >
After defining the connection variables, you can define the methods to be used to start and complete the purchase.
<?php
//Iniciamos a sessão
session_start();
//Incluimos a nossa classe
include_once('paypal.php');
//Se for utilizar o modo live, deixe a variavel $paypalmodo com o ponto(.) apenas
$paypalmodo = '.sandbox';
$moeda = 'USD';
$urlRetorno = 'http://site.com/retorno';
$urlCancela = 'http://site.com/cancela';
//Parte que trata do SetExpressCheckout
if(isset($_POST) && !empty($_POST)){
$itemNome = $_POST['itemNome'];
$itemPreco = $_POST['itemPreco'];
$itemQnt = $_POST['itemQnt'];
$itemTotal = ($itemPreco*$itemQnt);
$taxa = 1.50;
$total = ($itemTotal + $taxa);
$nvpData = '&METHOD=SetExpressCheckout'.
'&RETURNURL='.urlencode($urlRetorno).
'&CANCELURL='.urlencode($urlCancela).
'&PAYMENTREQUEST_0_PAYMENTACTION='.urlencode('Sale').
'&L_PAYMENTREQUEST_0_NAME0='.urlencode($itemNome).
'&L_PAYMENTREQUEST_0_AMT0='.urlencode($itemTotal).
'&L_PAYMENTREQUEST_0_QTY0='.urlencode($itemQnt).
'&NOSHIPPING=0'.
'&PAYMENTREQUEST_0_ITEMAMT='.urlencode($itemTotal).
'&PAYMENTREQUEST_0_TAXAMT='.urlencode($taxa).
'&PAYMENTREQUEST_0_AMT='.urlencode($total).
'&PAYMENTREQUEST_0_CURRENCYCODE='.urlencode($moeda).
'&LOCALECODE=BR'.
'&LOGOIMG='.'http://site.com/logo_a_utilizar_caso_tenha.jpg'.
'&CARTBORDERCOLOR=45D765'.
'&ALLOWNOTE=1';
//Definindo as as variaveis de SESSAO
$_SESSION['itemNome'] = $itemNome;
$_SESSION['itemPreco'] = $itemPreco;
$_SESSION['itemQnt'] = $itemQnt;
$_SESSION['itemTotal'] = $itemTotal;
$_SESSION['taxa'] = $taxa;
$_SESSION['total'] = $total;
//Instanciado a class paypal e chamando a função de conexão api('SetExpressCheckout','paramentros_da_url')
$paypal = new paypal();
$resposta = $paypal->api('SetExpressCheckout',$nvpData);
if('SUCCESS' == strtoupper($resposta['ACK']) || 'SUCCESSWITHWARNING' == strtoupper($resposta['ACK'])){
//Url de redirectionamento com os parâmetros inseridos
$paypalUrl = 'https://www'.$paypalmodo.'.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token='.$resposta["TOKEN"].'';
header('Location:'.$paypalUrl);
} else {
echo '<div style="color:red"><b>Erro : </b>'.urldecode($resposta["L_LONGMESSAGE0"]).'</div>';
}
echo '<pre>';
print_r($resposta);
echo '</pre>';
}
//Parte que trata do DoExpressCheckout
if(isset($_GET['token']) && isset($_GET['PayerID'])){
$token = $_GET['token'];
$payer_id = $_GET['PayerID'];
$itemNome = $_SESSION['itemNome'];
$itemNum = $_SESSION['itemNum'];
$itemQnt = $_SESSION['itemQnt'];
$itemTotal = $_SESSION['itemTotal'];
$taxa = $_SESSION['taxa'];
$total = $_SESSION['total'];
$nvpData = '&TOKEN='.urlencode($token).
'&PAYERID='.urlencode($payer_id).
'&PAYMENTREQUEST_0_PAYMENTACTION='.urlencode("Sale").
'&L_PAYMENTREQUEST_0_NAME0='.urlencode($itemNome).
'&L_PAYMENTREQUEST_0_AMT0='.urlencode($itemPreco).
'&L_PAYMENTREQUEST_0_QTY0='.urlencode($itemQnt).
'&PAYMENTREQUEST_0_ITEMAMT='.urlencode($itemTotal).
'&PAYMENTREQUEST_0_TAXAMT='.urlencode($taxa).
'&PAYMENTREQUEST_0_AMT='.urlencode($total).
'&PAYMENTREQUEST_0_CURRENCYCODE='.urlencode($moeda);
//Instanciando a class paypal e chamando a função api('DoExpressCheckoutPayment','paramentros_da_url')
$paypal = new paypal();
$resposta = $paypal->api('DoExpressCheckoutPayment',$nvpData);
if('SUCCESS' == strtoupper($resposta['ACK']) || 'SUCCESSWITHWARNING' == strtoupper($resposta['ACK'])){
echo "<h2 style='color:green;'>Concluído</h2>";
echo "ID da sua compra: ".$resposta['PAYMENTINFO_0_TRANSACTIONID'];
if('Completed' == $resposta['PAYMENTINFO_0_PAYMENTSTATUS']){
session_destroy();
echo '<div style="color:green">Pagamento completo! Obrigado pela compra.</div>';
} else if('Peding' == $resposta['PAYMENTINFO_0_PAYMENTSTATUS']){
echo '<div style="color:red">Transação completa, mas o pagamento precisa de ser aprovado manualmente na sua <a target="_new" href="http://www.paypal.com">Conta do PayPal</a></div>';
}
//Parte Responsavel por pegar os detalhes da transação
//Esta parte só é exibida se a transação for efectuada com sucesso ou retornar Success
$nvpData = '&TOKEN='.urlencode($token);
$paypal = new paypal();
$resposta = $paypal->api('GetExpressCheckoutDetails',$nvpData);
if('SUCCESS' == strtoupper($resposta['ACK']) || 'SUCCESSWITHWARNING' == strtoupper($resposta['ACK'])){
echo '<br /><b>Coisas para adicionar no banco de dados :</b><br /><pre>';
echo '<pre>';
print_r($resposta);
echo '</pre>';
} else {
echo '<div style="color:red"><b>GetTransactionDetails failed:</b>'.urldecode($resposta["L_LONGMESSAGE0"]).'</div>';
echo '<pre>';
print_r(urldecode($resposta));
echo '</pre>';
}
} else {
//Esta parte é responsavel por verificar o erro caso a chamada api('DoExpressCheckoutPayment','paramentros') falhe.
echo "Erro :".urldecode($resposta['L_LONGMESSAGE0']);
echo "<pre>";
foreach($resposta as $id=>$valor){
echo "<div style='color:red; border:2px solid #ccc;'>[".$id."] => ".urldecode($valor)."<br/></div>";
}
echo "</pre>";
}
}
?>
And finally the page responsible for providing the data about the item by the POST method.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Site.com(LOJA)</title>
<style type="text/css">
body {background-color:#D7D7D7;}
*{font-family: Tahoma, Geneva, sans-serif;}
h1 {text-align:center; color:#333; font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;}
h4 {color:#333; font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;}
table {border:1px solid #666; border-radius:5px 5px 5px 5px; box-shadow:1px 0px 1px #999 inset; background-color:#F2F2F2; margin:0 auto;}
input {border:1px solid #333; border-radius:4px 5px 5px 5px; box-shadow:1px 0px 1px #999 inset; padding:5px; margin-top:2px;}
input:hover {background-color:#FFF; transition:ease-in-out 0.4s; box-shadow:1px 0px 1px #CCC inset;}
</style>
</head>
<body>
<?php
$moeda = 'USD';
?>
<h1>Site.com</h1>
<table border="0" cellpadding="4">
<tr>
<td width="70%"><h4>Bilhetes Platina</h4>(Se vai ao concerto logo a noite, esta é a sua melhor chance de ficar na fila V.I.P)</td>
<td width="30%">
<form method="post" action="checkout.php">
<input type="hidden" name="itemNome" value="Bilhetes Platina" />
<input type="hidden" name="itemPreco" value="20.00" />
Quantidade : <select name="itemQnt"><option value="1">1</option><option value="2">2</option><option value="3">3</option></select>
<input type="submit" value="Comprar (20.00 <?php echo $moeda; ?>)" />
</form>
</td>
</tr>
</table>
</body>
</html>