Integrando PagSeguro com Django

Nesse artigo mostrarei de uma maneira rápida e resumida como integrar o meio de pagamento PagSeguro à uma loja virtual com carrinho próprio. O código é simples e pode ser adaptado para o uso com outros serviços de pagamento como por exemplo o Pagamento Digital.

INTRODUÇÃO

O funcionamento da integração com o PagSeguro é simples:

  1. Preenchimento do form com dados do pedido:
    Uma view do site renderiza um template contendo um form com campos ocultos (input type=”hidden”) preenchidos com dados sobre o pedido.
  2. Envio dos dados à URL do pagseguro:
    O form é submetido via POST para a URL do PagSeguro que recebe os dados do pedido e exibe a tela de escolha da forma de pagamento.
  3. Envio dos dados sobre a transação:
    Após o comprador escolher a forma de pagamento, o robô do PagSeguro envia em segundo plano um POST para a URL de retorno configurada pelo vendedor no site do PagSeguro. Em seguida redireciona o comprador para essa mesma URL de retorno.

A parte mais complicada é no passo 3, onde ocorre a comunicação em segundo plano (invisível ao usuário, não aparece no browser).
O robô do PagSeguro envia um POST para a URL de retorno definida pelo vendedor. Então é preciso verificar nessa URL se houve alguma requisição via POST. Então o método da view envia uma requisição ao PagSeguro, também em segundo plano, contendo os mesmos dados obtidos via POST e um código único (token) definido no painel de configuração da conta no site do PagSeguro. Após verificado a autenticidade da transação, os dados são armazenados no banco de dados para que o cliente possa acompanhar o status do pedido diretamente no seu site.

MÃO NA MASSA

Não será abordado quais campos e tipos de dados que devem ser enviados ao PagSeguro. Essas informações estão bem documentadas no site do mesmo.
No momento apenas será descrito como verificar a autenticidade da transação.

Vamos criar uma app chamada utils. Dentro do diretório dessa app, criamos o arquivo pagamentolib.py.

$ python manage.py startapp utils
$ vim utils/pagamentolib.py

Eis o código do pagamentolib.py:

# -*- coding: utf-8 -*-
 
import sys
import urllib2, urllib
from django.http import HttpResponse
 
 
class Pagamento(object):
 
    def _conectar(self, url, params):
        query_str = urllib.urlencode(params)
        req = urllib2.Request(url, query_str)
        f = urllib2.urlopen(req)
        conteudo = f.read()
        f.close()
        return conteudo
 
    def _enviar(self, url, params):
        retorno = self._conectar(url, params)
        if retorno.lower() == 'verificado':
            return True
        else:
            return False
 
 
class PagSeguro(Pagamento):
    def processar(self, token, params, url='https://pagseguro.uol.com.br/Security/NPI/Default.aspx'):
        if not params:
            return False
        else:
            lista = []
            for key in params.keys():
                lista.append((key,params[key]))
            lista.append(('Comando', 'validar'))
            lista.append(('Token', token))
 
            return self._enviar(url, lista)

Como exemplo, nossa URL de retorno é http://www.seusite.com/concluir/, que chama o método concluir contido na app carrinho

# -*- coding: utf-8 -*-
 
from django.views.generic.simple import direct_to_template
from meuprojeto.utils.pagamentolib import PagSeguro
 
def concluir(request):
    """
    Descricao:
    Armazena os dados do pedido e exibe a tela de pedido concluido.
    Verifica se o robo do PagSeguro enviou os dados do pedido via POST, e
    então armazena no banco de dados.
    Por fim, exibe a tela de pedido concluido com sucesso.
    """
 
    if request.method == 'POST':
        # token gerado no painel de controle do PagSeguro
        token = '12345699CA2AAAF4599EA697BB2F7FFF'
        p = PagSeguro()
        retorno = p.processar(token, request.POST)
 
        if retorno == True:
            try:
                # Cadastra os dados recebidos no banco de dados.
                # Utilize o request.POST.get('nomedocampo') para obter os valores
            except:
                pass
            return HttpResponse('Ok')
        else:
            return HttpResponse('Error')
 
    else:
        # Carrega tela contendo a mensagem de compra realizada
        return direct_to_template(request,'carrinho/concluir.html')

SERVIDOR DE TESTE

