Que o PagSeguro é realmente um dos melhores meios de pagamento da web, isso ninguem dúvida. Mas como integra-lo ao seu sistema de e-commerce? O site de ajuda do PagSeguro tenta ser claro e explicativo, mas o fato é, o script disponível no site simplismente não funciona.
Vamos aos erros…
No script PHP do PagSeguro eles usam uma função que se chama, tep_not_null() que não é uma função nativa do PHP, ou seja, o seu script não irá funcionar. Esta função pode ser encontrada no OsCommerce (que não recomendo) ou em outros scripts pela internet. Bola fora, porque este exemplo dado por eles serve justamente para implantar em outros sistemas, ja que os modulos para esses scripts prontos estão disponíveis no proprio site.
Erro apresentado: Fatal error: Call to undefined function tep_not_null() in /teste/pagseguro.php on line 53
… existem outras melhorias que podem ser feitas no script PHP oferecido pelo PagSeguro, não irei comentar, irei implementar mais abaixo, ok?
No script de criação de tabelas MySQL do PagSeguro existe alguns erros básicos e curiosidades tambem. O primeiro é o seguinte, para que existe a tabela PagSeguroTransacoesProdutos sendo que em nenhum dos scripts de linguagem oferecidos por ele existe a inclusão de dados nesta tabela? Com certeza fail. Na outra tabela PagSeguroTransacoes, esta sim é utilizada, mesmo assim com erros gritantes. Como por exemplo, o campo TransacaoID como chave primaria. Porque erro? Porque o PagSeguro faz um post cada vez que é atualizado a transação, desta maneira que esta apenas a primeira inclusão será feita no MySQL, as confirmações de pagamento, cancelamento ou outro status diferente da transação que será postado posteriormente serão ignoradas pelo MySQL pois so pode existir um registro com cada chave primária. Trocando em miudos, você não sabe quem pagou ou não, pois a transanção não será atualizada.
Erro apresentado: #1062 – Duplicate entry ‘TransacaoID’ for key 1
Ta bom ou quer mais? Mais? tem muita coisa, como falta de um campo data para saber quando aconteceu a confirmação, um campo de flag para saber o que você ja atualizou no sistema ou não, etc. Essas implementações eu irei fazer a seguir.
Coloquei o dedo na ferida, e agora? E agora vamos a…
Implementação
Tentei comentar o código de forma simples e sucinta, então qualquer explicação seria chuver no molhado, vamos lá.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
| <?
##############################################################
# CONFIGURAÇÕES
##############################################################
$retorno_site = 'http://www.exemplo.com.br/compra_efedutada.html'; // Site para onde o usuário vai ser redirecionado
$retorno_token = '000000000000000000000000000'; // Token gerado pelo PagSeguro
$retorno_host = 'localhost'; // Local da base de dados MySql
$retorno_database = 'basededados'; // Nome da base de dados MySql
$retorno_usuario = 'usuario'; // Usuario com acesso a base de dados MySql
$retorno_senha = 'senha'; // Senha de acesso a base de dados MySql
###############################################################
# NÃO ALTERE DESTA LINHA PARA BAIXO
################################################################
$lnk = mysql_connect($retorno_host, $retorno_usuario, $retorno_senha) or die ('Nao foi possível conectar ao MySql: ' . mysql_error());
mysql_select_db($retorno_database, $lnk) or die ('Nao foi possível ao banco de dados selecionado no MySql: ' . mysql_error());
// Validando dados no PagSeguro
$PagSeguro = 'Comando=validar';
$PagSeguro .= '&Token=' . $retorno_token;
$Cabecalho = "Retorno PagSeguro";
foreach ($_POST as $key => $value)
{
$value = urlencode(stripslashes($value));
$PagSeguro .= "&$key=$value";
}
if (function_exists('curl_exec'))
{
$curl = true;
}
elseif ( (PHP_VERSION >= 4.3) && ($fp = @fsockopen ('ssl://pagseguro.uol.com.br', 443, $errno, $errstr, 30)) )
{
$fsocket = true;
}
elseif ($fp = @fsockopen('pagseguro.uol.com.br', 80, $errno, $errstr, 30))
{
$fsocket = true;
}
if ($curl == true)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://pagseguro.uol.com.br/Security/NPI/Default.aspx');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $PagSeguro);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_URL, 'https://pagseguro.uol.com.br/Security/NPI/Default.aspx');
$resp = curl_exec($ch);
curl_close($ch);
$confirma = (strcmp ($resp, "VERIFICADO") == 0);
}
elseif ($fsocket == true)
{
$Cabecalho = "POST /Security/NPI/Default.aspx HTTP/1.0\r\n";
$Cabecalho .= "Content-Type: application/x-www-form-urlencoded\r\n";
$Cabecalho .= "Content-Length: " . strlen($PagSeguro) . "\r\n\r\n";
if ($fp || $errno>0)
{
fputs ($fp, $Cabecalho . $PagSeguro);
$confirma = false;
$resp = '';
while (!feof($fp))
{
$res = @fgets ($fp, 1024);
$resp .= $res;
if (strcmp ($res, "VERIFICADO") == 0)
{
$confirma=true;
break;
}
}
fclose ($fp);
}
else
{
echo "$errstr ($errno)<br />\n";
}
}
if ($confirma) {
// Recebendo Dados
$TransacaoID = $_POST['TransacaoID'];
$VendedorEmail = $_POST['VendedorEmail'];
$Referencia = $_POST['Referencia'];
$TipoFrete = $_POST['TipoFrete'];
$ValorFrete = $_POST['ValorFrete'];
$Extras = $_POST['Extras'];
$Anotacao = $_POST['Anotacao'];
$TipoPagamento = $_POST['TipoPagamento'];
$StatusTransacao = $_POST['StatusTransacao'];
$CliNome = $_POST['CliNome'];
$CliEmail = $_POST['CliEmail'];
$CliEndereco = $_POST['CliEndereco'];
$CliNumero = $_POST['CliNumero'];
$CliComplemento = $_POST['CliComplemento'];
$CliBairro = $_POST['CliBairro'];
$CliCidade = $_POST['CliCidade'];
$CliEstado = $_POST['CliEstado'];
$CliCEP = $_POST['CliCEP'];
$CliTelefone = $_POST['CliTelefone'];
$NumItens = $_POST['NumItens'];
// Gravando Dados
mysql_query("INSERT into PagSeguroTransacoes SET
TransacaoID='$TransacaoID',
VendedorEmail='$VendedorEmail',
Referencia='$Referencia',
TipoFrete='$TipoFrete',
ValorFrete='$ValorFrete',
Extras='$Extras',
Anotacao='$Anotacao',
TipoPagamento='$TipoPagamento',
StatusTransacao='$StatusTransacao',
CliNome='$CliNome',
CliEmail='$CliEmail',
CliEndereco='$CliEndereco',
CliNumero='$CliNumero',
CliComplemento='$CliComplemento',
CliBairro='$CliBairro',
CliCidade='$CliCidade',
CliEstado='$CliEstado',
CliCEP='$CliCEP',
CliTelefone='$CliTelefone',
NumItens='$NumItens',
Data=now();");
}
Header("Location: $retorno_site"); exit();
?> |
Basicamente, ele se conecta no MySQL, depois checa através do CURL se foi realmente o PagSeguro que enviou a postagem, recebe os dados via post e grava os dados na tabela.
… mas que tabela? Ahh sim… vamos a criação da tabela do MySQL.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| CREATE TABLE `PagSeguroTransacoes` (
`TransacaoID` varchar(36) NOT NULL,
`VendedorEmail` varchar(200) NOT NULL,
`Referencia` varchar(200) default NULL,
`TipoFrete` char(2) default NULL,
`ValorFrete` decimal(10,2) default NULL,
`Extras` decimal(10,2) default NULL,
`Anotacao` text,
`TipoPagamento` varchar(50) NOT NULL,
`StatusTransacao` varchar(50) NOT NULL,
`CliNome` varchar(200) NOT NULL,
`CliEmail` varchar(200) NOT NULL,
`CliEndereco` varchar(200) NOT NULL,
`CliNumero` varchar(10) default NULL,
`CliComplemento` varchar(100) default NULL,
`CliBairro` varchar(100) NOT NULL,
`CliCidade` varchar(100) NOT NULL,
`CliEstado` char(2) NOT NULL,
`CliCEP` varchar(9) NOT NULL,
`CliTelefone` varchar(14) default NULL,
`NumItens` int(11) NOT NULL,
`Data` datetime NOT NULL,
`status` tinyint(1) unsigned NOT NULL default '0',
UNIQUE KEY `TransacaoID` (`TransacaoID`,`StatusTransacao`),
KEY `Referencia` (`Referencia`),
KEY `status` (`status`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1; |
Na tabela acima todos os campos são basicamente os dados recebidos do PagSeguro. Existem mais campos adicionais que vem em POST tambem que não quis colocar, se você tiver conhecimento basta ler o manual do PagSeguro e adicionar os campos.
Os indices que coloquei foram 3. O primeiro de tipo UNIQUE em TransacaoID e StatusTransacao para evitar que um registro seja enviado mais de uma vez, isso pode ocorrer em servidores com conexão lenta, é melhor remediar, pois estamos falando de transações financeiras. Os outros dois são indices de chave (KEY) apenas, para indexar e deixar sua busca pelos registros mais rapidas. O primeiro é na Referencia, campo que você envia ao PagSeguro na hora da compra para vincular o pagamento a ele, seria nossa chave. O segundo é um campo criado por mim, status que nada mais é que uma flag que uso no meu sistema, para saber quando ja usei aquele registro ou não, por padrão, todos os registros inseridos tem status zero.
Legal ter o código aberto no blog, mas eu gosto de facilidade quando busco em outros blogs, por isso a partir de hoje, qualquer código estará disponivel tambem para download.
Faça download do código aqui.
… bem, acho que depois de um longo tempo sem atualizar o blog devido a uma cirurgia de redução de estomago (vou falar sobre isso depois), é uma postagem importante e relevante para os desenvolvedores da área. Espero que tenham gostado.
Have Fun!