Latest posts.

Palestra PagSeguro na Impacta

No sábado passado realizei uma palestra na Impacta sobre como implementar uma loja virtual do nada com ajuda do PagSeguro da UOL. Esta palestra já está na terceira versão, eu já a apresentei no PHP-Minas e PHPConference no ano passado. Eu sempre dou um upgrade entre uma apresentação e outra ou corto coisas que não são importantes, mas o conteúdo é basicamente o mesmo.

Foram abordados os temas controle de versão, PDO, Frameworks, motivação, KISS (keep it simple, stupid!) e desenvolvimento ágil.

Eu gosto muito dessa palestra em particular porque demonstra como você pode (e deve) ter sistemas grandes implementados com poucas linhas de código, bastando usar a essência do PHP. Hoje o PHP pode ser considerado uma linguagem bem estável e com grandes recursos que em muitos casos usar um Framework completo é algumas vezes perda de tempo, valendo mais a pena usar a essência da linguagem.

Sala cheia (duas) na palestra sobre PagSeguro na Impacta

Sala cheia (duas) na palestra sobre PagSeguro na Impacta

Também gosto pra caramba de implementar PagSeguro em palestras por ser simples. Em menos de vinte minutos explicativos é possível demonstrar como implementar PagSeguro com direito a retorno automático e dicas de segurança na hora de implementar. É muito satisfatório ver o quanto é rápido, simples e fácil implementar vários meios de pagamento de uma só vez. Com a segurança de “pishing”, fraude, reembolso e muitas outras vantagens que o PagSeguro disponibiliza.

A palestra esteve bem cheia, foram necessárias duas salas e uma conexão de áudio e vídeo para que todos possam ver a palestra. Dentre o pessoal consegui ver o @caferrari – dono do projeto vortice framework, e o @rodrideme – ex-funcionário da Visie e sua namorada @alazanscarol. Muito bom ver esse pessoal.

Enfim a palestra foi ótima e o código-fonte do projeto está no trac para qualquer um estudar. Para ver a palestra, basta vê-la no SlideShare. Espero que tenha mais palestras como esta pois acredite em mim, não é a mesma coisa assistir a palestra e vê-la no SlideShare, é completamente diferente.

PagSimples: faça combranças facilmente com o PagSeguro

Você, assim como eu, já deve ter se deparado com o problema de gerar uma cobrança para alguém através da internet e não queria entrar no painel de controle do PagSeguro e mandar aquele e-mail padrão que eles enviam quando fazem uma cobrança.

Ao invés disso você quer que ele acesse uma url única (bit.ly e tinyurl.com, por exemplo) para que ele possa fazer o pagamento via PagSeguro. Assim você pode fazer o e-mail formatado como você desejar. Talvez você considere essa mesma formula para mandar scraps via Orkut/FaceBook/Twitter/Skype/etc com cobranças ou pagamentos sem que você tenha a necessidade de escrever um formulário nos padrões do PagSeguro.

Mande um e-mail com a sua cobrança de forma simples

Existem inúmeras possibilidades para o PagSimples, use com moderação

Acontece que nem sempre você pode inserir HTML onde você gostaria que as pessoas lhe dessem dinheiro, como um link do youtube. Então faça uma cobrança no PagSimples e mande para quem você quiser.

Veja como é simples: http://pagsimples.dgmike.com.br/p/4b537c4bb8aed

O PagSimples é mais um projeto de uma madrugada (como diria o Marco Gomes) escrito com o Ice-Baby que foi desenvolvido a partir de uma conversa que tive com o Elcio dentro de um taxi.

IcePHP agora é IceBaby

Sei, o projeto está um pouco deixado de lado, mas este ano tem sido muita correria e nos momentos de desespero o CodeIgniter tem sido o meu framework padrão. Acontece que fiz uma busca na internet e encontrei um projeto chamado Internet Communications Engine – ICE, que faz parte da familia ZeroC e suporta PHP. Para não haver confusão, decidi trocar o meu humilde projeto de framework. Agora ele deixa de se chamar Ice e passa a se chamar Ice-Baby, em homenagem a uma música que gosto pra caramba do Vanilla Ice.

