quinta-feira, 22 de setembro de 2011

Como configurar o retorno automático do PagSeguro em dois ou mais sites

Se você chegou à essa página através de algum motor de busca deve estar a procura de uma solução para um problema comum, com a versão 1 da API do PagSeguro.

Nessa API somente podemos ter configurado uma url de retorno do PagSeguro. Basicamente funciona bem, mas se tivermos dois sistemas distintos que efetuam as operações em bancos de dados diferentes, teremos um problema.

Para resolver essa solução temos que utilizar um critério de diferenciação de cada um dos sites. Acho interessante utilizar o campo “VendedorEmail”, você pode ter diversos e-mails cadastrados no PagSeguro, ao enviar o cliente via POST para a página de pagamento do PagSeguro, você envia o email do vendedor, no campo “email”.

Inicialmente achei que estava incorreto e acabei fazendo a diferença pela Referência, já que a referência era sempre o número do pedido, coloquei um “c_” para um site e assim por diante, no início da referência. E funciona bem.

Com PHP podemos fazer um redirecionamento temporário que reenvia os dados via POST, mas utilizar essa opção me fez perder muito tempo. Acontece que utilizando a biblioteca curl do PHP (que o PagSeguro utiliza para enviar o POST para a url de retorno) por algum motivo esse redirecionamento temporário não acontece, logo não funciona.

Então ao invés de fazer um redirecionamento temporário, utilizo curl para enviar os dados à página correta. Para exemplificar:

if (count($_POST) > 0) {
    if (strpos($_POST['Referencia'], 'c_') !== false) {
        $url = "http://www.site1.com.br/retorno_pagseguro.php";
    } else {
        $url = "http://www.site2.com.br/pagseguro/PagSeguroRetorno.php";
    }
    $ch = curl_init();
   
    $fields_string = '';
    $count = 0;
    foreach ($_POST as $key=>$item) {
        if ($count > 0)
            $fields_string .= '&';
        $fields_string .= $key . '=' . $item;
        $count++;
    }
    curl_setopt($ch,CURLOPT_URL,$url);
    curl_setopt($ch,CURLOPT_POST, count($_POST));
    curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string);

    $result = curl_exec($ch);

    curl_close($ch);
   
} else {
    header("Location: http://www.site.com.br/mensagem-de-conclusao");
}
?>

Esse é o código que nos interessa, como expliquei acima, prefixei a referência com “c_”, então verifico se existe essa string no campo Referencia, utilizando a função strpos que retorna false, caso o segundo parâmetro string não esteja dentro do primeiro parâmetro string. Então se ele estiver eu defino que a url a ser enviado o POST é a url do primeiro sistema (a ordem não importa), podem ser informadas quantas páginas forem necessários, quantos sistemas você necessitar utilizar na mesma conta.

A última url é a url a qual o usuário será redirecionado quando voltar ao site, essa página deve ser única para todos os sistemas, pois nenhum dado de GET ou POST é enviado.

Com curl enviamos o POST, percorro o array $_POST para formatar a string que é necessária para definir o cabeçalho de envio e por fim chamo a função curl_exec que irá enviar o POST.

Dessa forma, você pode adaptar sua lógica com qualquer sistema.

Se tiver dúvidas ou precisar de ajuda para algum problema específico só enviar a dúvida nos comentários.

8 comentários:

Anônimo disse...

Olá, estou com o mesmo problema em ASP clássico, pode ajudar? Grato

Gabriel disse...

No ASP Clássico você irá utilizar o Objeto MSXML2 para substituir o cUrl.

Aqui está um exemplo que eu extraí de: http://objectmix.com/xml-soap/87408-sending-post-variables-using-msxml2-serverxmlhttp-3-0-a.html


Set objXMLDOC = Server.CreateObject("Msxml2.ServerXMLHTTP.3.0")

'SET CALL TIMEOUTS
lResolve = 8 * 1000 'Timeout values are in milli-seconds
lConnect = 8 * 1000
lSend = 10 * 1000
lReceive = 10 * 1000
objXMLDOC.setTimeouts lResolve, lConnect, lSend, lReceive

'MAKE THE CALL
objXMLDOC.open "POST", "http://localhost/test3.asp", False
objXMLDOC.setRequestHeader "Content-Type", "text/xml"
''objXMLDOC.setRequestHeader "Authorization", "Basic " & UserPass
objXMLDOC.setRequestHeader "action", "updateMediaData"
DataToSend = "test=booyah"
objXMLDoc.send(DataToSend)

Só é preciso adaptá-lo. Se precisar de algo é só dizer. Até mais.

Anônimo disse...

Olá

tenho 2 lojas virtual e preciso configurar o retorno de uma mesma conta do pagseguro para ambas.

è possivel?

Gabriel disse...

Olá Anônimo,

É possível sim, é justamente o que o texto do POST explica. Só que não existe uma configuração no próprio PagSeguro. Apesar de que, a nova versão da API já ajuda nesse sentido.

A página de pagamento dentro do PagSeguro será sempre igual com os mesmos dados, mas você pode usar a página de retorno e as referências geradas para tratar o retorno nas duas lojas.

Qualquer dúvida, estou a disposição.

Anônimo disse...

Gabriel, como faço para verificar os dados no website com url diferente do site que consta no pagseguro.. quando ele recebe os posts e tenta validar no pagseguro, o pagseguro não verifica.

Gabriel disse...

Olá Anonimo,

Eu acredito que o PagSeguro não consiga mesmo verificar de uma url diferente, mas não tenho certeza.

Mas de forma mais prática, você poderia utilizar só a página principal que recebe o retorno do PagSeguro para verificar com o PagSeguro, e na chamada à outra página você poderia fazer outra verificação, como enviando uma senha por POST que só as duas páginas saibam e então se esse valor estiver correto faz o processo de liberação.

Se tiver qualquer dúvida, é só entrar em contato. Até mais.

Anônimo disse...

Pois é.. tentei mil maneiras mas não consegui direito.. mas liguei pro pagseguro e criaram uma segunda conta pra mim por lá.. então vou fazer assim.. acho até um pouco melhor, pois fica mais fácil de saber a lucratividade de cada loja em separado.. obrigado gabriel.. ótimo blog.

Gabriel disse...

Olá, eu que agradeço a visita. Qualquer dúvida, estamos aí.