No site da Visie (empresa parceira do PagSeguro) está disponível para download uma aplicação feita em python que simula o servidor do PagSeguro. Com esse servidor de testes é possível verificar se a integração está enviando e recebendo os dados corretamente. É um servidor semelhante ao que acompanha o Django.

  1. Faça o download em: http://visie.com.br/pagseguro/pagseguro_testserver_v0.21.zip e Descompacte em qualquer diretório.
  2. Entre no diretório pagseguroMockup, edite o arquivo settings.py e altere o valor da variável retornourl para sua URL de retorno em ambiente de teste. Altere também dentro do arquivo pagseguro.py na linha 77 onde está ‘ProdId’ por ‘ProdID’.
  3. Insira a linha 127.0.0.1 pagseguro.uol.com.br pagseguro no arquivo /etc/hosts. Agora basta executar o comando sudo python PagSeguroServer.py para iniciar o servidor de testes. Ctrl + C para sair.

CONCLUSÃO

O que foi mostrado nesse artigo também serve com base para comunicação com webservices de outros serviços de pagamento on-line. Eu aconselho a quem estiver pensando em desenvolver um e-commerce que utilize algum serviço desse tipo a não se prender em apenas um. Deixem pré-configurado uma segunda alternativa caso venha a ter problemas com a primeira.
Fiquei decepcionado quando não encontrei exemplos em Python no site do PagSeguro. Na minha opinião, se uma empresa disponibiliza um webservice e ganha sobre isso, deveria investir melhor na documentação e principalmente no suporte.

You can leave a response, or trackback from your own site.

9 Responses to “Integrando PagSeguro com Django”

  1. Chrystiano Araújo says:

    Fala Gustavo…
    Mais uma vez, parabéns pelo post.
    Testarei assim que possível.

    Abraço

  2. Bom Post bem documentado e pratico.

    Parabens.

  3. Ai muito bom o Post, estou começando agora a mexer nessa área e até mesmo para mim foi bem prático.

    Obrigado.

  4. Ghabriel Rodrigues says:

    Fala Gustavo, tudo tranquilo ?

    Brother, tenho tido alguns problemas na implementação da minha view que recebe o post do pagseguro, queria te pedir ajuda, se possível, caso vc possua algum exemplo de uma view implementando uma resposta do pagseguro, q pudesse me encaminhar pro meu email, apenas tratando os dados do post enviado, eu agradeceria muito.

    Mals a encheção de saco ae,

    Um grande abraço, parabens pelo seu ótimo trabalho.

    • gustavohenrique says:

      Infelizmente não tenho mais o código de quando fiz a integração com o pagseguro, e como já tem muito tempo, também não lembro.
      Parece que atualmente o pessoal está tendo problemas com o encoding utilizado pelo pagseguro e o suporte não consegue ajudar (continuam inúteis).
      Lembro ter visto uma discussão recente na lista django-brasil, talvez lá você encontre uma solução.

  5. Guevara says:

    Olá Gustavo!
    Estou tentando implementar o seu tutorial para o meu caso, mas ainda tenho algumas dúvidas.
    A action do form deve ser a url do pagseguro?
    No meu caso, a cobrança é pelo uso do site, então no cadastro do visitante, eu monto três forms na html, cliente, endereço e user, sendo que user não pode ir no post, como poderia resolver isto?
    Não consigo printar os dados na url de retorno, recebo um OK na html mas nada é mostrado, nem usando o django-pagseguro consigo pegar os dados.
    Outro problema é quanto aos campos, o pagseguro usa atributos próprios, então não posso usar forms criados a partir dos models, sou obrigado a usar um form avulso e colocar os names ‘CliNome’, ‘CliEmail’, etc, para que ele me repasse os dados corretos?
    Abraço!

    • gustavohenrique says:

      A action do form deve ser sim a url do pagseguro.
      Esse form deve conter os campos utilizados pelo pagseguro, com os nomes CliNome, CliEmail, etc. Não precisa ser um ModelForm, basta ser um form (nem precisa ser criado com o django, pode ficar estático no html) contendo os dados que voce quer mandar para o pagseguro.

  6. Guevara says:

    Obrigado pela dica Gustavo!
    Criei um form simples na html pra envio dos dados. Porém ao enviar e clicar em “testar retorno automático” sou redirecionado para o “OK” mas não mostra nada sendo recebido via POST do servidor de testes do pagseguro, veja como está o retorno_pagseguro:

    http://dpaste.com/601347/

    Coloquei um print pro nome e telefone pra ver se aparece algo chegando, mas até agora nada. Sabe o que pode ser?
    Abraço!

    • Guevara says:

      Consegui obter os dados do retorno pelo django-pagseguro, é só trabalhar com os signals dele, não precisa criar view e mapear na urls.py. =)
      Abraço!

Leave a Reply

Powered by WordPress | Shop the Best Verizon Wireless Deals. | Thanks to Best CD Rates, Credit Cards and Credit card