Na minha última palestra (PHP Minas) eu apresentei um microframework e ele me serviu de rascunho para o novo Ice-Baby. Talvez mantenha alguma coisa do Banco de dados do antigo Ice, mas provavelmente tudo irá mudar.

Alguns conceitos de MVC devem ser abstraidos quando você for usar o framework já que ele não exige uma estrutura lógica como a maioria dos frameworks por aí. Ao invés de você ter que pensar URL com arquivo, com classe e com método e assim por diante você deve pensar em mapear uma ou mais URLs e direcioná-las para a classe desejada. O método que ele irá usar é o método no qual o usuário chegou na página (get/post). Simples, né?! E os parâmetros, você decide o que é parâmetro também :D Veja um exemplo de código de como sua aplicação pode ficar:

1
2
3
4
5
6
7
8
9
10
<?php
require_once('appropriate/app.php');
 
app(array('^.*$' => 'Welcome'));
 
class Welcome {
  function get() {
    print 'Hello from Bahamas!';
  }
}

Sim! Você consegue escrever uma aplicação com apenas dez linhas de código.

No momento estou me concentrando a escrever a parte do Framework que conversa com o banco de dados (Models e seus resultados). Quem quiser acompanhar o desenvolvimento da ferramenta, pode acompanhar no github, dessa vez vai!

Quem quiser, pode usar outro framework enquanto o Ice-Baby não sai do Beta. Recomendo o Vórtice, Spaghetti e CodeIgniter. Os motivos pelos quais eu escolhi estes frameworks para indicar e não outros? Liberdade! Eu gosto de escrever código da forma que eu quiser sem ter que aprender muito para começar a usar uma ferramenta.

O PagSeguro mudou a URL de retorno automático, e agora?

Nesta sexta-feira, dia 30 de outubro, o PagSeguro mudou a sua homepage e com ela muitas coisas novas aconteceram. Inclusive rolou uma palestra para 70 pessoas do twitter que acompanharam as mudanças do Twitter. A palestra foi ministrada pelo Dennis Ferreira e pela Valéria Santos. Pessoas que tive a oportunidade de conhecer de perto e eles são pessoas responsáveis e estão conscientes das mudanças e do impacto que esta mudança causa.

PagSeguro - Uma empresa UOL

PagSeguro - Uma empresa UOL

Tem bastante gente falando sobre as novidades do novo site do PagSeguro por aí, então se quiser saber o que exatamente, recomendo os slides da palestra e uma busca no oráculo.

