Uma das grandes vantagens do uso do Express Checkout como solução de pagamento para o comerciante é o aumento das taxas de conversão. Com ele, o cliente não precisa inserir informações pessoais na aplicação, o checkout é muito simples, amplamente aceito e mantém o cliente dentro da loja após a finalização da compra. Já para o desenvolvedor, a grande vantagem está justamente na facilidade de integração, que pode ser feita em 4 passos simples:
- Adição do botão de checkout na tela de pagamento.
- Adição do comportamento (click) no botão para integrar com o PayPal utilizando a operação da API do Express Checkout.
- Na tela de finalização, utilize a operação da API do Express Checkout para recuperar o endereço de entrega e aceitar o pagamento.
- Testes no sandbox.
Vamos começar este artigo com a adição do botão. Para isso, iremos até Express Checkout – Button Code para gerar a imagem.
<img src="https://www.paypal.com.br/pt_BR/i/btn/btn_xpressCheckout.gif" align="left" style="margin-right:7px;">
Isso gerará a seguinte imagem (percebam o pt_BR para localização do texto do botão):

Com a imagem gerada, criamos um formulário HTML, no qual adicionaremos o comportamento ao botão:
<html>
<head>
<title>Express Checkout</title>
<style type="text/css">
#ec-button {
cursor: pointer;
margin-right: 7px;
}
</style>
</head>
<body>
<form id="checkout" action="checkout.php" method="post">
<span>Total </span><span>RINSERT:CONTENT:ENDnbsp;100.00</span><br />
<img id="ec-button" src="https://www.paypal.com.br/pt_BR/i/btn/btn_xpressCheckout.gif" onclick="checkout.submit();" />
</form>
</body>
</html>
Esse formulário fará uma postagem ao checkout.php, que, por sua vez, é bastante simples:
<?php
$total = 100.00; //Total do carrinho do cliente
$nvp = array(
'PAYMENTREQUEST_0_AMT' => $total,
'PAYMENTREQUEST_0_CURRENCYCODE' => 'BRL',
'PAYMENTREQUEST_0_PAYMENTACTION' => 'Sale',
'RETURNURL' => 'http://127.0.0.1/paypal/retorno.php',
'CANCELURL' => 'http://127.0.0.1/paypal/cancelamento.php',
'METHOD' => 'SetExpressCheckout',
'VERSION' => '64',
'PWD' => 'xxxx',
'USER' => 'login.do.usuario',
'SIGNATURE' => 'assinatura'
);
$curl = curl_init();
curl_setopt( $curl , CURLOPT_URL , 'https://api-3t.sandbox.paypal.com/nvp' );
curl_setopt( $curl , CURLOPT_SSL_VERIFYPEER , false );
curl_setopt( $curl , CURLOPT_RETURNTRANSFER , 1 );
curl_setopt( $curl , CURLOPT_POST , 1 );
curl_setopt( $curl , CURLOPT_POSTFIELDS , http_build_query( $nvp ) );
$response = urldecode( curl_exec( $curl ) );
$responseNvp = array();
curl_close( $curl );
if ( preg_match_all( '/(?<name>[^\=]+)\=(?<value>[^&]+)&?/' , $response , $matches ) ) {
foreach ( $matches[ 'name' ] as $offset => $name ) {
$responseNvp[ $name ] = $matches[ 'value' ][ $offset ];
}
}
if ( isset( $responseNvp[ 'ACK' ] ) && $responseNvp[ 'ACK' ] == 'Success' ) {
$paypalURL = 'https://www.sandbox.paypal.com/cgi-bin/webscr';
$query = array(
'cmd' => '_express-checkout',
'token' => $responseNvp[ 'TOKEN' ]
);
header( 'Location: ' . $paypalURL . '?' . http_build_query( $query ) );
} else {
echo 'Falha na transação';
}
Um ponto que pode ser notado no código acima é que podemos utilizar, na URL de retorno e de cancelamento, durante os testes no sandbox, como nossa URL local http://127.0.0.1. Isso torna mais práticos nossos testes agiliza o desenvolvimento. Após a requisição ao checkout.php ser concluída, o cliente é direcionado ao ambiente seguro do PayPal para fazer login, confirmar os dados da transação e, logo após a confirmação de todos os dados, o usuário é redirecionado à URL de retorno definida no campo RETURNURL da requisição. Na URL de retorno, o PayPal enviará um token de identificação da transação; com essa informação, conseguiremos fazer uma nova chamada à operação da API PayPal para verificar o sucesso da operação e recuperar os dados do cliente:
<?php
if ( isset( $_GET[ 'token' ] ) ) {
$token = $_GET[ 'token' ];
$nvp = array(
'TOKEN' => $token,
'METHOD' => 'GetExpressCheckoutDetails',
'VERSION' => '64',
'PWD' => 'xxxx',
'USER' => 'login.do.usuario',
'SIGNATURE' => 'ASSINATURA'
);
$curl = curl_init();
curl_setopt( $curl , CURLOPT_URL , 'https://api-3t.sandbox.paypal.com/nvp' );
curl_setopt( $curl , CURLOPT_SSL_VERIFYPEER , false );
curl_setopt( $curl , CURLOPT_RETURNTRANSFER , 1 );
curl_setopt( $curl , CURLOPT_POST , 1 );
curl_setopt( $curl , CURLOPT_POSTFIELDS , http_build_query( $nvp ) );
$response = urldecode( curl_exec( $curl ) );
$responseNvp = array();
curl_close( $curl );
if ( preg_match_all( '/(?<name>[^\=]+)\=(?<value>[^&]+)&?/' , $response , $matches ) ) {
foreach ( $matches[ 'name' ] as $offset => $name ) {
$responseNvp[ $name ] = $matches[ 'value' ][ $offset ];
}
}
if ( isset( $responseNvp[ 'TOKEN' ] ) && isset( $responseNvp[ 'ACK' ] ) ) {
if ( $responseNvp[ 'TOKEN' ] == $token && $responseNvp[ 'ACK' ] == 'Success' ) {
echo '<pre>';
print_r( $responseNvp );
echo '</pre>';
} else {
echo 'Nãoo foi possível concluir a transação';
}
} else {
echo 'Não foi possível concluir a transação';
}
}
Isso nos dará uma matriz com um conteúdo semelhante ao seguinte:
Array
(
..
[EMAIL] => email.do.cliente@dominio.com
[PAYERID] => X0X0X0XXXX0XX
[PAYERSTATUS] => verified
[FIRSTNAME] => Usuário
[LASTNAME] => teste
[COUNTRYCODE] => BR
[SHIPTONAME] => Usuário de teste
[SHIPTOSTREET] => Endereço
[SHIPTOCITY] => Cidade do usuário
[SHIPTOSTATE] => SP
[SHIPTOZIP] => 123456789
[SHIPTOCOUNTRYCODE] => BR
[SHIPTOCOUNTRYNAME] => Brasil
[ADDRESSSTATUS] => Confirmed
[CURRENCYCODE] => BRL
[AMT] => 100.00
...
)
Com as informações retornadas pela operação GetExpressCheckoutDetails, podemos concluir a transação fazendo apenas um ajuste no código da página de retorno:
<?php
if ( isset( $_GET[ 'token' ] ) ) {
$token = $_GET[ 'token' ];
$nvp = array(
'TOKEN' => $token,
'METHOD' => 'GetExpressCheckoutDetails',
'VERSION' => '64',
'PWD' => 'xxxx',
'USER' => 'login.do.usuario',
'SIGNATURE' => 'ASSINATURA'
);
$curl = curl_init();
curl_setopt( $curl , CURLOPT_URL , 'https://api-3t.sandbox.paypal.com/nvp' );
curl_setopt( $curl , CURLOPT_SSL_VERIFYPEER , false );
curl_setopt( $curl , CURLOPT_RETURNTRANSFER , 1 );
curl_setopt( $curl , CURLOPT_POST , 1 );
curl_setopt( $curl , CURLOPT_POSTFIELDS , http_build_query( $nvp ) );
$response = urldecode( curl_exec( $curl ) );
$responseNvp = array();
if ( preg_match_all( '/(?<name>[^\=]+)\=(?<value>[^&]+)&?/' , $response , $matches ) ) {
foreach ( $matches[ 'name' ] as $offset => $name ) {
$responseNvp[ $name ] = $matches[ 'value' ][ $offset ];
}
}
if ( isset( $responseNvp[ 'TOKEN' ] ) && isset( $responseNvp[ 'ACK' ] ) ) {
if ( $responseNvp[ 'TOKEN' ] == $token && $responseNvp[ 'ACK' ] == 'Success' ) {
$nvp[ 'PAYERID' ] = $responseNvp[ 'PAYERID' ];
$nvp[ 'PAYMENTREQUEST_0_AMT' ] = $responseNvp[ 'PAYMENTREQUEST_0_AMT' ];
$nvp[ 'PAYMENTREQUEST_0_CURRENCYCODE' ] = $responseNvp[ 'PAYMENTREQUEST_0_CURRENCYCODE' ];
$nvp[ 'METHOD' ] = 'DoExpressCheckoutPayment';
$nvp[ 'PAYMENTREQUEST_0_PAYMENTACTION' ] = 'Sale';
curl_setopt( $curl , CURLOPT_POSTFIELDS , http_build_query( $nvp ) );
$response = urldecode( curl_exec( $curl ) );
$responseNvp = array();
if ( preg_match_all( '/(?<name>[^\=]+)\=(?<value>[^&]+)&?/' , $response , $matches ) ) {
foreach ( $matches[ 'name' ] as $offset => $name ) {
$responseNvp[ $name ] = $matches[ 'value' ][ $offset ];
}
}
if ( $responseNvp[ 'PAYMENTINFO_0_PAYMENTSTATUS' ] == 'Completed' ) {
echo 'Parabéns, sua compra foi concluída com sucesso';
} else {
echo 'Não foi possível concluir a transação';
}
} else {
echo 'Não foi possível concluir a transação';
}
} else {
echo 'Não foi possível concluir a transação';
}
curl_close( $curl );
}
Como podemos ver, Express Checkout é vantajoso:
- Para nós, como desenvolvedores, pois é muito simples de implementar.
- Para nossos clientes, pois aumenta a taxa de conversão e é mundialmente aceito.
- Para os clientes de nossos clientes, pois oferece um ambiente seguro, simples e confiável no qual o usuário não precisará informar seus dados pessoais diretamente na loja.
O código utilizado neste artigo poderá ser encontrado na íntegra em Code Sample e, caso encontrem alguma dificuldade na implementação, o Fórum do PayPal X Brasil possui uma categoria dedicada ao Express Checkout. No nosso próximo artigo, demonstraremos como integrar o Express Checkout em uma aplicação mobile e disponibilizaremos uma aplicação de exemplo. Então, até lá.