Mas, e na parte de códigos? O que muda? Você precisa atualizar seus códigos para essa nova plataforma? A resposta é simples e óbvia: NADA. Sim você não precisa atualizar seu código correndo achando que sua URL mudou. O PagSeguro deixou de ser implementado em ASP e passou a ser implementado em JAVA, o que deixou a aplicação muito mais robusta e segura, com isso a URL do retorno automático mudou. No site do PagSeguro eles indicam uma nova URL para o retorno automático ( https://pagseguro.uol.com.br/pagseguro-ws/checkout/NPI.jhtml ) mas a URL anterior continua funcionando normalmente e continuará por um longo tempo.

O pessoal do PagSeguro fez todas as alterações no seu sistema e antes de por no ar fez uma longa bateria de testes e só foi para o ar após verificar se todas as bibliotecas oficiais continuavam funcionando normalmente. Então, as URL de retorno automático continuará funcionando normalmente. Com o passar do tempo, é óbvio que a URL anterior morra, mas isso acontecerá muito tempo depois, até perceberem que ninguém mais utiliza a URL antiga.

A mudança vai ser longa e sutil, com o tempo iremos alterar todos os scripts para a nova URL, mas você não precisa sair desesperado para trocar suas URLs. O PagSeguro pensou bem nisso quando alterou a url de retorno automático. Eu mesmo fiz testes hoje de tarde para comprovar isso, já que recebi algumas dúvidas de alguns clientes e algumas pessoas reclamaram disso no twitter. Portanto, não se preocupe, você não precisa alterar nada no seu script de retorno automático do PagSeguro.

PDO e classe de resultados

Estava fazendo alguns testes com PDO e SQLite e descobri uma coisa muito interessante sobre o PDO: classe de resultados. O que isso quer dizer, que quando você faz um fetchObject você pode usar sua própria classe com seus próprios métodos.

Atenção! Este post é totalmente NERD e destinado para programadores com algum conhecimento em PHP e banco de dados. Caso este não seja seu perfil aconselho a desistir enquanto é tempo.

Caixa, guarde o que é seu

O código começou mais ou menos assim, eu queria desenvolver um model específico para o ICEPHP, e com o advento do PDO decidi usá-lo como base. Então precisei de alguns definitions: diretório onde se encontra o arquivo (script) e o separador de pastas que em linux é barra e no windows é contra-barra. Também criei duas tabelas no banco de dados, post e categoria:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
define('DS', DIRECTORY_SEPARATOR);
define('ICE_DIR', dirname(__FILE__));
 
$bd = new PDO('sqlite:'.ICE_DIR.DS.'banco.db');
# A conexão do PDO não é linda?!

$bd->query("
    CREATE TABLE IF NOT EXISTS categoria (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        nome VARCHAR(40),
        slug VARCHAR(40)
    );
");
$bd->query("
    CREATE TABLE IF NOT EXISTS post (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        titulo VARCHAR(40),
        slug VARCHAR(40),
        post TEXT,
        data TIMESTAMP
    );
");

Após isso fiz um select no banco de dados e se não me retornasse resultados, inseri um dado no banco de dados:

1
2
3
4
5
6
7
8
9
10
11
12
$c=$bd->query("SELECT COUNT(*) as c FROM post;");
 
if (!$c->fetchObject()->c) {
    $bd->query("
        INSERT INTO post (titulo, slug, post, data) VALUES (
            'Apenas um teste',
            'apenas-um-teste',
            'Este post é apenas um teste do novo Framework: ICEPHP',
            CURRENT_DATE
        );
    ");
}

Com isso eu consigo usar o resultado de forma linda (orientado a objetos):

1
2
3
4
5
$c=$bd->query("SELECT * FROM post;");
$r = $c->fetchObject();
echo $r->titulo;
 
// Isto retorna "Apenas um teste"

Lendo a documentação sobre o fetchObject do PDO vi que é possivel passar como parâmetro uma string com o nome da Classe que você deseja que seja utilizado para o resultado, lembrando que (!), o padrão é o stdClass. Entao passei minha classe resultado como exemplo e o que descobri. Coisas lindas de se fazer. Eis a classe Resultado:

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
class Resultado
{
    var $_data = array();
    var $_updated = false;
 
    function __toString()
    {
        return "O resultado é: ".$this->titulo . ' ('.date('d-m-Y h:i:s', $this->data).")\n";
    }
 
    function __get($k)
    {
        return $this->_data[$k];
    }
 
    function __set($k, $v)
    {
        if (isset($this->_data[$k]) AND $this->_data[$k] != $v) {
            $this->_updated = true;
        }
        $this->_data[$k] = $v;
    }
 
    function salvaPost()
    {
        global $bd;
 
        $sql = "UPDATE post SET ";
        foreach ($this->_data as $k=>$v) {
            if ($k!='id' || $k != 'data') {
              $sql .= "\n  $k = '$v',";
            }
        }
        $sql = substr($sql, 0, -1);
        $sql .= "\n WHERE id = ".$this->id;
 
        $bd->query($sql);
    }
 
    function __destruct()
    {
        if ($this->_updated) {
            $this->salvaPost();
        }
    }
}

Veja, apenas usei um método de verdade, todos os outros usei os métodos mágicos do PHP (__toString, __get, __set, __destruct). Recomendo que leia sobre estes métodos e use-os, eles podem salvar sua vida. Whatever, com essa classe Resultado é possivel fazer o que eu sempre quis fazer, um objeto de resultado de banco de dados que atualiza o banco sem usar o estilo seta parametros e depois salva. Veja como é feito na maioria dos ORMs por aí:

1
2
3
$r=$post->get(1);
$r->titulo = 'Titulo Alterado';
$r->save();

Pense comigo, se você atribuiu um valor, você quer que ele seja salvo, correto? Então não ficaria mais fácil se forsse assim?

1
2
$r=$post->get(1);
$r->titulo = 'Titulo Alterado';

Sim!!! Às vezes você atribui um valor que não deseja salvar, faz isso apenas para configurar os dados e etc, mas pense, quantas vezes você faz isso? Além disso, óbvio que é possivel fazer tudo o que deseja gastando um pouco mais de massa cinzenta, mas a proposta não é essa no momento.

Usando a classe Resultado é possivel fazer o update quase que “on the fly”. Na verdade, para o programador parece que é instantâneo, mas não é. O update se dá no destruct do objeto, normalmente quando o script finaliza, mas pode ser quando damos um novo fetchObject nessa variável. Se ele não for alterado ele, obviamente, não salva as alterações no banco de dados. Veja como fica o exemplo do que estou falando.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$c=$bd->query("SELECT * FROM post;");
# Pegando o objeto e jogando-o na classe de resultados
$r = $c->fetchObject('Resultado');
 
# Imprimindo, devido ao método __toString aparece:
# O resultado é: Apenas um teste (31-12-1969 09:33:29)
print ($r);
 
# Alterando o resultado
$r->titulo = 'Teste';
 
# Imprimindo mais uma vez, aparece
# O resultado é: Teste (31-12-1969 09:33:29)
# mas isto está em 'cache'
print ($r);
 
# Quando o objeto é destruído, ao finalizar o script
# ele faz o update necessário

Testei isso no foreach e também funcionou, então é fazer updates de objetos em escala, mas não exagere, o ideal é fazer isso no sql. Veja como fica com o foreach:

1
2
3
4
5
$c=$bd->query("SELECT * FROM post;");
 
while ($x = $c->fetchObject('Resultado')) {
    $x->data = time();
}

Isso me deixa com várias ideias para criar o ORM do ICEPHP. Mas fica a dica para vocês desenvolverem seus códigos, experimente criar um método FORM que já cria um formulário html para você facilitar sua vida. :D

PagSeguro, o que aconteceu por aqui

Algumas matérias sobre PagSeguro que passaram no meu blog são muito interessantes para serem esquecidas no meio de tantos POSTs que eu escrevo, então decidi fazer um review do que rolou por aqui durante esse tempo todo.

Aconteceu esta semana 2009-10-10

[Post Rápido] Músicas dos anos 90′

Para quem curte relembrar os velhos tempos. Eu, @dublado e @rodrideme estávamos lembrando das músicas que faziam a festa de nossa época. A playlist pode ser ouvida aqui mesmo:

Verifique o retorno automático, sempre!

Você já deve ter ouvido falar no Retorno Automático de dados do PagSeguro. Com ele você consegue sincronizar os dados de sua loja com os dados em suas transações no PagSeguro. O que é interessantíssimo pois com ele não precisamos ficar verificando cada e-mail que chega do PagSeguro e atualizando o nosso banco de dados.

** nota: Que fique claro que neste POST falo sobre carrinho próprio

Basicamente, uma aplicação funciona assim: Você monta uma compra e grava-a no seu banco de dados. Tomemos como exemplo duas chupetas doces no valor de R$ 3,40. Isto gerará uma compra no valor de R$ 6,80. Então, com isso montamos um formulário de pagamento que fará um POST para o PagSeguro.

Quando fizer isso, use um código de referencia para essa compra, se você usa auto_increment no seu banco de dados fica a dica para usar esse campo como código único, mas você pode gerar um número único baseado na data/hora atual mais um número aleatório. Em PHP você pode usar o método uniqid para isto.

O seu formulário ficará mais ou menos assim:

1
2
3
4
5
6
...
<input type="hidden" name="referencia" value="codigo_unico_de_compra" />
...
<input type="hidden" name="valor" value="340" />
<input type="hidden" name="quant" value="2" />
<input type="hidden" name="descr" value="chupeta doce" />

O que acontece?

Quando o comprador efetuar uma ação na compra, se você configurar e ativar uma URL de retorno automático no seu painel do PagSeguro, você receberá todos os dados da compra, inclusive o status da compra. A URL que você configurar como retorno automático é a mesma para a qual o usuário será redirecionado após o termino da transação no PagSeguro, seja ela emissão de boleto, pagamento via cartão de crédito ou débito ou mesmo transação entre contar PagSeguro.

Assim, você pode usar o código de referencia para saber a qual compra você vai atualizar. Mas, se é a mesma URL, como eu sei quem é o retorno automático? O retorno automático é um POST, a volta do usuário é GET. Um código bem simples em PHP para atualizar se assemelha bastante a este:

1
2
3
4
5
6
7
<?php
if ($_POST) {
  $compras = new Compras;
  $compras->get($_POST['Referencia']);
  $compras->set('status', $_POST['StatusTransacao']);
  die('Esta mensagem somente sera vista pelo robo do PagSeguro.');
}

Simples, né?! Mas o mundo não é perfeito, ainda mais na internet, então devemos nos prevenir de crackers (hackers malvados =P ). Imagine se eu efetuo uma compra e não pago. Então crio um formulário apontando para a URL de retorno à qual fui redirecionado com o StatusTransacao como Aprovado? Sim caro leitor, a pessoa efetua a compra sem pagar.

Pensando nisso, o PagSeguro fez um robôzinho onde você pode verificar se quem mandou o POST realmente foi ele. Funciona assim: Ao receber o POST, envie um POST para o robô e leia a saída. É como se você escrevesse um formulário direcionado para a URL de verificação de POST do PagSeguro e visse a página, ela deve aparecer como um arquivo de texto escrito VERIFICADO ou FALSO, caso os dados não batam com os dados contidos no PagSeguro.

Mas, para que a segurança seja maior, você deve enviar junto com todos os dados do PagSeguro os campos “Comando” com o valor “Verificar” e o campo “Token” com o código gerado no painel de controle do PagSeguro. Se você não enviar esses valores, o PagSeguro retornará FALSO, afinal, ele também verifica se você é você usando esse token que só você e o PagSeguro conhecem.

Em PHP você pode usar cURL para verificar esse POST, o código não é tão complicado de implementar assim. Apenas deve verificar que a URL do robô é https e que você está enviando um POST, então flags especiais devem ser usadas. Se você quiser, também pode usar a biblioteca PHP para PagSeguro desenvolvida pela visie que já faz essa verificação para você, apenas precisando que você faça a sua função como se não precisasse verificar nada.

A grosso modo, podemos alterar o nosso código para o seguinte:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
define('TOKEN','código gerado no painel de controle do PagSeguro'); # Aqui vai seu Token
include('retorno.php'); # Incluindo o arquivo da biblioteca

function retorno_automatico ( $VendedorEmail, $TransacaoID, 
  $Referencia, $TipoFrete, $ValorFrete, $Anotacao, $DataTransacao,
  $TipoPagamento, $StatusTransacao, $CliNome, $CliEmail, 
  $CliEndereco, $CliNumero, $CliComplemento, $CliBairro, $CliCidade,
  $CliEstado, $CliCEP, $CliTelefone, $produtos, $NumItens) {
    # E aqui, o nosso código
    $compras = new Compras;
    $compras->get($_POST['Referencia']);
    $compras->set('status', $_POST['StatusTransacao']);
    die('Esta mensagem somente sera vista pelo robo do PagSeguro.');
}

Ok, nosso mundo mudou bastante, colocamos proteção para o nosso cracker e ele vai ter um pouco mais de trabalho. Mas ainda temos um problema, quer dizer, uma solução… que gerou um problema: firebug.

Como todos nós estamos carecas de saber, o formulário que enviamos ao PagSeguro é um html normal que pode ser alterado de diversas formas, inclusive alterar os valores. Então, imaginemos o seguinte ambiente: você tem uma loja onde o usuário compra uma máquina de lavar por R$ 1.200,00. Para aproveitar mais ainda, ele compra três máquinas. Então ele chega no checkout e altera o formulário final para 5000, ou seja, R$ 50,00. Então ele pagará muito mais barato pela máquina, certo? Certo!

Certo?! Como assim?

Sim, ele vai pagar mais barato, porque burlou o sistema, cabe a você ter tino e devolver o dinheiro do infeliz. Mas calma! Você não precisa verificar todas as contas na mão para saber se a pessoa está burlando o sistema. Basta você conferir o valor do POST de retorno com o valor da compra.

Lembra que gravamos a compra no banco antes de enviar o comprador para o PagSeguro usando um código único? Coloque também o valor total da compra. Quando você receber o POST do retorno automático, verifique o valor da compra pois se a pessoa alterar o valor do input com a firebug (ou similar) o sistema saberá que não é válido. Veja como fica o nosso código.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
define('TOKEN','código gerado no painel de controle do PagSeguro'); # Aqui vai seu Token
include('retorno.php'); # Incluindo o arquivo da biblioteca

function retorno_automatico ( $VendedorEmail, $TransacaoID, 
  $Referencia, $TipoFrete, $ValorFrete, $Anotacao, $DataTransacao,
  $TipoPagamento, $StatusTransacao, $CliNome, $CliEmail, 
  $CliEndereco, $CliNumero, $CliComplemento, $CliBairro, $CliCidade,
  $CliEstado, $CliCEP, $CliTelefone, $produtos, $NumItens) {
    # E aqui, o nosso código
    $total = 0;
    foreach ($produtos as $produto) {
      $total += ($produto['ProdValor'] * $produto['ProdQuantidade']) + $produto['ProdFrete'] + $produto['ProdExtras'];
    }
    if ($total == $compras->total) {
      $compras = new Compras;
      $compras->get($Referencia);
      $compras->set('status', $StatusTransacao);
    }
    die('Esta mensagem somente sera vista pelo robo do PagSeguro.');
}

Simples assim! Apenas pegamos todos os produtos e somamos o produto de seus valores pelas suas respectivas quantidades, aliado aos valores extras e de frete. Quanto mais campos você verificar no retorno automático, melhor. Mas não exagere pois poderá falhar em alguns casos. Por exemplo você pode enviar um e-mail para o PagSeguro e a pessoa decidir pagar com outra conta (da esposa ou da empresa, por exemplo).

[Post rápido] PHP-MG

Pessoal, este é apenas um POST jabá. No dia 17 de outubro (este mês) vou palestrar no PHP-MG, onde vou falar aertamente sobre e-commerce. A palestra é voltada para novos programadores e programadores que queiram saber como implementa-se o PagSeguro e seu obscuro Retorno Automático de Dados.

O tema de minha palestra é Da argila ao forte: Como desenvolver uma loja virtual, onde irei demonstrar como você pode começar a ganhar dinheiro de uma forma simples e rápida. Quem me acompanha no twitter viu que alguns dias atrás estive testando vários sistemas de e-commerce, como o prestashop. Mas na ocasião não irei implementar nenhum sistema convencional, no entanto… Bom, não vou estragar a surpresa, acho melhor vocês irem lá presenciar.