Sunteți pe pagina 1din 85

‘’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’

Sistema de Vendas usando Pagseguro

PHP & PAGSEGURO – Vendas usando Pagseguro Exemplo de Sistema em PHP


Copyright © 2017 - Wanderlei Santana do Nascimento

Todos os direitos reservados. Nenhuma parte deste Material poderá ser reproduzida, mesmo
parcial, sob qualquer meio, seja este físico ou digital, sem a permissão por escrito do autor.

Autor/Editor
Wanderlei Santana

Capa
Wanderlei Santana

Diagramação
Wanderlei Santana

Contato
sans.pds@gmail.com

Data
05/05/2017 23:16

Revisão
20170506130100

Este Livro registra em suas páginas nomes comerciais e marcas registradas de produtos
pertencentes a diversas companhias. O autor apenas utiliza-se destas marcas para fins
editoriais e em benefício das empresas proprietárias da marca, sem qualquer intenção de
infringir seus direitos.

http://sooho.com.br

2
Sistema de Vendas usando Pagseguro

Wanderlei Santana

PHP & PAGSEGURO


Vendas usando Pagseguro: Exemplo de
sistema em PHP

2017

3
Sistema de Vendas usando Pagseguro

TABELA DE CONTEÚDOS

Sumário
PHP & PAGSEGURO ............................................................................................................................ 3
Vendas usando Pagseguro: Exemplo de sistema em PHP ................................................................ 3
TABELA DE CONTEÚDOS .................................................................................................................... 4
INTRODUÇÃO ............................................................................................................................. 6
Objetivo deste tutorial ...................................................................................................... 6
Resultado Final e Código Fonte ........................................................................................ 7
O que será abordado? ..................................................................................................... 10
O que não será abordado? ............................................................................................. 10
COMO FUNCIONA UM SISTEMA DE VENDAS ......................................................................... 11
Fluxograma de Vendas ao Cliente................................................................................... 11
PLANEJAMENTO E PROCESSOS INICIAIS ................................................................................. 13
O Cliente será capaz de... ................................................................................................ 13
Criando a Estrutura de Pastas ......................................................................................... 14
Criando a Classe Carrinho de Compras .......................................................................... 15
Criando uma Classe para gerenciar Sessões do usuário ............................................... 28
O Banco de Dados ........................................................................................................... 33
Banco de Dados: Tabelas Produtos ................................................................................ 38
Banco de Dados: Tabela Usuários ................................................................................... 40
Banco de Dados: Tabela Vendas ..................................................................................... 41
Banco de Dados: Tabela Itens de Vendas ....................................................................... 41
CRIANDO A PÁGINA DE PRODUTOS ........................................................................................ 41
Fluxograma interno da Página Produtos ........................................................................ 42
Obtendo os Produtos ...................................................................................................... 44
CRIANDO A PÁGINA CARRINHO DE COMPRAS ....................................................................... 49
Fluxograma interno Carrinho de Compras ..................................................................... 50
Atualizando o Carrinho.................................................................................................... 51
A PÁGINA DE CADASTRO DE USUÁRIOS ................................................................................. 55
CRIANDO A PÁGINA FINALIZAR COMPRA ............................................................................... 55
PROCESSOS FINAIS DA VENDA E INTEGRAÇÃO COM O PAGSEGURO DA UOL ..................... 58
Identificando o Cliente .................................................................................................... 58
Gravando informações da Venda no banco de Dados................................................... 60
Gravando informações dos Itens da Venda no banco ................................................... 62
Iniciando transação com Pagseguro: Gerando Arquivo XML ........................................ 62
Rotinas de Auditoria ........................................................................................................ 66

4
Sistema de Vendas usando Pagseguro

Enviando XML ao Pagseguro ........................................................................................... 66


O arquivo XML de retorno do Pagseguro ....................................................................... 67
Verificação de Erros ......................................................................................................... 68
Informando Cliente via E-mail sobre Compra realizada com sucesso .......................... 69
Direcionando Cliente para o Pagseguro ......................................................................... 70
CRIANDO UMA PÁGINA DE ERROS ......................................................................................... 72
CRIANDO UMA PÁGINA DE CONFIRMAÇÃO DA COMPRA ..................................................... 75
CRIANDO UMA PÁGINA DE NOTIFICAÇÕES ............................................................................ 76
INFORMANDO A PÁGINA DE NOTIFICAÇÃO NO PAGSEGURO ............................................... 76

5
Sistema de Vendas usando Pagseguro

INTRODUÇÃO
Este é um artigo ensinando como criar um sistema de vendas simples – em código PHP puro.
Ele foi elaborado apenas com intuito de demonstrar como funciona a integração de um sistema
de Vendas com a API do Pagseguro. Informando ao Pagseguro sobre uma venda realizada e
processando as notificações que informam sobre o status dessa venda.

Esse simples sistema permite que um Cliente visualize Produtos em uma página Web, adicione
produtos a um carrinho de compras, acesse a lista dos produtos escolhidos e conclua a compra
sendo direcionado no final para o PAGSEGURO a fim de realizar o pagamento da Compra.

Uma vez que o foco principal é apenas a integração com a API do Pagseguro, tópicos como
“Gerenciamento de Usuário”, “Gerenciamento de Produtos”, “Criação de Dashboard” ou “área
do Cliente” não serão abordados para não tornar o tutorial demasiado extenso.
Decidi criar um pequeno sistema de vendas para acompanhar esse artigo sobre a integração
com o Pagseguro, justo para dar um norte a quem está começando ou precisa de dicas e
informações sobre o funcionamento de um sistema de vendas.

O código foi construído com programação estruturada em vários pontos e não segue as
melhores práticas de desenvolvimento, isso se faz necessário para tornar-se fácil de entender
para pessoas com diferentes níveis de conhecimento técnico em PHP. Também pensando nisso,
são apresentados inúmeros fluxogramas para maximizar a compreensão da lógica empregada
num sistema de vendas.

Objetivo deste tutorial


Volto a frisar que o foco principal deste documento é apresentar a integração do Pagseguro
com um sistema de vendas. Não farei uso de código de terceiros como os que são oferecidas no
Github e nem da biblioteca do Pagseguro. Todo o código será feito e explicado linha a linha
desde o momento de escolha de um produto pelo cliente, passando pela geração de um
arquivo XML para envio ao Pagseguro e terminando com um arquivo PHP que recebe
notificações do Pagseguro informando o status de pagamento das compras realizadas no seu
site.

Importante:

Se o seu intuito é apenas aprender como gerar o arquivo de XML e remeter ao sistema do
Pagseguro, podes então pular para o item “Processos Finais da Venda e Integração com o

6
Sistema de Vendas usando Pagseguro

Pagseguro da UOL”, porém, acompanhando este material por completo você encontrar
informações que podem ser úteis ao seu sistema e que podem agregar valioso conhecimento
ao seu desenvolvimento profissional.

Resultado Final e Código Fonte


As imagens abaixo dão uma demonstração do resultado que será alcançado seguindo os
ensinamentos contidos nesse material. Este é o pequeno sistema que vamos desenvolvendo.

Página para a exibição de Produtos

Figura 1 - Página WEB com exibição de Produtos à Venda

7
Sistema de Vendas usando Pagseguro

Carrinho de Compras

Confirmação de Compra

8
Sistema de Vendas usando Pagseguro

Download de Código fonte

O download do Código fonte não se encontra disponível no momento, mas será disponibilizado
quanto antes.

9
Sistema de Vendas usando Pagseguro

O que será abordado?


Serão abordadas as seguintes funcionalidades, listados abaixo.

Front-End:
 Criação de uma Página de Produtos;
 Criação de uma Página para visualização de Carrinho de Compras;
 Criação de uma Página para a Verificação de Itens da Compra;
 Criação de uma Página de Confirmação de Venda;
 Criação de um script para comunicação com o Pagseguro;
 Criação de uma Página para Apresentação de Erros;
 Criação de um Template para Envio de E-mail de Confirmação de Compra;

Back-End:
 Criação de uma Classe PHP para gerenciamento de Sessões;
 Criação de uma Classe PHP para gerenciamento de Carrinho de Compras;
 Criação de uma Classe PHP para uso de um Banco de Dados Hipotético em JSON
 Registro de Logs para Auditoria
 Processos para adição de Produtos a um Carrinho de Compras;
 Processos para gerenciar Carrinho de Compras;
 Processos para realizar a integração com a API do Pagseguro;
 Processos para receber notificações do Pagseguro;
 Processos para envio de E-mail de confirmação de Compra realizada;

O que não será abordado?


Abaixo uma lista de coisas que não serão abordadas, mas que merecem atenção quando se
está construindo um sistema de vendas completo.

Processos relacionados ao Dashboard: Não serão abordados.

Gerenciamento de Clientes: Será escrito sobre, porém não serão desenvolvidos scripts para o
gerenciamento de clientes. Esse é um processo a parte que demanda tempo, que requer
cuidados e que pode se estender a muitas possibilidades fugindo totalmente do escopo desse
tutorial.

10
Sistema de Vendas usando Pagseguro

No sistema que vamos desenvolver, usaremos informações de um usuário que estão gravadas
em uma tabela feita em JSON – para simular um Cliente Cadastrado em um banco de dados.

Cadastro de Clientes: O Cadastro de Clientes é parte do Gerenciamento de Clientes e se


enquadra na explicação supracitada.

Login de Clientes: Também se enquadra na explicação acima e no mesmo sistema.

Gerenciamento de Produtos: Não será abordado.

COMO FUNCIONA UM SISTEMA DE


VENDAS
O foco principal em um sistema de vendas online é permitir a qualquer pessoa cadastrar-se
através de um formulário, visualizar os produtos oferecidos, adicionar produtos a um carrinho
de compras, realizar pagamentos e acompanhar o status de entrega da sua compra – salvo
casos em que o cliente decide retirar o produto direto na loja.

Fluxograma de Vendas ao Cliente


Note que, o fluxograma abaixo contempla apenas a parte que será implantada por este tutorial.
Para um sistema completo e funcional, o cadastro e login de usuários são itens obrigatórios.
O fluxograma abaixo serve para demonstrar os processos básicos necessários para a
concretização de uma venda. Nele, são apresentadas as ações realizadas por SISTEMA e
CLIENTES lado a lado.

11
Sistema de Vendas usando Pagseguro

12
Sistema de Vendas usando Pagseguro

PLANEJAMENTO E PROCESSOS INICIAIS


Gosto de começar a construção de qualquer software sempre com um bom planejamento,
porque aos poucos outras necessidades vão surgindo antes de iniciar a parte prática. Isso ajuda
a não ficar parado em um ponto do desenvolvimento sem saber qual é o próximo passo a
seguir. Isso serve também para evitar surpresas desagradáveis durante o desenvolvimento –
como a adição de uma nova funcionalidade que causa anomalias em diferentes pontos do
sistema.

O Cliente será capaz de...


Começo sempre respondendo a perguntas como: “O Cliente será capaz de?” Ou, “O Sistema
será capaz de?” ou ainda, “O Administrador será capaz de?”.
Vou tentar listar abaixo várias das ações que um usuário comum pode realizar num sistema de
vendas Online. Em um sistema real, essa lista de ações deve ser avaliada, aprovada por uma
equipe e implantada como funcionalidades do sistema. Note que nem todas as opções farão
parte do escopo deste tutorial e eu fiz questão de evidenciar as que farão parte no início desse
artigo.

Para um sistema de vendas online o cliente é capaz de:


 Visualizar uma página com uma lista de produtos à venda;
 Visualizar detalhes de um Produto, fotos, modelos e afins;
 Escolher modelos diferentes de um Produto;
 Adicionar um ou mais produtos ao carrinho de compras – dada a disponibilidade;
 Realizar solicitação de Compras;
 Realizar Pagamento;
 Baixar documentos e catálogos sobre o Produto;
 Avaliar um produto que comprou;
 Ver avaliação de outros compradores sobre o produto;
 Cadastrar-se no sistema;
 Realizar Login;
 Realizar Logout;
 Acessar área do Cliente;
 Alterar dados Cadastrais;
 Visualizar o Status das suas Compras;
 Visualizar Histórico de Compras;
 Gerar 2ª via de cobranças;
 Rastrear pedidos;

13
Sistema de Vendas usando Pagseguro

 Entrar em contato com setor de vendas da empresa;


 Apagar a Conta;
 Cancelar uma compra;
 Fazer uma reclamação;

A lista acima serve para mostrar que as possibilidades para um cliente em um sistema de
vendas são inúmeras. E a implantação prática apenas das que citei tornaria esse tutorial um
livro de 300 páginas. Note ainda que essas são apenas as funcionalidades do Cliente. Existem
inúmeras outras funcionalidades ligadas ao Sistema. Você deve lembrar sempre que, toda
entidade que “interage” com qualquer sistema que você estiver desenvolvendo e forneça a
Entrada, Processamento ou Saída de Dados é um candidato em potencial para uma lista de
funcionalidades como a supracitada.

Então, comece sempre o planejamento de qualquer software listando todas as ações que as
entidades e o sistema serão capazes de realizar. E posteriormente essas ações vão se tornar
funcionalidades do seu sistema.

Criando a Estrutura de Pastas


Comece por criar uma estrutura das pastas que irão armazenar os arquivos. Se você já tem um
sistema em progresso, crie uma estrutura que se encaixe em seu projeto. Abaixo você pode ver
a estrutura de pastas que usei para implantação desse sistema. Você não precisa usa-las tal
como está aqui descrito, adapte-as de forma que fiquem organizadas para você.

- Assets guarda arquivos associados ao Front-End. Imagens, Javascript, CSS.


- Na pasta Classes ficarão as classes de Sessão e Carrinho de compras.
- A pasta Database armazena um banco de dados hipotético. Esta pasta é opcional, se você já
estiver usando um banco de dados como Oracle, MySQL, SQL Server, Firebird, etc.
- A pasta Logs armazena logs de transações com o Pagseguro. Importante para auditoria do
sistema caso algo saia errado nesses processos.

14
Sistema de Vendas usando Pagseguro

Figura 2 - Estrutura de Pastas vistas através do Editor de Código

Criando a Classe Carrinho de Compras


Como gravar as informações dos produtos que o cliente escolher comprar?

Quando um cliente entra num site de vendas, visualiza um produto e dá um clique sobre o
botão comprar, informações como: Identificação do Produto, Nome do Produto, Modelo do
Produto e quantidade de Produtos precisam ser armazenadas em algum lugar. Para que quando
o cliente finalize a compra, todas as informações dos produtos que ele escolheu sejam reunidas
em uma página e apresentadas a ele para confirmação e conclusão do Pedido.

Solução
A forma mais usada para resolver esse problema é a criação de um Carrinho de Compras.

Um Carrinho de Compras possibilita ao Cliente registrar os itens que ele quer comprar e
determinar a quantidade de cada item. Além disso, o carrinho (ou Cart) oferece métodos que
permitem listar os produtos já selecionados pelo cliente e calcular automaticamente o valor
total da compra.

Nesse artigo não vamos criar uma classe Carrinho do zero. Afinal, uma das melhores coisas
sobre programação Orientada a Objetos é a possibilidade de reaproveitar código, e um bom
exemplo disso é a classe descrita abaixo – Cart.class.php (carrinho de compras). Essa classe foi
reaproveitada de um excelente framework PHP, o CodeIgniter.

15
Sistema de Vendas usando Pagseguro

Eu realizei alguns poucos ajustes para remover as dependências e desagregar essa classe do
CodeIgniter. Dessa forma, podemos usar ela no nosso sistema com outros códigos que não os
contidos nas livrarias do CodeIgniter.

Abaixo você acompanha todo o código que compõe essa classe, darei um breve resumo sobre
cada um.

Descrição: Classe PHP para gerenciar o Carrinho de compras


Localicação: C:\wamp\www\Pagseguro\classes\LIBVENDAS\Car.class.php

Registrando Informações de um Produto no Carrinho de Compras – O


Método Insert

A primeira e mais importante função que um Carrinho de compras precisa ter é a capacidade
de receber e gravar informações de um produto. Essas informações são gravadas com o
método insert(). As informações são enviadas por parâmetro e seguem o padrão já
estabelecido pelo Codeigniter, sendo:
- id: Identificação única de um Produto no banco de dados;
- qty: Quantidade de um mesmo produto sendo adicionadas ao carrinho;
- price: Preço unitário do produto sendo adicionado;
- name: Nome ou título do Produto sendo adicionado;
- options: Esse é um campo livre para inclusão de informações extras sobre o produto sendo
adicionado ao carrinho. No caso, vamos adicionar apenas as informações “modelo”,

16
Sistema de Vendas usando Pagseguro

“modelo_title” e “peso”. Porém, você é livre para adicionar qualquer informação extra que
julgar útil.

Cart.class.php
<?php

namespace LIBVENDAS;

require_once 'session.class.php';

/**
* Esta é a Classe Cart reaproveitada da Framework CodeIgniter
* Para mais informações consulte o site do Desenvolvedor.
*
* @fonte: https://www.codeigniter.com
*/
class Cart
{
// These are the regular expression rules that we use to validate
// the product ID and product name
// alpha-numeric, dashes, underscores, or periods
var $product_id_rules = '\.a-z0-9_-';

// alpha-numeric, dashes, underscores, colons or periods


var $product_name_rules = '\.\:\-_ a-z0-9';

// Private variables. Do not change!


var $session;
var $_cart_contents = array();

O comando: namespace LIBVENDAS; é usado para evitar conflito com outra classe que por
ventura possa ter o mesmo nome que Cart, dessa forma, serve para categorizar a Livraria que
estamos desenvolvendo.

require_once 'session.class.php’;
Inclui no sistema a classe responsável por gerenciar sessões. Essa classe vai permitir que o
cliente navegue pelo site sem perder as informações sobre os produtos que ele escolhe
adicionar à compra. Sem essa classe, o objeto Cart iria registrar um produto escolhido pelo
cliente, mas as informações gravadas seriam perdidas assim que o cliente visitasse outra página
do site.

var $product_id_rules = '\.a-z0-9_-';


Trata-se de uma expressão regular em PHP para filtrar uma informação e remover tudo que não
se enquadra na regra estabelecida. No caso acima se aplica ao campo ID do Produto. Por
exemplo, se tentarmos adicionar na classe Cart um produto com ID “16%$#7” esse filtro irá
limpar essas informação e gravar o ID como “167”.

17
Sistema de Vendas usando Pagseguro

O método construtor da Classe

Cart.class.php (continuação)
public function __construct($params = array())
{
// Are any config settings being passed manually? If so, set them
$config = array();
if (count($params) > 0)
{
foreach ($params as $key => $val)
{
$config[$key] = $val;
}
}

// Load the Sessions class


$this->session = new Session();

// Grab the shopping cart array from the session table, if it exists
if ($this->session->get('cart_contents') != null)
{
$this->_cart_contents = $this->session->get('cart_contents');
}
else
{
// No cart exists so we'll set some base values
$this->_cart_contents['cart_total'] = 0;
$this->_cart_contents['total_items'] = 0;
}

O Método construtor da classe Cart recebe alguns parâmetros para a configuração através do
array $params. Porém, não cabe a explicação detalhada dessa funcionalidade aqui, pois não
faremos uso dela. A única alteração importante em relação à classe Original do CodeIgniter que
cabe ser mencionada é a remoção das linhas que fazem chamadas às bibliotecas do
CodeIgniter e a utilização da linha :

$this->session = new Session();

Para a chamada da classe de sessão própria que criaremos a seguir.

O método INSERT
Esse é o método usado no carrinho de compras que permite ao cliente registrar os Produtos e
demais informações sobre o item.

18
Sistema de Vendas usando Pagseguro

Cart.class.php (continuação)
/**
* Insert items into the cart and save it to the session table
*
* @access public
* @param array
* @return bool
*/
function insert($items = array())
{
// Was any cart data passed? No? Bah...
if ( ! is_array($items) OR count($items) == 0){
return FALSE;
}

$save_cart = FALSE;
if (isset($items['id'])){
if (($rowid = $this->_insert($items))){
$save_cart = TRUE;
}
}
else{
foreach ($items as $val){
if (is_array($val) AND isset($val['id'])){
if ($this->_insert($val)){
$save_cart = TRUE;
}
}
}
}

// Save the cart data if the insert was successful


if ($save_cart == TRUE){
$this->_save_cart();
return isset($rowid) ? $rowid : TRUE;
}
return FALSE;
}

Esse método recebe como parâmetro um Array com as seguintes informações: id:string,
qty:integer, price:decimal, name:string, options:Array.

Veja abaixo um exemplo hipotético de como usar esse método. Note que os campos id, qty,
price e name são padrões, já o campo options pode guardar um Array com qualquer
informação que você desejar. Essa é a mecânica criada pela equipe do CodeIgniter e que se
manterá intacta.

Exemplo de uso:
$_produto = array(
'id' => 1001,

19
Sistema de Vendas usando Pagseguro

'qty' => 2,
'price' => 149.99,
'name' => Celular Nokia 1914,
'options' => array(
'modelo' => ’C3PO’,
'modelo_title' => ’Modelo com visual Retro’,
'peso' => 3000 /* 3Kg */
)
);

$carrinho -> insert( $_produto );

O método privado _INSERT


_INSERT é um método privado chamado através do Método público INSERT. Existe por questões
de conveniência apenas para diminuir a quantidade de código em um mesmo método. Isso
evita que um programador se perca em meio a diferentes lógicas para diferentes processos.

Cart.class.php (continuação)
/**
* Insert
*
* @access private
* @param array
* @return bool
*/
function _insert($items = array()){
// Was any cart data passed? No? Bah...
if ( ! is_array($items) OR count($items) == 0){
return FALSE;
}

if ( ! isset($items['id']) OR !
isset($items['qty']) OR ! isset($items['price']) OR !
isset($items['name'])){
return FALSE;
}

// Prep the quantity. It can only be a number. Duh...


$items['qty'] = trim(preg_replace('/([^0-9])/i', '', $items['qty']));
// Trim any leading zeros
$items['qty'] = trim(preg_replace('/(^[0]+)/i', '', $items['qty']));

// If the quantity is zero or blank there's nothing for us to do


if ( ! is_numeric($items['qty']) OR $items['qty'] == 0){
return FALSE;
}

20
Sistema de Vendas usando Pagseguro

if ( ! preg_match("/^[".$this->product_id_rules."]+$/i", $items['id'])){
return FALSE;
}

if ( ! preg_match("/^[".$this->product_name_rules."]+$/i",
$items['name'])){
return FALSE;
}
$items['price'] =
trim(preg_replace('/([^0-9\.])/i', '', $items['price']));
// Trim any leading zeros
$items['price'] =
trim(preg_replace('/(^[0]+)/i', '', $items['price']));

if ( ! is_numeric($items['price'])){
return FALSE;
}

if (isset($items['options']) AND count($items['options']) > 0){


$rowid = md5($items['id'].implode('', $items['options']));
}
else{
$rowid = md5($items['id']);
}

unset($this->_cart_contents[$rowid]);

$this->_cart_contents[$rowid]['rowid'] = $rowid;

foreach ($items as $key => $val){


$this->_cart_contents[$rowid][$key] = $val;
}

// Woot!
return $rowid;
}

O método público UPDATE

Este método permite que a quantidade de um dado item possa ser alterada.
Tipicamente ele é chamado através do front-end, mais precisamente através da página carrinho
de compras quando um cliente faz alterações na quantidade de itens antes de realizar o
Checkout da compra. O parâmetro passado a esse método precisa conter o ID do Produto e a
quantidade para cada item para o registro funcionar corretamente.

Cart.class.php (continuação)
/*
* @access public
* @param array
* @param string

21
Sistema de Vendas usando Pagseguro

* @return bool
*/
function update($items = array()) {
// Was any cart data passed?
if ( ! is_array($items) OR count($items) == 0) {
return FALSE;
}

$save_cart = FALSE;
if (isset($items['rowid']) AND isset($items['qty'])) {
if ($this->_update($items) == TRUE) {
$save_cart = TRUE;
}
}
Else {
foreach ($items as $val)
{
if (is_array($val) AND
isset($val['rowid']) AND isset($val['qty'])){
if ($this->_update($val) == TRUE)
{
$save_cart = TRUE;
}
}
}
}

// Save the cart data if the insert was successful


if ($save_cart == TRUE) {
$this->_save_cart();
return TRUE;
}

return FALSE;
}

O método privado _UPDATE

Assim como o método privado _insert, o método _update também segue a metodologia
“dividir para conquistar”. É uma abordagem muito comum em programação orientada a
Objetos a divisão de código em peças menores. Isso torna mais fácil manejar os trechos
pequenos e não gerar o problema que a IBM – em seu artigo Build seven good object-oriented
habits in PHP – chama de “Olhar para a Medusa”.

Cart.class.php (continuação)
function _update($items = array())
{
// Without these array indexes there is nothing we can do
if ( ! isset($items['qty']) OR ! isset($items['rowid']) OR !
isset($this->_cart_contents[$items['rowid']]))

22
Sistema de Vendas usando Pagseguro

{
return FALSE;
}

// Prep the quantity


$items['qty'] = preg_replace('/([^0-9])/i', '', $items['qty']);

// Is the quantity a number?


if ( ! is_numeric($items['qty']))
{
return FALSE;
}

// Is the new quantity different than what is already saved in the cart?
// If it's the same there's nothing to do
if ($this->_cart_contents[$items['rowid']]['qty'] == $items['qty'])
{
return FALSE;
}

// Is the quantity zero? If so we will remove the item from the cart.
// If the quantity is greater than zero we are updating
if ($items['qty'] == 0)
{
unset($this->_cart_contents[$items['rowid']]);
}
else
{
$this->_cart_contents[$items['rowid']]['qty'] = $items['qty'];
}

return TRUE;
}

O método privado _SAVE_CART


Esse método é chamado internamente em vários pontos da classe Cart. Visto que todos os
dados do carrinho são armazenados em forma de Array, esse método age para salvar esse Array
na sessão do usuário que esta acessando o sistema.

Cart.class.php (continuação)
/**
* Save the cart array to the session DB
*
* @access private
* @return bool
*/
function _save_cart()
{
// Unset these so our total can be calculated correctly below
unset($this->_cart_contents['total_items']);
unset($this->_cart_contents['cart_total']);

23
Sistema de Vendas usando Pagseguro

// Lets add up the individual prices and set the cart sub-total
$total = 0;
$items = 0;
foreach ($this->_cart_contents as $key => $val)
{
// We make sure the array contains the proper indexes
if ( ! is_array($val) OR ! isset($val['price']) OR !
isset($val['qty']))
{
continue;
}

$total += ($val['price'] * $val['qty']);


$items += $val['qty'];

// Set the subtotal


$this->_cart_contents[$key]['subtotal'] =
($this->_cart_contents[$key]['price'] * $this->_cart_contents[$key]['qty']);
}

// Set the cart total and total items.


$this->_cart_contents['total_items'] = $items;
$this->_cart_contents['cart_total'] = $total;

// Is our cart empty? If so we delete it from the session


if (count($this->_cart_contents) <= 2)
{
$this->session->del( 'cart_contents' );

// Nothing more to do... coffee time!


return FALSE;
}

// If we made it this far it means that our cart has data.


// Let's pass it to the Session class so it can be stored
$this->session->set('cart_contents', $this->_cart_contents) ;

// Woot!
return TRUE;
}

Os assessores públicos, métodos informativos e de controle

Os métodos a seguir finalizam a classe Carrinho de Compras. São métodos usados para fazer o
controle do Carrinho ou para obter informações sobre seu estado atual do mesmo.

24
Sistema de Vendas usando Pagseguro

Método total()
Se você tem um carrinho de compras, em algum momento você vai precisar saber o valor total
a ser pago pelas mercadorias dentro dele, e é para isso que serve o método total(). Esse
método retorna um valor decimal com o preço a ser pago pela compra do Cliente.

Cart.class.php (continuação)
/**
* @access public
* @return decimal
*/
function total()
{
return $this->_cart_contents['cart_total'];
}

Você sabe quantos itens existem dentro do Carrinho? O Método


total_items() responde
Da mesma forma que você precisa saber o preço total de uma compra, você também precisa
saber quantos itens está dentro de um carrinho. E nesse momento o método total_items entra
para suprir essa necessidade.

Cart.class.php (continuação)
/**
* Total Items
*
* Returns the total item count
*
* @access public
* @return integer
*/
function total_items()
{
return $this->_cart_contents['total_items'];
}

Fazendo um Dump do Carrinho – o Método contents()


Se você é programador e está alterando algum aspecto do carrinho de compras, então durante
o processo de debug você precisa visualizar na sua tela todas as informações gravadas no
carrinho de compras de uma só vez, para analisar se os cálculos e contabilizações estão
corretas. Para isso, o método contents() existe, ele retorna um array com todas as informações
que você precisa.

25
Sistema de Vendas usando Pagseguro

Cart.class.php (continuação)
/**
* Cart Contents
*
* Returns the entire cart array
*
* @access public
* @return array
*/
function contents()
{
$cart = $this->_cart_contents;

// Remove these so they don't create a problem when showing the cart table
unset($cart['total_items']);
unset($cart['cart_total']);

return $cart;
}

Recuperando dados extras de um registro no Carrinho de Compras –


options
Importante notar que rowid não se refere ao ID do Produto e sim ao ID do registro no carrinho!
Sempre que você adicionar um produto ao Carrinho é criado uma rowid única para identificar
esse registro. Essa RowID é usada por exemplo quando você quer atualizar uma informação de
um produto.
O método has_options(), recebe como parâmetro uma rowid e informa se esse produto tem
opções associadas a ele, caso tenha retorna um valor TRUE.

Cart.class.php (continuação)
/**
* Has options
*
* Returns TRUE if the rowid passed to this function correlates to an item
* that has options associated with it.
*
* @access public
* @return array
*/
function has_options($rowid = '')
{
if ( ! isset($this->_cart_contents[$rowid]['options']) OR
count($this->_cart_contents[$rowid]['options']) === 0){
return FALSE;
}
return TRUE;

26
Sistema de Vendas usando Pagseguro

Já no caso do método product_options() ao passar a rowid do registro por parâmetro, será


retornado um Array com as opções associadas àquele produto.

Cart.class.php (continuação)
/**
* Product options
*
* Returns the an array of options, for a particular product row ID
*
* @access public
* @return array
*/
function product_options($rowid = '')
{
if ( ! isset($this->_cart_contents[$rowid]['options'])){
return array();
}
return $this->_cart_contents[$rowid]['options'];
}

Formatando Preços – O método format_number()


Por padrão, o preço de um produto é armazenado dentro do carrinho de compras em formato
decimal (ex: 1149.99). A classe Cart oferece o método format_number() para permitir que
você formate esse valor. Assim, o valor decimal 1149.99 seria convertido para 1,149.99

Nota: Acima foi usado o padrão americano de normatização, com a vírgula antes do ponto. Eu
decidi não alterar esse código, mas caso queira alterar para o padrão usado no Brasil, basta
mudar conforme abaixo:

return number_format($n, 2, '.', ',');


por
return number_format($n, 2, ',', '.');

Com essa alteração valores armazenados no Cart como 1149.99 se convertidos com essa
função retornarão como 1.149,99

Cart.class.php (continuação)
/**
* Format Number

27
Sistema de Vendas usando Pagseguro

*
* Returns the supplied number with commas and a decimal point.
*
* @access public
* @return integer
*/
function format_number($n = '')
{
if ($n == ''){
return '';
}

// Remove anything that isn't a number or decimal point.


$n = trim(preg_replace('/([^0-9\.])/i', '', $n));

return number_format($n, 2, '.', ',');


}

O método publico destroy()


Quando o cliente concluir a compra, o carrinho de compras não será mais útil e precisa ser
destruído. Para isso você precisa implantar um método destroy(). Esse método vai destruir
todas as variáveis que a classe Carrinho salvou na sessão do usuário.

Cart.class.php (continuação)
/**
* Destroy the cart
*
* Empties the cart and kills the session
*
* @access public
* @return null
*/
function destroy()
{
unset($this->_cart_contents);

$this->_cart_contents['cart_total'] = 0;
$this->_cart_contents['total_items'] = 0;

$this->session->unset_userdata('cart_contents');
}

Criando uma Classe para gerenciar Sessões do usuário


Devido a natureza dos sistemas online e a forma como as informações transitam entre o Cliente
e o Servidor, toda e qualquer variável declarada em um script PHP só existirá enquanto esse

28
Sistema de Vendas usando Pagseguro

script estiver sendo processando no Servidor. No momento que a página final é retornada ao
Cliente, todas as variáveis e constantes declaradas em PHP deixam de existir, pois o Servidor
finaliza os processos do interpretador PHP.
Portanto, ao programar sistemas online em PHP, ASPX, Ruby é necessário ter mecanismos que
permitam identificar um Cliente que está fazendo requisições ao Servidor. Também é
importante garantir que uma variável declarada possa existir pelo tempo que quisermos. Essas
habilidades são possíveis graças as Sessões. Elas nos permitem algo chamado Persistência de
Dados.
O Carrinho de Compras construído no artigo anterior seria inútil sem uma sessão, pois sem a
sessão seria impossível identificar um usuário em meio a milhares quando ele retornar ao site
ou faz novas requisições ao servidor.

Portanto, agora vamos criar uma classe bem simples para gerenciar sessões, porém bem
flexível e que vai facilitar muito o trabalho no sistema de vendas online.

Descrição: Gereciamento de Sessões no PHP


Localização: C:\wamp\www\Pagseguro\LIBVENDAS\Session.class.php

Essa Classe conta com apenas duas propriedades privadas, onde:


$instance – trata-se de uma variável que guarda uma instância da própria Classe – Modelo
Singleton.
$session_expire_time – Se você quiser que a sessão detentora dos dados de um usuário seja
destruída depois de algum tempo (30 minutos, por exemplo), basta definir essa variável para o
valor inteiro 1800, que é a representação de 30 minutos em segundos.

Session.class.php

29
Sistema de Vendas usando Pagseguro

<?php

namespace LIBVENDAS;

class Session
{
private static $instance;
private $session_expire_time = null ;

O método Construtor

O método construtor da classe Session é quem realiza todo o trabalho pesado, sendo ele o
responsável por impor as únicas linhas contendo algum tipo de lógica de programação.
Por seguir um modelo Singleton, a primeira linha de código self::$instance =& $this; diz ao
interpretador PHP que, a variável $instance deve receber o objeto atualmente instanciado, em
outras palavras receber a si própria.

session_start() – inicializa nossa sessão, não sendo necessário mais inserir essa chamada em
nenhum outro arquivo.

Session.class.php (continuação)
/**
* Método construtor
*
* @access public
* @param int - tempo máximo para expiração da sessão
*/
public function __construct( $expire_time = null )
{
# Singleton - evita ser instanciado duas vezes
self::$instance =& $this;

$this->setExpiretime( $expire_time );

session_start();
header("Cache-control: private");

# troca o ID da sessão a cada atualização da página


# quando fecha browser destrói sessão
# impede roubo de sessão
session_regenerate_id();

# definindo configurações do arquivo ini( evita JS acessar sessão )


ini_set( 'session.cookie_httponly' , true );
ini_set( 'session.use_only_cookies', true );

# verificando se sessão esta configurada para expirar apos inatividade


if( ! is_null( $this->session_expire_time ) ):
# verificando se sessão não expirou por tempo
if( isset($_SESSION['SS_ULTIMA_ATIVIDADE']) &&

30
Sistema de Vendas usando Pagseguro

(time() - $_SESSION['SS_ULTIMA_ATIVIDADE'] >


$this->session_expire_time ) ):
# Sessão expirada: destrói a sessão
$this->destroy();
endif;
endif;
# determinando a ultima atividade no sistema do usuário
$_SESSION['SS_ULTIMA_ATIVIDADE'] = time();
}

header( "Cache-control: private" ) – Essa linha de código indica que toda ou parte da
mensagem de resposta do servidor é destinada a um único usuário e não deve ser armazenada
em cache por um serviço de cache compartilhado, como um servidor proxy, por exemplo.

session_regenerate_id() – Em teoria! Atualiza o id da sessão atual com um novo id gerado a


cada refresh. Em teoria porque, na prática o PHP tem algumas dificuldades técnicas para
alcançar esse objetivo.

A única lógica empregada nessa classe se encontra na condição IF. Essa condição verifica
primeiro se o programador definiu um tempo de expiração para a sessão dos usuários, caso
positivo, então dentro da condição IF, verificamos se entre o momento da ultima atividade do
usuário no sistema e o momento atual, excedeu-se o tempo determinado na variável
$session_expire_time. Caso não tenha excedido, apenas atualizamos o momento em que o
usuário realizou a ultima atividade no sistema com a função do PHP time() . Já para os casos em
que um usuário está inativo a muito tempo no sistema e o tempo excede o limite, será
chamado o método da classe destroy() que irá limpar todos os dados desse usuário e destruir a
sessão dele.

Implementando Singleton - O método estático getInstance()


Como fora citado acima, a classe Session utiliza uma metodologia chamada Singleton. Dessa
forma, apenas uma única instância da classe permanece ativa durante a execução do sistema.
Isso se faz útil por não precisarmos de mais de um Objeto Session criado no sistema. Se
criarmos mais de uma session, isso causaria alguma confusão ao programador que em algum
momento não lembraria em qual dos objetos Session uma determinada informação está
gravada.

Session.class.php (continuação)
public static function getInstance( $expire_time = null ){
if(!isset(self::$instance))
self::$instance = new self( $expire_time );
return self::$instance;
}

31
Sistema de Vendas usando Pagseguro

Esse método é bem pequeno como os demais e não contém muita lógica de programação, ele
apenas verifica se o Objeto Session já foi criado, e para caso positivo, retorna-o. O ideal é
instanciar a classe Session através do comando Session::getInstance(); dessa
forma, esse método sempre verificará se a classe Session já foi instanciada e retornará sempre
o mesmo objeto.

Métodos Set e Get


Os próximos métodos apresentados servem apenas como assessores para obter e definir dados
da Classe Session. Esses métodos têm no máximo quatro linhas de código e não cabem uma
explicação profunda, pois eles por si só são auto explicativos.

Session.class.php (continuação)
public function setExpiretime($__value = null ){
if($__value != null)
$this->session_expire_time = $__value;
}

public function getExpiretime(){


return $this->session_expire_time ;
}

public function __set( $name, $value ){


$this->set($name,$value);
}

public function __get($name){


return $this->get($name);
}

public function set($__name, $__value){


$_SESSION[trim($__name)] = $__value;
}

public function get($__name = null){


if($__name == null) return null;
if(isset($_SESSION[trim($__name)]))
return $_SESSION[trim($__name)];
else
return null;
}

Note apenas nos métodos acima a presença de __set e __get que são conhecidos no jargão
PHP como métodos mágicos. Esses métodos permitem que você defina e obtenha variáveis das
sessões com comandos como os a seguir:

32
Sistema de Vendas usando Pagseguro

$session = Session::getInstance() ;
$empresa = $session -> empresa ;
$session -> empresa = “ABC Limitada” ;
echo $empresa ;

Excluindo variáveis de sessão ou destruindo a sessão


Por fim, temos dois métodos que nos permite excluir informações da sessão.
O primeiro é o método del($name), com ele podemos informar uma variável da sessão que
queremos excluir.
O segundo método, trata-se do destroy(). Esse método é usado para eliminar todos os dados da
sessão usando as funções do PHP session_destroy() e session_regenerate_id().

Session.class.php (continuação)
public function del($name){
unset($_SESSION[trim($name)]);
}

function destroy(){
$_SESSION = array();
session_destroy();
session_regenerate_id();
}
}

O Banco de Dados
O ideal em um software de vendas – ou qualquer outro tipo de software que necessite uma
base de dados – é a criação das tabelas que armazenarão as informações utilizando um Sistema
gerenciador de banco de dados, tal como MySQL, Oracle, SQL Server, etc.
Eu não vou ensinar nessa série de artigos como desenvolver o banco de dados e as tabelas. No
caso vou criar apenas uma simulação de banco de dados. Criando um banco de dados JSON
através de uma classe PHP estática. Farei isso para não prolongar de mais em assuntos que
fogem ao escopo desse documento.

A classe que controla o banco de dados será estática. Ficando presente durante toda a vida útil
do script. Afinal, não precisamos ter mais de 1 objeto gerenciador de base de dados
instanciado. E é melhor assim, pois evita conflito durante gravações. Imagine se dois objetos de
uma classe Database, tentassem abrir um arquivo ao mesmo tempo e gravar informações nele?

33
Sistema de Vendas usando Pagseguro

Descrição: Gerenciamento de um banco de dados em JSON


Localização: Pagseguro\database\Database.php

Construindo a Classe estática Database

Database.php
<?php

/**
* Classe Database
* ---------------
*
* Esta é uma implementação simples de um Banco de dados em
* Arquivos de TEXTO. Usado apenas para fins didaticos
* para acompanhar o artigo sobre uso da API do PAGSEGURO.
* Recomendo o uso dessa classe apenas para testes,
* em produção o ideal é a utilização de um SGBD como
* MySQL, SQL Server, ORACLE, etc.
*
* --------------------------
*
* @created 2017.04.22 18:44h
* @autor wanderlei santana <sans.pds@gmail.com>
*/
class Database
{
private static $ext = "" ;

/**
* Retornar o caminho completo para uma tabela no
* servidor Web.
*
* @access private
* @param string $__tablename - nome da Tabela
* @return string
*/
private static function dbfilepath( $__tablename = "tabela_a_carregar" ){
return dirname(__FILE__) .
DIRECTORY_SEPARATOR .

34
Sistema de Vendas usando Pagseguro

strtolower( $__tablename . Database::$ext );


}

/**
* Dado o nome de uma tabela JSON, retorna as informações
* contidas nessa tabela na forma de Array.
*
* @access public
* @param string $__tablename - nome da tabela
* @return Array
*/
public static function get( $__tablename ){
$__filepath = self::dbfilepath( $__tablename );
if(!file_exists($__filepath))
throw new Exception("Arquivo '$__filepath' não existe.", 1);
return json_decode(file_get_contents($__filepath ), true );
}

Na classe acima você pode ver dois métodos inicialmente. O primeiro, dbfilepath( ) serve para
obter o caminho absoluto das nossas tabelas JSON, já o segundo método get( ) é responsável
por retornar em forma de Array todos os dados encontrados dentro de uma tabela de dados
JSON.

Salvando dados em um arquivo JSON


No seu caso – que eu espero tenha optado por usar um banco de dados como MySQL –, esse
tópico descrever o método em que você recebe informações e as salva em uma tabela destino.

Como eu optei por criar um gerenciador de banco de dados JSON, existe uma pequena lógica
empregada no salvamento de dados, que prefiro demonstrar de uma forma visual através de
um diagrama de blocos para ficar bem claro. Em resumo, queremos gravar um Array de dados
dentro de uma tabela, porém, precisamos considerar algumas possibilidades de erros e
evita-las. Por exemplo:

 A tabela existe?
 A tabela já tem registros?
 O usuário definiu um ID que ele quer que seja o INDICE do registro?
 O índice definido pelo usuário já existe?

Precisamos tomar cuidado para que ao gravar uma informação, outra já existente
não seja sobrescrita.
Abaixo, exemplo de um diagrama de blocos com a lógica empregada para fazer o salvamento
das informações em um arquivo JSON.

35
Sistema de Vendas usando Pagseguro

36
Sistema de Vendas usando Pagseguro

Database.php( continuação )
public static function save( $__tablename, $_dados = array() ){
$_tabela = Database::get( $__tablename ) ;
if($_tabela == null) $_tabela = array();

# verificando pela existencia de uma ID


# Se existir sera a Key para o Array
if(isset($_dados['id'])){
$index = $_dados['id'];
}else{
$index = null;
$tmp = count($_tabela) + 1;
while($index == null){
$index = (!isset($_tabela[$tmp])) ? $tmp : null;
$tmp++;}}

$_tabela[$index] = $_dados ;
file_put_contents(
self::dbfilepath( $__tablename ), json_encode($_tabela) );
return $index;
}

Atualizando e Removendo registros


O índice criado anteriormente e tão explicado é importante nesse ponto para a atualização de
registros. Através do INDICE podemos identificar um registro entre muitos a ser atualizado.

Database.php( continuação )
public static function update(
$__tablename,
$__key = 0,
$_dados = array() )
{
$_tabela = Database::get( $__tablename ) ;
if($_tabela == null) return false;
$_registro = (isset($_tabela[$__key]) &&
is_array($_tabela[$__key])) ? $_tabela[$__key] : null;
if($_registro == null) return false;
foreach ($_dados as $key => $value) $_registro[$key] = $value;
$_tabela[$__key] = $_registro ;
return file_put_contents(
self::dbfilepath( $__tablename ), json_encode($_tabela) );
}

public static function remove( $__tablename, $__key = 0){


$_tabela = Database::get( $__tablename ) ;
unset($_tabela[$__key]);
return file_put_contents(
self::dbfilepath( $__tablename ),
json_encode($_tabela) );
}
}

37
Sistema de Vendas usando Pagseguro

O método remove() como o próprio nome diz, serve para excluir um registro. Basta passar
como parâmetro o nome da Tabela e o Índice que deve ser removido.
Isso finaliza o banco de dados JSON. Para gravar uma informação nesse nosso banco de dados
hipotético basta proceder da seguinte maneira.
1. Criar um arquivo vazio na pasta database. Ex: database/minha_tabela
2. Emitir os comandos abaixo para manipular a tabela:

# declarando um array de dados


$_dados = array( ‘id’ => 10, ‘nome’ => ‘Socrates’, ‘email’ => ‘scrs@gmail.com’);

# salva um array de dados


$__id = Database::save( ‘minha_tabela’, $_dados );

# atualiza um registro
$_dados[‘email’] = ‘socrates@outlook.com’ ;
Database::update( ‘minha_tabela’, $__id , $_dados );

# remove um registro
Database::remove( $__id );

Banco de Dados: Tabelas Produtos


Se você esta desenvolvendo um grande banco de dados para um sistema de vendas, o ideal é
que use uma estrutura de tabelas bem elaborada como esse exemplo que lhe apresento na
imagem abaixo:

38
Sistema de Vendas usando Pagseguro

A estrutura acima é um exemplo e pode lhe dar um norte para criar uma complexa estrutura e
armazenas as informações sobre seus produtos. Eu não vou explica-la nem implanta-la no
sistema, pois não é foco desse material. Mas, sinta-se a vontade para usa-la como quiser.

Agora continuando com o banco de dados hipotético que é foco desse pequeno sistema
exemplo. As tabelas são criadas em JSON. Tudo que precisamos no momento é criar um arquivo
vazio dentro da pasta database. No meu caso, o arquivo se chama produtos e fica localizado
em:
Descrição:Nossa tabela hipotética de Produtos
C:\wamp\www\Pagseguro\database\produtos

Nesse arquivo você vai inserir as seguintes informações:

39
Sistema de Vendas usando Pagseguro

Arquivo: produtos

{"31":{"id":31,"titulo":"iPhone 7 Plus 128GB Vermelho","desc":"Celular iPhone 7 Plus com


128GB de m\u00e9moria interna, Cor\r\n\t\t\t Vermelho Tela Retina HD 5,5\" 3D Touch
C\u00e2mera Dupla de 12MP -
Apple","preco":"4049.99","img":"assets\/images\/Como-criar-um-sistema-de-vendas-Pagsegur
o-iphone-7-foto-exemplo.jpg","modelo":"Vermelho","modelo_titulo":"7
Plus","peso":700},"33":{"id":33,"titulo":"Microsoft Office 365 Home","desc":"Software
Microsoft Office 365 Home: 5 Licen\u00e7as (PC, Mac, Android e IOS)\r\n\t\t\t e ainda mais 1
TB de HD virtual para cada licen\u00e7a
adiquirida","preco":"119.99","img":"assets\/images\/Criando um sistema de vendas com
Pagseguro - Microsoft Office 365 Home.png","modelo":"Home","modelo_titulo":"Office
365","peso":700},"35":{"id":35,"titulo":"Toca Discos Ctx Sonata","desc":"Um belo Toca Discos
Ctx Sonata Com Cd, R\u00e1dio Fm, Usb, Cart\u00e3o De\r\n\t\t\t Mem\u00f3ria, Entrada E
Sa\u00edda Auxiliar com estrutura externa feita em
madeira.","preco":"761.22","img":"assets\/images\/Criando um sistema de vendas com
Pagseguro - Toca Discos Ctx Sonata.jpg","modelo":"CTX","modelo_titulo":"Toca Discos
Sonata","peso":3000}}

As informações acima estão escritas em JSON e referem-se a 3 produtos. Isso bastará para o
nosso teste com o Pagseguro.

Banco de Dados: Tabela Usuários


A tabela usuário é a responsável por guardar as informações dos seus clientes. Crie a tabela
usuários dentro da pasta database. No meu caso ela tem o endereço:
C:\wamp\www\Pagseguro\database\usuarios
Insira o seguinte valor dentro do arquivo.

{"10001":{"id":10001,"nome":"Wanderlei","sobrenome":"Santana do
Nascimento","email":"sans.pds@gmail.com","cpf":"34208236587","fone":"987554321","fone_
cod":"98","endereco":{"endereco":"Rua
Hipotetica","numero":"4530","bairro":"Pereque","cidade":"Ilhabela","estado":"SP","cep":"1163
0000","referencia":"Proximo ao Mercado Hipotetico"}}}

40
Sistema de Vendas usando Pagseguro

Banco de Dados: Tabela Vendas


A tabela de vendas armazena informações sobre venda realizada ao cliente. Normalmente são
informações para identificar o Cliente, a data da venda, forma de pagamento, status, forma de
envio, valor total, etc. Para esta basta criar um arquivo vazio chamado vendas. Em meu caso:
C:\wamp\www\Pagseguro\database\vendas

Banco de Dados: Tabela Itens de Vendas


Para manter salvo as informações sobre cada um dos produtos que é vendido, usamos uma
tabela chamada vendas_item. Crie ela em seu sistema. No meu caso ficará:
C:\wamp\www\Pagseguro\database\vendas_itens

CRIANDO A PÁGINA DE PRODUTOS


A página de produtos será responsável por listar todos os produtos cadastrados no banco de
dados e também será responsável por processar as solicitações de compra do Cliente.
Lembre-se que em seu sistema você deve considerar também:
 Criar uma página para exibir os detalhes dos Produtos;
 Considerar a quantidade de produtos em Estoque;
 Criar opções de filtro para pesquisar produtos;

Nossa página final de Produtos deve ficar da seguinte forma:

41
Sistema de Vendas usando Pagseguro

Para facilitar o trabalho e reaproveitar código as páginas do Front-End são Divididas em três
partes, sendo: Cabeçalho (frontend_header.php), Conteúdo (produtos.php) e Rodapé
(frontend_footer.php).

C:\wamp\www\Pagseguro\produtos.php
C:\wamp\www\Pagseguro\frontend_header.php
C:\wamp\www\Pagseguro\frontend_footer.php

Frontend_header.php
<!doctype html>
<html lang="pt-br">
<head>
<meta charset="utf-8">

<title>Produtos para a Venda</title>


<meta name="description" content="Sistema de Vendas usando Pagseguro">
<meta name="author" content="Wanderlei Santana">

<link rel="stylesheet" type="text/css" href="assets/css/style.css">


</head>
<body>

<!-- nosso menu navegarional -->


<ul class="menu-top-opcoes">
<li><a href="produtos.php">Produtos</a></li>
<li><a href="carrinho.php">Carrinho</a></li>
<li><a href="finalizar_compra.php">Finalizar Compra</a></li>
</ul>

A página header acima guarda informações de CSS a ser inserido, Javascript e configura o
Cabeçalho HTML5 necessário em toda página Web. A demais, esta página cria um Menu
navegacional para que todas as páginas que a incluírem recebam também esse menu.

Frontend_footer.php
</body>
</html>

A página footer não requer muitos detalhes. Por convenção apenas fechamos as tags Body e
HTML. Você pode adicionar informações de Copyright se assim o desejar. Mas para um sistema
de exemplo, isso deve bastar.

Fluxograma interno da Página Produtos


O arquivo da página Produtos guarda uma lógica que cabe explicação aqui através de um
fluxograma.

42
Sistema de Vendas usando Pagseguro

Acima você pode ver a lógica empregada para processar a página Produtos e abaixo o código
desenvolvido na prática.

43
Sistema de Vendas usando Pagseguro

Obtendo e listando os Produtos


Começamos por desenvolver a parte responsável por controlar as funcionalidades da página.

Produtos.php
<?php

# BANCO DE DADOS DE PRODUTOS


# --------------------------
# Criando um array que guarda os Produtos
# Isto é a simulação de um Banco de dados Hipotético.
# Na vida real, você deve fazer essa consulta no banco de dados
# e obter os produtos a ser exibidos via MySQL, ORACLE, etc.
require_once 'database/database.php';

# @var Array – obtemos a lista de produtos de nosso banco


$_produtos = Database::get( 'produtos' );

# VERIFICANDO SOLICITAÇÔES
# ------------------------
# Quando o usuário clica no botão adicionar produto ao carrinho,
# essa página é encarregada de processar esse pedido.
# Para isso, ela verifica se a URL atual contém um parâmetro
# chamado "adicionar_ao_carrinho".
# Esse parâmetro, guarda o ID do produto.
# Você pode - e deve - implementar outro mecanismo de processo
# que melhor se enquadre na necessidade do seu sistema.
# No meu caso eu costumo fazer esses processos via jQuery/Ajax.
if( isset($_GET['adicionar_ao_carrinho']) &&
is_numeric($_GET['adicionar_ao_carrinho']) ):

# armazenando id do produto para facilitar manipulação


# aproveitamos para garantir que tenha apenas números.
# @var int -
$__pid = preg_replace( '/[^\d-]+/','', $_GET['adicionar_ao_carrinho'] ) ;

# quantidade de produtos esta na URL também


# @var int -
$__qtd = preg_replace( '/[^\d-]+/','', $_GET['qtd'] ) or 1;

# obtendo as informações do produto da sua base de dados


# @var Array -
$_produto = isset($_produtos[$__pid]) ? $_produtos[$__pid] : null ;

# verificando se realmente o produto foi encontrado


if( $_produto != null ){

# gera o array que sera gravado no carrinho de compras


# @var Array -
$_data = array(
'id' => $_produto['id'],
'qty' => $__qtd,

44
Sistema de Vendas usando Pagseguro

'price' => $_produto['preco'],


'name' => $_produto['titulo'],
'options' => array(
'modelo' => $_produto['modelo'],
'modelo_title' => $_produto['modelo_titulo'],
'peso' => $_produto['peso']
)
);

# solicitamos a inclusão do Objeto carrinho,


# ele nos permite gerenciar o carrinho de compras do cliente.
require_once 'classes/LIBVENDAS/Cart.class.php' ;
$carrinho = new LIBVENDAS\Cart ;

# a biblioteca carrinho, precisa de um parâmetro a mais


# para corrigir o problema om caracteres acentuados.
$carrinho->product_name_rules = '\d\D';

# adicionando o produto ao carrinho


$carrinho->insert( $_data );

# @var Array - guarda o resultado de um processamento


# do sistema.
$_message = array( 'success' => 1,
'message' => 'Produto adicionado ao Carrinho de Compras' );
}
else{
$_message = array( 'success' => 0,
'message' => 'Esse produto não foi encontrado.' );
}

endif;

?>

Por fim criamos a parte que apresenta o conteúdo HTML que deve ser retornado ao cliente.

Produtos.php (continuação)
<?php
# Incluindo o cabecalho da pagina html
include 'frontend_header.php'; ?>

<h2>Produtos</h2>

<?php
# ALERTA DO SISTEMA
# -------------------
# Verificando se ha alguma mensagem sobre produto
# adicionado ao carrinho de compras
if(isset($_message) && count($_message) > 0 )
echo
"<div class='sysvendas-alertar-{$_message['success']}'>
{$_message['message']}
</div>";
?>

45
Sistema de Vendas usando Pagseguro

<section class="lista-produtos">
<?php foreach ($_produtos as $_produto): ?>

<div class='produto'>
<div class='produto-imagem'>
<img src='<?=$_produto['img'];?>'>
</div>
<div class='produto-info'>
<h2><?=$_produto['titulo'];?></h2>
<p><?=$_produto['desc'];?></p>
<span>
R$<?=number_format(
$_produto['preco'], 2, ',', '.');?>
</span>
<a
href='?adicionar_ao_carrinho=<?=$_produto['id'];?>&qtd=1'
class='btn-add-carrinho'>
Adicionar ao Carrinho
</a>
</div>
</div>

<?php endforeach;?>
</section>

<?php include 'frontend_footer.php'; ?>

O Arquivo Style.css
Abaixo deixo o arquivo CSS completo para todo o sistema. Ele será adicionado por inteiro sem
muita explicação por não ser foco deste artigo.

Descrição: Estilo CSS


Localização: C:\wamp\www\Pagseguro\assets\css\style.css

Style.css
body{
font-family: "Source Sans Pro","HelveticaNeue","Helvetica Neue",sans-serif;
color: #666;
padding:10px 20px;
}
div.sysvendas-alertar-1,
div.sysvendas-alertar-0{padding: 10px;margin-bottom: 20px;}
div.sysvendas-alertar-1{background-color: #DFF0D4;color:#2C7635;
border-color: #D6E9C4;
}
div.sysvendas-alertar-0{
background-color: #F2DEDC;
color:#AC260D;
border-color: #EBCCCF;

46
Sistema de Vendas usando Pagseguro

}
a:focus, input:focus{outline: none;}
/* PAGINA: PRODUTOS.PHP */
section.lista-produtos{display:flex;flex-wrap:wrap;}
div.produto{
padding: 2%;
flex-grow: 1;
flex-basis: 16%;
display: block;
border: 3px solid #fff;
}
div.produto:hover{border: 3px solid #eee;}
div.produto-imagem img {max-width: 100%;}
div.produto-info {margin-top: auto;}
div.produto-info h2{
font-size: 17px;
line-height: 1.375;
}
div.produto-info p{font-size: 14px;}
div.produto-info span{
font-size: 18px;
display: block;
margin: 10px 0px;
}
div.produto-info a.btn-add-carrinho:link,
div.produto-info a.btn-add-carrinho:visited{
background-color: #7AB55C;
color:#fff;
text-decoration: none;
padding: 10px 20px;
display: block;
text-align: center;
border-radius: 3px;
}
div.produto-info a.btn-add-carrinho:hover{background-color: #6DAA4D;}
ul.menu-top-opcoes{list-style: none;margin:0;padding: 0;background-color:
#EDEFF0;font-size: 14px;}
ul.menu-top-opcoes li{display: inline;}
ul.menu-top-opcoes li a:link,
ul.menu-top-opcoes li a:visited{
text-decoration: none;
padding: 10px;
line-height: 36px;
color:#444444;
}
ul.menu-top-opcoes li a:hover{background-color: #7AB55C;color:#fff;}

/* PAGINA: CARRINHO.PHP */
table, th, td {border: 1px solid #D9D9D9; border-collapse: collapse;}
table.table-sysvendas-cart{
width: 100%;
background-color: #F2F2F2;
}
table.table-sysvendas-cart thead tr th{
background-color: #D9D9D9;
line-height: 36px;
font-size: 14px;

47
Sistema de Vendas usando Pagseguro

}
table.table-sysvendas-cart tbody tr{border-bottom: 1px solid #999999;}
table.table-sysvendas-cart tbody tr td{line-height: 30px;padding: 10px 20px;}
table.table-sysvendas-cart tbody tr td:last-child{text-align: center;}
table.table-sysvendas-cart tbody tr td a{text-decoration: none;color:#0077CF;}
table.table-sysvendas-cart tbody tr td a:hover{text-decoration: underline;}
table.table-sysvendas-cart tfoot{background-color: #D9D9D9;}
table.table-sysvendas-cart tfoot tr td{padding: 10px 20px;color:#000;}
table.table-sysvendas-cart tfoot tr td input{
border:none;
color:#0066CC;
font-size: 18px;
background-color: #D9D9D9;
cursor: pointer;

}
table.table-sysvendas-cart tfoot tr td input:hover{color:#FF4C00;}
div.div-fechar-pedido{text-align: center;}
input.btn-fc-enabled, input.btn-fc-disabled{
border:none;
padding: 15px 50px;
color:#fff;
text-transform: uppercase;
}
input.btn-fc-enabled{background-color: #559911;cursor: pointer;}
input.btn-fc-enabled:hover{background-color: #6FC717;}
input.btn-fc-disabled{background-color: #ccc;}
/* PAGINA: FINALIZAR_COMPRA.PHP */
h1{text-decoration: underline;}
table.sysv-confirmar-pedido{width: 100%;}
table.sysv-confirmar-pedido tr th{font-weight: bold;text-align: left;padding:10px;}
table.sysv-confirmar-pedido tr td{padding:10px;}
input.cartend{
background-color: #559911;
color:#fff;
border:none;
cursor: pointer;
padding: 15px 50px;
text-transform: uppercase;
}
input.cartend:hover{
background-color: #6FC717;
}
a.link-setar-forma-envio:link,a.link-setar-forma-envio:visited{
background-color: #7AB55C;
color:#fff;
text-decoration: none;
padding: 10px 20px;
width:200px;
text-align: center;
border-radius: 3px;
}
td.td-destaque{background-color: #F3F3F3;}

48
Sistema de Vendas usando Pagseguro

CRIANDO A PÁGINA CARRINHO DE


COMPRAS
A página carrinho de compras é necessária para permitir que o cliente possa ver os produtos
que já adquiriu e se assim desejar, possa atualizar o carrinho adicionando ou removendo os
produtos listados.

49
Sistema de Vendas usando Pagseguro

Fluxograma interno Carrinho de Compras

50
Sistema de Vendas usando Pagseguro

Visualizando e editando o Carrinho de Compras


Descrição: Carrinho de Compras
Localização: C:\wamp\www\Pagseguro\carrinho.php

Carrinho.php
<?php

# INICIALIZANDO OBJETO CART


# -------------------------
# adicionando a classe responsavel por gerenciar
# o carrinho de compras.
require_once 'classes/LIBVENDAS/Cart.class.php';
$carrinho = new LIBVENDAS\Cart;

# INICIALIZANDO SESSAO
# --------------------
# vamos fazer uso do objeto que manipula
# sessao. Logo, pegamos sua instancia que
# ja foi criada anteriormente pela classe
# Cart.
$session = LIBVENDAS\Session::getInstance();

# VERIFICANDO SOLICITACAO DE REMOÇÃO DE ITEM


# ------------------------------------------
# Verifica se o cliente solicitou a remoção
# de algum item do carrinho.
# A ação vem contida na URL.
if( isset($_GET['remover']) ):
$data = array( 'rowid' => $_GET['remover'], 'qty' => 0 );
$carrinho->update( $data );
endif;

# VERIFICANDO SOLICITACAO DE ATUALIZAÇÂO


# --------------------------------------
# Caso o cliente decida atualizar o numero
# de itens no carrinho, esse trecho de codigo
# é responsavel por processar os novos números.
if($_POST):
$data = array();
foreach( $_POST as $row )
$data[] = array('rowid'=> $row['rowid'],'qty' => $row['qty']);
$carrinho->update( $data );
endif;

# SETADNO O TIPO DE ENVIO DA ENCOMENDA


# ------------------------------------
# @var Array - Servicos de entrega disponiveis
$_servicos_de_entrega = array(
'999' => 'RETIRADA NA LOJA',

51
Sistema de Vendas usando Pagseguro

'1' => 'PAC',


'2' => 'SEDEX',
'3' => 'Não Especificado');

# O trecho abaixo verifica se o cliente escolheu


# a forma de envio da encomenta. SEDEX, PAC, etc.
if( isset($_GET['forma_envio']) ):

# @var int - codigo numerico do servico de entrega


$__cod_servico = preg_replace( '/[^\d-]+/','', $_GET['forma_envio'] ) ;

# verificando se servico solicitado existe


if(isset($_servicos_de_entrega[$__cod_servico])):
# o valor sera calculado pelo Pagseguro
$valor_envio = '0.00';

# grava dados na sessao do usuario


$session->set( 'dados_envio',
array(
'cod_servico' => $__cod_servico,
'forma_envio' => $_servicos_de_entrega[$__cod_servico],
'valor_envio' => $valor_envio ) );
endif;
endif;
?>

Acima o controle e processos PHP, abaixo View e exibição de processos HTML.

Carrinho.php (continuação)
<?php include 'frontend_header.php'; ?>

<h2>Carrinho de Compras</h2>

<section class="carrinho">
<?php
$i = 1;
$total_items = $carrinho->total_items();
if( $total_items > 0 ){ ?>

<!-- Container: Carrinho de compras -->


<div style="overflow-x:auto;">
<form action="<?=$_SERVER['PHP_SELF'];?>" method="post">
<table class="table-sysvendas-cart">
<thead>
<tr>
<th>Descrição</th>
<th>Qtd.</th>
<th>Preço</th>
<th>Sub-Total</th>
<th>Excluir</th>
</tr>
</thead>

<tbody>
<?php foreach ($carrinho->contents() as $items): ?>

52
Sistema de Vendas usando Pagseguro

<tr>
<td>
<input type="hidden" name="<?=$i;?>[rowid]"
value="<?=$items['rowid'];?>">
<?=$items['name']; ?> -
<?=$items['options']['modelo_title']; ?></td>
<td>
<input type="text" name="<?=$i.'[qty]';?>"
id="qtd" value="<?=$items['qty'];?>"
maxlength="2" size="5"
onkeypress="return event.charCode >= 48 && event.charCode
<= 57">
</td>
<td>
<?=$carrinho->format_number($items['price']); ?></td>
<td>
R$<?=$carrinho->format_number($items['subtotal']);?></td>
<td>
<a class="remove_item"
title="Excluir este item do carrinho de compras?"
href="?remover=<?=$items['rowid'];?>">remover</a>
</td>

</tr>
<?php $i++; endforeach; ?>
</tbody>
<tfoot>
<tr>
<td>
<input type="button" class="retcart"
value="continuar comprando"
onclick="javascript:window.location ='produtos.php';" />
</td>
<td>
<input type="submit" class="upcart" name=""
value="Atualizar Carrinho">
</td>
<td colspan="3">
<b>Total dos produtos:</b> R$<strong>
<?php
echo number_format( $carrinho->total(), 2, ',', '.' );
?>
</strong></td>
</tr>
</tfoot>
</table>
</form>
</div><!-- // tabela carrinho -->

<br>
<hr>

<div>
<h3> Escolha uma Forma de Envio </h3>
<p>
Escolha abaixo uma das formas de envio da mercadoria oferecido.
Essa informação será enviada ao Pagseguro para o devido calculo

53
Sistema de Vendas usando Pagseguro

de taxa de envio.
Você também pode retirar sua compra diretamente em nossa loja.
</p>
<?php
# verificando se ja setou a forma de envio
$_tmp = $session->dados_envio ;

foreach( $_servicos_de_entrega as $key => $value )


echo "<input type='radio'
onclick=\"javascript:window.location='?forma_envio={$key}';\"
name='forma_envio' value='{$value}'

".((isset($_tmp)&&$_tmp['forma_envio']==$value)?'checked':'').">{$value}
<br>";
?>
<p>
<strong>Nota:</strong>
O valor de envio será Calculado por Pagseguro no ato
do pagamento dos produtos.<br>
<strong>Nota:</strong> Selecione "<strong>Não especificado</strong>"
se quiser deicidir durante o pagamento no Pagseguro.<br>
</p>

</div>

<?php
# seta o botao de continuar
$__enabled = (isset( $_tmp )&&count($_tmp) > 0 ) ? 'enabled' : 'disabled' ;
?>

<br><hr><br>

<div class="div-fechar-pedido">
<input type="button" value="Finalizar Compra"
id="fechar_pedido" class="btn-fc-<?=$__enabled;?>"
onclick="javascript:window.location ='finalizar_compra.php';"
<?=$__enabled;?> />
</div>

<br>

<?php }else{ ?>

Você ainda não adicionou produtos ao carrinho de compras.

<?php } ?>

</section>

<?php include 'frontend_footer.php'; ?>

54
Sistema de Vendas usando Pagseguro

A PÁGINA DE CADASTRO DE USUÁRIOS


Não será desenvolvida a página de cadastro de usuário, uma vez que, o foco é apenas a
integração com o sistema do Pagseguro. Mas é ideal a criação de uma págia que permita ao
cliente se cadastrar no seus sistema e também que permita a ele realizar o login.

CRIANDO A PÁGINA FINALIZAR COMPRA


Uma vez que o cliente já tenha escolhido todos os itens que ele quer comprar, precisamos criar
uma página para permitir a ele finalizar a compra, verificando todos os itens adiquiridos,
detalhes de frete, login, cadastro e demais detalhes antes de poder enviar a compra para o
GATEWAY de Pagamento.

Descrição: Verifica e Finaliza a Compra


Localização: C:\wamp\www\Pagseguro\finalizar_compra.php

Finalizar_compra.php
<?php

require_once 'classes/LIBVENDAS/Cart.class.php';
$carrinho = new LIBVENDAS\Cart;
$session = LIBVENDAS\Session::getInstance();

# DADOS DO CLIENTE
# ----------------
# Uma vez que o foco deste codigo é demonstrar
# o uso da API do Pagseguro., não foi implementado
# um sistema de cadastro e login de usuários.
# Portanto, aqui eu uso um usuário hipotetico e
# estatico para preencher os dados que devem ser
# enviados ao Pagseguro.
# Em seu Código, você deve obter os dados do Cliente
# que esta realizando a compra aqui via SGBD.
require_once 'database/database.php' ;
$_tabela = Database::get( 'usuarios' ) ;

# pegando o primeiro cliente da tabela


$cliente = array_pop( $_tabela );

# convertemos array para um objeto afim de ficar mais intuitivo manipular os dados.
$cliente = json_decode(json_encode( $cliente ),FALSE) ;

# verificando se ja setou forma de envio


$_tmp = $session->dados_envio ;
$__forma_de_envio = isset($_tmp['forma_envio']) ?
$_tmp['forma_envio'] : 'Não Definido' ;

# seta o botao de continuar

55
Sistema de Vendas usando Pagseguro

$__enabled = (isset( $_tmp )&&count($_tmp) > 0 ) ? 'enabled' : 'disabled' ;

?>

Finalizar_compra.php (continuação)
<?php include 'frontend_header.php'; ?>

<h2>Finalizar Compra</h2>

<?php
# verificando se temos uma compra em andamento
# para este cliente.
$total_items = $carrinho->total_items();
( $total_items > 0 ) or die(
"Você ainda não adicionou produtos ao carrinho de compras." ); ?>

<h1>Confirmar Pedido: #97631 </h1>

<h3>Confirme os dados da sua Compra para Proseguir</h3>


<p>
Confira abaixo a descrição detalhada da sua compra.
Se tudo estiver correto, clique sobre o botão <b>Continuar</b> e
você será direcionado ao Site do Pagseguro para efetuar o
pagamento e calcular a taxa de envio para sua compra.
</p>

<h2>Descrição dos produtos </h2>

<table class="sysv-confirmar-pedido">
<thead>
<tr>
<th>Pedido</th>
<th>Qtd.</th>
<th>Preço</th>
<th>Sub-Total</th>
</tr>
</thead>

<tbody>
<?php foreach ($carrinho->contents() as $items): ?>
<tr>
<td>
<?php echo $items['name'] . " - " .
$items['options']['modelo_title']; ?>
</td>
<td><?=$items['qty']; ?></td>
<td><?php echo $carrinho->format_number($items['price']); ?></td>
<td>
R$<?php echo $carrinho->format_number($items['subtotal']);?>
</td>
</tr>
<?php endforeach; ?>

56
Sistema de Vendas usando Pagseguro

</tbody>

<tfoot>
<tr>
<td colspan="5"><h3>Detalhes da Venda </h3></td>
</tr>
<tr>
<td colspan="3"><strong>Valor dos produtos:</strong></td>
<td>
R$<?php echo $carrinho->format_number($carrinho->total()); ?>
</td>
</tr>
<tr>
<td colspan="3"><strong>Frete:</strong></td>
<td><b>Será calculado pelo Pagseguro</b></td>
</tr>
<tr>
<td colspan="3"><strong>Valor Total:</strong></td>
<td class="td-destaque"><b>R$
<?php echo $carrinho->format_number($carrinho->total()); ?>
+ Frete</b>
</td>
</tr>
<tr>
<td colspan="3"><strong>Forma de Envio:</strong></td>
<td class="td-destaque"><b><?=$__forma_de_envio;?></b></td>
</tr>
</tfoot>
</table>

<br>

<h1>Dados do Cliente</h1>

<?php
echo $cliente->nome . " " . $cliente->sobrenome . "<br>";
echo $cliente->email;
echo "<br>Documento : $cliente->cpf" ;

echo "<br>" ;

echo "<h2>Endereço de Entrega e Cobrança</h2>";


echo "<p><label>Endereço: </label> {$cliente->endereco->endereco} </p>";
echo "<p><label>Número: </label> {$cliente->endereco->numero} </p>";
echo "<p><label>Bairro: </label> {$cliente->endereco->bairro} </p>";
echo "<p><label>Cidade: </label> {$cliente->endereco->cidade} </p>";
echo "<p><label>Estado: </label> {$cliente->endereco->estado} </p>";
echo "<p><label>CEP: </label> {$cliente->endereco->cep} </p>";
echo "<p><label>Referência: </label> {$cliente->endereco->referencia} </p>";
?>

<br><hr /><br>

<form method="post" action="concluir_pedido.php" name="formas_de_pagamento">


<?php
# apresenta mensagem para que o cliente escolha a forma de envio
if( $__enabled == 'disabled' )

57
Sistema de Vendas usando Pagseguro

echo "Você não definiu qual a forma de Envio da sua compra. Por favor,
clique no link a seguir e selecione uma das
formas de envio disponíveis.
<a class='link-setar-forma-envio' href='carrinho.php'>
Forma de Envio</a><br><br><hr>";
?>

<p>
Ao clicar em <b>Continuar</b> você será direcionado
ao site do <b>Pagseguro</b> para efetuar o seu pagamento,
e também calcular os custos de envio da sua compra.
</p>

<center>
<input type="submit" class="btn-fc-<?=$__enabled;?>"
name="continuar" id="fechar_pedido"
value="Concluir" <?=$__enabled;?> />
</center>
</form>

<br>

<?php include 'frontend_footer.php'; ?>

PROCESSOS FINAIS DA VENDA E


INTEGRAÇÃO COM O PAGSEGURO DA UOL
Essa é a parte foco desse material que ensina como usar o gateway de pagamento Pagseguro
da UOL. Será um artigo extenso, visto que são obrigatórios muitos cuidados quanto se está
lidando com transações online. Eu prometo tentar não me estender muito nas explicações,
caso algo fique subentendido ou careça de mais explicações, por favor, entre em contato e
exponha as suas dúvidas. Então, vamos lá!

Identificando o Cliente
Se você esta acompanhando esta série de artigos desde o início, então, o arquivo que vamos
criar a seguir deve ser nomeado como concluir_pedidos.php. No meu caso esse arquivo se
localiza em:

Descrição: Concluir o Pedido e direciona cliente ao Pagseguro


Localização: C:\wamp\www\Pagseguro\concluir_pedido.php

58
Sistema de Vendas usando Pagseguro

Se você começou a ler a partir desse artigo, pois só precisa aprender a implantar o Pagseguro
em seu site, então o arquivo que se segue trata-se do arquivo responsável por finalizar a
compra de um cliente e remeter ele ao GATWAY de pagamento.

A primeira coisa logica a ser feita no script é obter as informações que identificam o Cliente, os
dados da compra e iniciam a base de dados. Pois assim, poderemos gravar uma nova venda no
banco de dados e associar ao cliente.

concluir_pedido.php
<?php
# AREA PARA DECLARAÇÃO DE FUNÇÕES UTEIS
# -------------------------------------
# base_url() obtem a URL principal do site
# @return string
function base_url() {
$pathInfo = pathinfo($_SERVER['PHP_SELF']);
$protocolo = strtolower(substr($_SERVER["SERVER_PROTOCOL"],0,5))
=='https://'?'https://':'http://';
return $protocolo.$_SERVER['HTTP_HOST'].$pathInfo['dirname']."/";
}

# INICIALIZANDO OBJETO CART


# -------------------------
require_once 'classes/LIBVENDAS/Cart.class.php';
$carrinho = new LIBVENDAS\Cart;

# INICIALIZANDO SESSAO
# --------------------
$session = LIBVENDAS\Session::getInstance();

# --------------------------------
# [1]. INICIANDO BANCO DE DADOS &
# --------------------------------
# [1.1] IDENTIFICANDO O CLIENTE
# --------------------------
# Obtendo novamente dados hipoteticos de
# um cliente logado no sistema.
# O ideal aqui, e' usar os dados da Sessão para
# identificar o cliente logado e obter todas as
# informações do banco de dados.
# Dados Gerais, endereços e etc.
require_once 'database/database.php' ;
$_tabela_clientes = Database::get( 'usuarios' ) ;

# pegando o primeiro cliente da tabela


$cliente = array_pop( $_tabela_clientes );

# convertemos array para um objeto afim de ficar mais intuitivo manipular os dados.
$cliente = json_decode(json_encode( $cliente ),FALSE) ;

# --------------------------
# [2]. CLIENTE ESTA LOGADO ?

59
Sistema de Vendas usando Pagseguro

# --------------------------
# Verifique aqui sempre se o usuario esta
# devidamente logado no sistema e tem sessão ativa.
# Caso não estiver, direcionar o cliente para
# a pagina de login ou cadastro.
$idcliente = $cliente -> id ;

if( ! $idcliente ){
# direcionar aqui usuario para a página de Login
exit;
}

A função base_url() existe apenas para pegar o endereço do site e o caminho para o arquivo
que o esta chamando.
Em seguida, requerimos a classe Cart.class.php pois ela gerencia todos os produtos comprados
pelo cliente através da classe de sessão (Session::getInstance()).

Na linha de código a seguir:


$cliente = array_pop( $_tabela_clientes );

Você deve obter as informações do cliente que está realizando a compra em seu site. Como
criei um pequeno site hipotético para apresentar o funcionamento do sistema do Pagseguro,
eu apenas obtenho um cliente qualquer de uma base de dados.

É importante verificar nesse ponto se o cliente está logado. Caso não estiver, então você
precisa redireciona-lo para uma página de login ou de cadastro dentro do seu site.

Gravando informações da Venda no banco de Dados


Alguns detalhes precisam ser adicionados à forma como as informações são gravadas no banco
de dados, uma vez que estamos usando o Pagseguro. Você precisa de um código que será
compartilhado entre você e o sistema da UOL para que possam identificar uma venda e saber
se ela foi ou não paga pelo cliente.
Partindo dessa premissa, é necessário que em seu banco de dados na tabela vendas exista uma
coluna chamada pscode que guarde uma chave alfanumérica com no mínimo 32 caracteres.

O Pscode é uma informação gerada pelo sistema do Pagseguro. Quando você envia os dados da
compra do cliente via XML, o Pagseguro retorna outro arquivo XML que contém a resposta a
essa solicitação e o número gerado para identificar a transação. Você deve pegar esse código e
gravá-lo dentro da tabela vendas na coluna pscode.

concluir_pedido.php (continuação)
# ----------------------------------------------
# [3]. GRAVANDO DADOS DA VENDA NO BANCO DE DADOS

60
Sistema de Vendas usando Pagseguro

# ----------------------------------------------
# Você deve ter uma tabela no seu banco de dados que
# guarda todos os dados referentes a venda. Nesse caso,
# o código abaixo visa gerar todos os dados necessarios
# para identificar essa venda no seu sistema.

# @var string - codigo para identificação dessa venda no sistema


# Aqui, gerando um codigo com 24 caracteres: "Ano atual + 20 caracteres"
# Esse Codigo servira de referencia para o Pagseguro identificar a
# sua Venda.
$key = date('Y') .
strtoupper(substr(str_shuffle(str_repeat(

$x='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
ceil(20/strlen($x)))),1,20));

# @var integer - Codigo numerico que identifica a forma de envio.


$forma_envio = $session->get( 'dados_envio' );

# idcliente - ID unica do cliente.


# key - Serve de referencia para o PagSeguro
# pscode - Codigo que o Pagseguro envia para identificar transação
# active - (opcional) informa que o registro esta ativo no Banco de dados
# forma_pagto - Definindo a forma de pagamento
# forma_envio - Determina a forma de envio da Mercadoria, PAC, SEDEX, etc;
# valor_envio - Sera definido no Pagseguro
# valor_total - Valor total da Venda
# status_venda - Status Padrão
$dados_venda = array(
'idcliente' => $idcliente,
'key' => $key,
'pscode' => null,
'active' => 1,
'forma_pagto' => 'Pagseguro',
'forma_envio' => ((!isset($forma_envio['cod_servico'])) ? '3' :
$forma_envio['cod_servico']), /* 3 indica que sera decidido no pagseguro */
'valor_envio' => '0.00',
'valor_total' => $carrinho->total(),
'status_venda' => 'Aguardando pagamento'
);

# salvando dados da venda no banco de dados...


# aqui, realize o processo de salvar os dados na sua tabela de vendas
$idvenda = Database::save( 'vendas', $dados_venda );

Note no código acima que além do pscode, também existe uma coluna na tabela de vendas
chamada Key. Essa coluna é necessária e serve como referência para identificar a venda
sempre que o Pagseguro envia uma mensagem de alteração no estatus da mesma. No caso eu
criei uma chave alfanumérica de 20 caracteres. Essa referência deve ser enviada ao Pagseguro,
pois no momento que o cliente pagar a compra, o sistema do Pagseguro usa esse código de
referência para informar que essa venda em especifico foi quitada, ou teve seu status alterado.

61
Sistema de Vendas usando Pagseguro

Gravando informações dos Itens da Venda no banco


Note que a tabela de vendas só serve para armazenar informações como data, forma de
pagamento, forma de envio, id do cliente, e afins. Todo sistema de vendas precisa gravar
também informações sobre os produtos que foram vendidos. Essa tabela deve ser usada para
gravar as quantidades de produtos vendidos, seus valores e etc.

concluir_pedido.php (continuação)
# ----------------------------------------------
# [4]. GRAVANDO ITEMS DA VENDA NO BANCO DE DADOS
# ----------------------------------------------
# Esta é a parte em que você registra todos os itens vendidos
# na sua tabela de itens de venda.
$_produtos = array();
foreach ($carrinho->contents() as $items):

$total = $items['qty'] * $items['price'];


$item = array(
'idvenda' => $idvenda,
'item_id' => $items['id'],
'title' => $items['name'],
'modelo' => $items['options']['modelo'],
'modelo_title' => $items['options']['modelo_title'],
'qtd' => $items['qty'],
'preco' => $items['price'],
'total' => $total,
'peso' => $items['options']['peso']
);

$_produtos[] = $item;

endforeach;

# salvando os itens vendidos no banco de dados


Database::save( 'vendas_itens', $_produtos );

Nesse processo, tudo que fazemos é percorrer todos os produtos que estão no carrinho de
compras do cliente e gravar essas informações no banco de dados para garantir a permanência
das informações. Caso você se esqueça de gravar essas informações no banco de dados, elas
irão se perder com a sessão e possivelmente você não poderá criar um relatório sobre seu
estoque, ou sobre o total de itens vendidos, entre outras coisas.

Iniciando transação com Pagseguro: Gerando Arquivo XML


O primeiro passo para iniciar a transação com o Pagseguro é obter todos os dados de
configuração que serão necessários para a geração do arquivo XML que será enviado.

62
Sistema de Vendas usando Pagseguro

Nota: Aqui eu optei por criar uma Classe PHP vazia (stdClass) por achar mais pratico a
manipulação de dados, porém você pode usar seus dados através de array ou como preferir.

É importante que antes de prosseguir você possua um cadastro ativo no Pagseguro e as


credenciais que lhe identificam. No caso do Pagseguro as credenciais solicitadas são o E-mail
usado para o cadastro e Token do Cliente.

No código abaixo eu uso o e-mail e token hipotético, para fins de teste, trate de alterar essas
informações com os seus dados verdadeiros. Além de alterar também as demais informações
hipotéticas que eu utilizei para fins de exemplo.

concluir_pedido.php (continuação)
# --------------------------------------------------
# [5]. INICIANDO PROCESSO DE TRANSAÇÃO COM PAGSEGURO
# --------------------------------------------------
# Carregando os dados de Configurações
# setando as configuracoes necessarias para integração
$config = new stdClass;

# dados da sua empresa


$config -> empresa = 'SUA EMPRESA';
$config -> empresa_mail = 'email_contato_sua_empresa@suaempresa.com.br';
$config -> empresa_fone_01 = "12 4321-0987";
$config -> empresa_fone_02 = "12 7654-0987";
$config -> url_facebook = "javascript:void(0);" ;
$config -> url_blogger = "javascript:void(0);" ;
$config -> url_site = "javascript:void(0);" ;

# Email do responsavel pela criacao e manutencao da integracao ao pagseguro


$config -> dev_email = 'sans.pds@gmail.com';

# Credenciais hipoteticas para testes com Pagseguro


$config -> pagseguro_email = 'teste@lojaexemplo.com.br';
$config -> pagseguro_token = '2013VMY38LWO37WRE5DGR99SDFE4ER72';

# URL do Pagseguro a ser chamada com os dados da Venda


$config -> url = 'https://ws.pagseguro.uol.com.br/v2/checkout/?email=' . $config
-> pagseguro_email . '&token='.$config->pagseguro_token;

# construindo o arquivo XML a ser enviado ao Pagseguro.


# esse arquivo contem detalhes sobre a venda que são
# importantes para que o sistema do Pagseguro calcule
# corretamente os valores a serem pagos pelo cliente.
$xml = '<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
<checkout>
<currency>BRL</currency>
<redirectURL>' . base_url() . 'confirmacao.php</redirectURL>';

Note acima, na variável $xml, a tag redirectURL. O valor contido nela deve ser algo como:
http://nomedoseusite.com.br/confirmacao.php

63
Sistema de Vendas usando Pagseguro

Esse arquivo será construido logo mais. Trata-se de um arquivo simples HTML que é chamado
pelo Pagseguro quando o cliente pagar a compra. Esse arquivo serve apenas para informar ao
cliente que a compra dele foi realizada com sucesso.

Continuando com a geração do arquivo XML que será enviado ao Pagseguro, definimos agora
no arquivo as informações sobre os itens vendidos (id, titulo, peso, quantidade, peso) e
também as informações sobre o cliente (nome, fone).

concluir_pedido.php (continuação)
# Aqui, informamos ao pagseguro sobre os itens que foram vendidos.
# Enviando apenas algunas informações básicas.
$xml .= "<items>";
foreach( $_produtos as $produto ):
$xml .= "
<item>
<id>{$produto['item_id']}</id>
<description>" . utf8_decode( $produto['title'] ) . " - " . utf8_decode(
$produto['modelo_title'] ) . "</description>
<amount>{$produto['preco']}</amount>
<quantity>{$produto['qtd']}</quantity>
<weight>{$produto['peso']}</weight>
</item>";
endforeach;
$xml .= "</items>";

# Informando ao Pagseguro nossa Chave de Referencia da Venda


# Essa chave, serve para sabermos qual das nossas vendas
# O Pagseguro recebeu o pagamento.
$xml .= "<reference>$key</reference>";

# Nessa seção do arquivo XML precisamos informar


# os dados do Cliente que esta realizando a compra.
$xml .= "<sender>
<name>" . utf8_decode($cliente -> nome) . " " . utf8_decode($cliente ->
sobrenome) . "</name>
<email>$cliente->email</email>";

# Setando informação sobre telefone


# O pagseguro exige que os sejam enviados apenas numeros de
# telefones sem pontos ou traços.
$__fone = trim( preg_replace( "/[^0-9]+/i", "", $cliente -> fone ) );
$__fone_cod = trim( preg_replace( "/[^0-9]+/i", "", $cliente -> fone_cod )
);

if(isset($__fone)){
$xml .="<phone>
<areaCode>$__fone_cod</areaCode>
<number>$__fone</number>
</phone>";
}
$xml .= "</sender>";

64
Sistema de Vendas usando Pagseguro

Repare acima a presença da chave que criamos e gravamos no banco de dados – $key – dentro
da tag reference. Como dito anteriormente, ela servirá para identificar a nossa venda no
Pagseguro.

Abaixo, definimos a forma de pagamento e tomamos algumas precauções para validar os dados
que serão enviados ao Pagseguro.

Nota: lembre-se que é muito comum em um site de vendas, o cliente ter a opção de definir o
endereço de entrega e o endereço de cobrança. Se esse for o seu caso, você deve inserir
condições para satisfazer essa opção, informando isso ao Pagseguro.

concluir_pedido.php (continuação)
# setando tipo de envio Sedex(2), pac(1) ou retirada na loja(999), ou nao
especificado(3)
$__cod_envio = $forma_envio['cod_servico'];

# Se a forma de envio foi definida como "retirada na loja (999)"


# entao nao precisamos mandar os dados de endereço do cliente ao pagseguro
if( $__cod_envio != '999' ){

# retira caracteres não numericos do cep


$__cep = trim( preg_replace( "/[^0-9]+/i", "", $cliente->endereco->cep ) );
$__state = strtoupper( $cliente->endereco->estado );
$__complement = substr( $cliente->endereco->referencia,0, 35 );

# setando o XML com dados de Endereço do Cliente


# para o correto calculo dos dados de venda.
$xml .= "<shipping>
<type>$__cod_envio</type>
<address>
<street>" . utf8_decode($cliente->endereco->endereco). "</street>
<number>{$cliente->endereco->numero}</number>
<complement>" . utf8_decode($__complement) . "</complement>
<district>" . utf8_decode($cliente->endereco->bairro)."</district>
<postalCode>{$__cep}</postalCode>
<city>" . utf8_decode($cliente->endereco->cidade) . "</city>
<state>{$__state}</state>
<country>BRA</country>
</address>
</shipping>";
}

# Concluindo e fechando o arquivo XML


$xml .= "</checkout>";

Isso conclui a geração do arquivo XML que deve ser enviado ao Pagseguro.

65
Sistema de Vendas usando Pagseguro

Rotinas de Auditoria
Como você está manipulando informações sensíveis e vitais para a realização com sucesso de
uma operação de venda, é ideal que você possa realizar uma auditória para o caso de ocorrer
erros ou o caso de uma anomalia vir a afetar as vendas. Por exemplo, os desenvolvedores do
Pagseguro podem alterar uma mecânica do sistema em algum momento e passar a considerar
o arquivo XML que você envia como sendo inválido. Portanto, grave a todos os processos de
comunicação com o sistema de pagamentos em arquivos de log ou então no banco de dados
que estiveres a usar.

Aqui eu criei uma pasta chamada Logs, que já foi referida anteriormente. E vou gravar nessa
pasta o arquivo XML que acabei de gerar. É muito importante que ninguém tenha acesso a essa
pasta e aos arquivos dela. Se você optar por gravar arquivos de logs em seu servidor, dentro da
pasta crie um arquivo .htaccess com a linha de código:
Deny from all

Isso impedirá as pessoas de ter acesso à pasta e aos arquivos.

concluir_pedido.php (continuação)
# AUDITORIA
# ---------
# Existem momentos em que é necessario fazer auditoria
# dos dados enviados ao pagseguro. Portanto, a linha
# abaixo, tem o objetivo de registrar um log da venda
# efetuada.
# [!IMPORTANTE]: Caso opte por fazer o log desse XML
# tenha certeza de armazena-lo num local privado no
# seu servidor para evitar acesso não autorizado.
$__filepath = getcwd() . DIRECTORY_SEPARATOR . 'logs' . DIRECTORY_SEPARATOR .
strtolower( "ps_{$idvenda}_" );
file_put_contents( $__filepath, $xml ) ;

Enviando XML ao Pagseguro


Para enviar o arquivo XML ao sistema do Pagseguro basta utilizar as funções CURL do PHP.
O código abaixo realiza esse envio e irá receber a resposta do sistema do Pagseguro dentro da
variável chamada $xml .

Após o envio, voltamos a realizar um processo de auditoria, que é gravar em log o resultado do
xml retornado do Pagseguro. O arquivo de log será nomeado como rs_{id_da_venda}_ . Dessa

66
Sistema de Vendas usando Pagseguro

forma, caso ocorra um erro com uma venda em especifico você pode verificar o que informa o
arquivo de log para aquela venda.

concluir_pedido.php (continuação)
# -------------------------------------------
# [6]. FAZENDO REQUISIÇÃO A API DO PAGSEGURO
# -------------------------------------------
# Essa seção do codigo usa a tecnologia CURL
# para fazer um POST dos dados no serviço do Pagseguro.
$curl = curl_init( $config -> url );
# configuurando curl para nao verificar certificados ssl
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
# avisando ao curl para retornar a resposta do pagseguro
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
# informando ao curl o tipo de dado a ser transportado
curl_setopt($curl, CURLOPT_HTTPHEADER,
Array('Content-Type: application/xml; charset=ISO-8859-1'));
# setando o xml a ser transportado pelo CURL
curl_setopt($curl, CURLOPT_POSTFIELDS, $xml);
# exeutando o CURL e recebendo resposta do pagseguro
$xml = curl_exec( $curl );

# AUDITORIA
# ---------
# Quando fizermos um post com CURL
# o Pagseguro nos retornará um XML de resposta
# que iremos registrar tambem no servidor.
$__filepath = getcwd() . DIRECTORY_SEPARATOR . 'logs'.
DIRECTORY_SEPARATOR . strtolower( "rs_{$idvenda}_" );
file_put_contents( $__filepath, $xml ) ;

O arquivo XML de retorno do Pagseguro


Quando você envia o arquivo XML ao Pagseguro com as informações da compra de um cliente,
você pode obter dois resultados. Sendo um sucesso e outro erro.
No caso de sucesso ao enviar o arquivo xml com os dados da venda, o Pagseguro irá retornar
para você um arquivo parecido com o seguinte:

Exemplo de Sucesso. Arquivo de Retorno do Pagseguro em caso de sucesso.


<?xml version="1.0" encoding="ISO-8859-1"?>
<checkout>
<code>8CF4BE7DCECEF0F004A6DFA0A8243412</code>
<date>2010-12-02T10:11:28.000-02:00</date>
</checkout>

67
Sistema de Vendas usando Pagseguro

Observe no caso acima, que o Pagseguro retornou um xml com uma tag chamada code. O valor
desta tag refere-se ao Pscode que foi citado anteriormente e o qual teve uma coluna criada na
tabela vendas do banco de dados.

Exemplo de Erro. Caso algum parametro seja invalido, o XML devera ser algo como:
<?xml version="1.0" encoding="UTF-8"?>
<errors>
<error>
<code>11004</code>
<message>Currency is required.</message>
</error>
<error>
<code>11005</code>
<message>Currency invalid value: 100</message>
</error>
</errors>

Caso aconteça algum erro no processo de transação com o Pagseguro, o ideal é que o cliente
seja direcionado para uma página informando o erro, ou então, que esse erro seja enviado ao
programador responsável pelo sistema via e-mail.

Verificação e tratamento de Erros


A seguir estamos verificando se ocorreu erro ao tentar realizar a transação com o Pagseguro.
Fazemos isso analisando o arquivo de retorno XML.

concluir_pedido.php (continuação)
# VERIFICAÇÃO DE ERRO 01
# ----------------------
# unalthorized indica um erro com token ou email
if($xml == 'Unauthorized'){
# Insira seu código avisando que o sistema está com problemas,
# sugiro enviar um e-mail avisando para alguém fazer a manutenção
# redireciona usuario para uma pagina que indica o erro com a venda
# pode ser interessante desfazer a venda nesse caso
header( 'Location:' . base_url() . 'paginadeerro.php' );
exit; # Matando o processo
}

# fechando o CURL
curl_close( $curl );

# transformando o XML recebido em um objeto


$xml = simplexml_load_string( $xml );

68
Sistema de Vendas usando Pagseguro

# VERIFICAÇÃO DE ERRO 02
# ----------------------
if(count($xml->error) > 0){
# Insira seu código avisando que o sistema está com problemas,
# sugiro enviar um e-mail avisando para o desenvolvedor,
# talvez seja útil enviar os códigos de erros.
# carregando dados de configuracao do pagseguro
# redirecionando cliente a pagina de erros
header( 'Location:' . base_url() . "paginadeerro.php?error=" . $xml->error->code
);
exit;//Mantenha essa linha
}

Note acima a presença de um comando header. Ele ira direcionar o cliente para uma página
chamada paginadeerro.php . Essa página deve ser criada para apresentar os possíveis erros que
aconteceram durante a transação com o Pagseguro.

Informando Cliente via E-mail sobre Compra realizada com


sucesso
Se a comunicação com o Pagseguro ocorreu com sucesso, então foi retornado um arquivo xml
com o código da transação. Portando devemos salvar esse código na tabela de vendas.

concluir_pedido.php (continuação)
# se nao ocorreu erro guarda codigo de transacao na tabela de vendas
Database::update( "vendas", $idvenda, array( 'pscode' => $xml->code ) );

Abaixo, realizamos o processo de enviar um e-mail ao cliente informado o sucesso no registro


da sua compra que está apenas esperando ser paga através do sistema do Pagseguro. Nós
vamos criar essa página logo mais com uma lista de todos os códigos de erro do Pagseguro.

Eu criei um arquivo chamado email_template.html para facilitar a padronização do envio de


mensagens. Se você abrir esse arquivo em seu navegador verá algo como na imagem a seguir:

69
Sistema de Vendas usando Pagseguro

Usaremos a função str_replace do PHP para trocar as hashtags por informações que são
definidas no arquivo concluir_pedido.php .

Não colocarei o código do arquivo Template aqui, por ser extenso e não ser crucial ao
funcionamento da página concluir_pedido. Você pode baixar o arquivo através do link:
http://sooho.com.br/resources/email_template.html
Basta acessar essa página, Segurar a tecla CTRL e pressionar U. Copiar todo o código e salvar.

Abaixo, segue o código responsável por carregar o arquivo de Template, definir as mensagens e
enviar definitivamente o e-mail ao endereço do cliente.

concluir_pedido.php (continuação)
# -----------------------------------------
# [7]. ENVIANDO EMAIL DE SUCESSO NA COMPRA
# -----------------------------------------
# O codigo abaixo visa informar o cliente de
# que a compra dele foi registrada com sucesso.
#

70
Sistema de Vendas usando Pagseguro

$assunto = "Confirmação de Pedido";


$titulo = " ";
$nome_destinatario = "$cliente -> nome $cliente->sbnome";

$resumo =
"Esse e-mail visa informar que registramos sua compra com sucesso em nosso sistema.
Obrigado por Comprar conosco da {$config->empresa}!";

$conteudo = "- Seu pedido será postado imediatamente após a compensação de pagamento.
<br />
- Para pagamento por Depósito ou Transferência o comprovante deve ser enviado
para <b>{$config->empresa_mail}</b> ou através do seu Painel de Controles.<br /><br
/>

Os produtos são reservados até a data de vencimento do seu pedido.<br /><br />

No dia da postagem, será enviado um email automático com o número de registro


de sua entrega, juntamente com um link, para que você possa acompanhar a entrega.
As informações de rastreamento serão visualizadas após às 19h.<br /><br />
- Para exclarecer qualquer dúvida entre em contato conosco através de um dos
meio de comunicação que seguem abaixo.";

$nota = "Para acompanhar o andamento de sua compra, você pode utilizar seu
Painel de Controles <a href='".base_url()."cliente/login'>clicando aqui</a>.";

$unsubscribe = base_url() . "main/unsubscribe";


$termos = base_url() . "termos-de-uso";
$privaciade = base_url() . "politica-de-privacidade";

$tpl = file_get_contents( "email_template.html" );

$tpl = str_replace( "#nome_da_empresa#", $config -> empresa, $tpl );


$tpl = str_replace( "#title#", $titulo, $tpl );
$tpl = str_replace( "#codigo#", $key, $tpl );
$tpl = str_replace( "#resumo#", $resumo, $tpl );
$tpl = str_replace( "#conteudo#", $conteudo, $tpl );
$tpl = str_replace( "#nota#", $nota, $tpl );
$tpl = str_replace( "#fone_01#", $config -> empresa_fone_01, $tpl );
$tpl = str_replace( "#fone_02#", $config -> empresa_fone_02, $tpl );
$tpl = str_replace( "#email#", $config -> empresa_mail, $tpl );

$tpl = str_replace( "#endereco_facebook#", $config -> url_facebook, $tpl );


$tpl = str_replace( "#endereco_blogger#", $config -> url_blogger, $tpl );
$tpl = str_replace( "#endereco_site#", $config -> url_site, $tpl );

$tpl = str_replace( "#nome_destinatario#", $nome_destinatario, $tpl );


$tpl = str_replace( "#lnk_unsubscribe#", $unsubscribe, $tpl );
$tpl = str_replace( "#lnk_privacidade#", $privaciade, $tpl );
$tpl = str_replace( "#lnk_termos#", $termos, $tpl );

# envia o email para o cliente avisando da confirmacao do pedido


$__headers = "MIME-Version: 1.1" . "\n";
$__headers .= "Content-type: text/html; charset=UTF-8" . "\n";
$__headers .= 'From: <'.$config -> empresa_mail.'>' . "\n";
$__headers .= 'Cc: '. $config -> empresa_mail . "\n";

71
Sistema de Vendas usando Pagseguro

if( ! mail( $cliente -> email, $assunto, $tpl, $__headers ,"-r".$config ->
empresa_mail ) ){
$__headers .= "Return-Path: " . $config -> empresa_mail . "\n";
mail($cliente -> email, $assunto, $tpl, $__headers );
}

Caso você venha a usar o código acima descrito para envio de e-mail ao cliente, lembre-se de
alterar as informações para que se adequem as suas necessidades.

Direcionando Cliente para o Pagseguro


Por fim, direcionamos o Cliente para que ele possa pagar a compra no Pagseguro.
Aproveitamos também para limpar os recursos usados durante a compra destruindo as
informações contidas no carrinho de compras.

concluir_pedido.php (continuação)
# -----------------------------------------------
# [8]. FINALIZANDO PROCESSOS E LIMPANDO RECURSOS
# -----------------------------------------------
# limpando carrinho de compras
$carrinho->destroy();

# se esta OK, entao redireciona comprador para o pagseguro


# para realizar o pagamento da compra
redirect( ‘https://pagseguro.uol.com.br/v2/checkout/payment.html?code=’ .
$xml->code, 'refresh' );

Isso concluiu a explicação sobre como realizar uma venda com o Pagseguro. Nos próximos
tópicos vamos tratar de alguns assuntos muito importantes como a criação de uma página de
erros e também a página que recebe as notificações do Pagseguro e muda o status de uma
venda.

CRIANDO UMA PÁGINA DE ERROS


No tópico anterior, definimos uma condição onde: Caso o Pagseguro nos retorne algum erro
através de seu arquivo de retorno XML, o cliente deve ser direcionado para uma página de
erros. Portanto, agora vamos construir essa página de erros.

Descrição: Pagina de Exibição de Erros


Localização: C:\wamp\www\Pagseguro\paginadeerro.php

Será uma página simplória que servirá de base aos seus projetos.

72
Sistema de Vendas usando Pagseguro

Primeiro vamos definir todas as possibilidades de erro do Pagseguro em um Array.

paginadeerro.php
<?php
$_status_pagseguro = array(
10001 => 'Email is required.',
10002 => 'Token is required.',
10003 => 'Email invalid value.',
11001 => 'receiverEmail is required.',
11002 => 'receiverEmail invalid length: {0}.',
11003 => 'receiverEmail invalid value.',
11004 => 'Currency is required.',
11005 => 'Currency invalid value: {0}',
11006 => 'redirectURL invalid length: {0}',
11007 => 'redirectURL invalid value: {0}',
11008 => 'reference invalid length: {0}',
11009 => 'senderEmail invalid length: {0}',
11010 => 'senderEmail invalid value: {0}',
11011 => 'senderName invalid length: {0}',
11012 => 'senderName invalid value: {0}',
11013 => 'senderAreaCode invalid value: {0}',
11014 => 'senderPhone invalid value: {0}',
11015 => 'ShippingType is required.',
11016 => 'shippingType invalid type: {0}',
11017 => 'shippingPostalCode invalid Value: {0}',
11018 => 'shippingAddressStreet invalid length: {0}',
11019 => 'shippingAddressNumber invalid length: {0}',
11020 => 'shippingAddressComplement invalid length: {0}',
11021 => 'shippingAddressDistrict invalid length: {0}',
11022 => 'shippingAddressCity invalid length: {0}',
11023 => 'shippingAddressState invalid value: {0}, must
fit the pattern: \w\{2\} (e. g. "SP")',
11024 => 'Itens invalid quantity.',
11025 => 'Item Id is required.',
11026 => 'Item quantity is required.',
11027 => 'Item quantity out of range: {0}',
11028 => 'Item amount is required. (e.g. "12.00")',
11029 => 'Item amount invalid pattern: {0}. Must fit the patern: \d+.\d\{2\}',
11030 => 'Item amount out of range: {0}',
11031 => 'Item shippingCost invalid pattern: {0}.
Must fit the patern: \d+.\d\{2\}',
11032 => 'Item shippingCost out of range: {0}',
11033 => 'Item description is required.',
11034 => 'Item description invalid length: {0}',
11035 => 'Item weight invalid Value: {0}',
11036 => 'Extra amount invalid pattern: {0}. Must fit the patern: -?\d+.\d\{2\}',
11037 => 'Extra amount out of range: {0}',
11038 => 'Invalid receiver for checkout: {0}, verify receiver\'s account status.',
11039 => 'Malformed request XML: {0}.',
11040 => 'maxAge invalid pattern: {0}. Must fit the patern: \d+',
11041 => 'maxAge out of range: {0}',
11042 => 'maxUses invalid pattern: {0}. Must fit the patern: \d+',
11043 => 'maxUses out of range.',
11044 => 'initialDate is required.',
11045 => 'initialDate must be lower than allowed limit.',

73
Sistema de Vendas usando Pagseguro

11046 => 'initialDate must not be older than 6 months.',


11047 => 'initialDate must be lower than or equal finalDate.',
11048 => 'search interval must be lower than or equal 30 days.',
11049 => 'finalDate must be lower than allowed limit.',
11050 => 'initialDate invalid format, use
\'yyyy-MM-ddTHH:mm\' (eg. 2010-01-27T17:25).',
11051 => 'finalDate invalid format, use
\'yyyy-MM-ddTHH:mm\' (eg. 2010-01-27T17:25).',
11052 => 'page invalid value.',
11053 => 'maxPageResults invalid value (must be between 1 and 1000).',
11057 => 'senderCPF invalid value: {0}'
);
?>

Esses códigos numéricos se encontram no manual de uso da API do Pagseguro. Aqui eles foram
mantidos em sua versão original em idioma Inglês.
Abaixo finalizamos a página de erros reutilizando os arquivos criados para estruturar o layout de
todo o site. Nessa página o único código PHP existente usa a clausula $_GET para verificar se
existe um código numérico de erros sendo passado através da URL do site.

paginadeerro.php (continuação)
<?php include 'frontend_header.php'; ?>

<br />

<h2 class="pages-h2">Página de Erro</h2>

<h1> Problemas ao realizar a Compra </h1>

<h3>Ocorreu um erro durante o processamento de sua compra com o Pagseguro. </h3><br />

<b>Código do Erro</b><br />


<?php
if( isset($_GET['error']) ):
$cod = $_GET['error'];
$desc = isset($_status_pagseguro[$cod]) ? $_status_pagseguro[$cod] :
"Undefined";
echo "{$cod} - {$desc}";
else:
echo "0 - Unauthorized";
endif;
?>
<br />
<br />
<p>Para ajudar-nos a corrigir esse erro envie um e-mail para
<b>contato@nomesuadaempresa.com.br</b> informando como o erro aconteceu.</p>

<?php include 'frontend_footer.php'; ?>

74
Sistema de Vendas usando Pagseguro

CRIANDO UMA PÁGINA DE CONFIRMAÇÃO


DA COMPRA
A fim de manter a simplicidade do sistema, a página de Confirmação da Compra também é
simploria. Durante o envio do arquivo XML ao Pagseguro, nós informamos essa página para que
o cliente seja direcionado a ela quando finalizar o pagamento da compra.

Descrição: Pagina de Confirmação de Compra


Localização: C:\wamp\www\Pagseguro\confirmacao.php

confirmacao.php
<?php include 'frontend_header.php'; ?>

<br />

<h2>Confirmação</h2>

<h1>Compra Registrada com Sucesso</h1>

<h3>Sua compra foi registrada em nosso sistema com sucesso. </h3>


<p>
Agradecemos por realizar suas compras conosco!<br />
- Seus produtos serão enviados assim que <b> o seu pagamento</b>
for confirmado pelo Pagseguro.
Você <b>receberá uma mensagem de aviso</b> no *e-mail cadastrado em nosso site.
Caso tenha qualquer tipo de dúvida, sinta-se a vontade para entrar
em contato conosco através de um dos nossos Canais de comunicação.<br /><br />
Obrigado por sua confiança. <b>NOME DA EMPRESA</b>.
</p>

<p>
<i>* - Caso não receba mensagens em seu E-mail, verifique em sua caixa de span.</i>
</p>

<?php include 'frontend_footer.php'; ?>

75
Sistema de Vendas usando Pagseguro

INFORMANDO A PÁGINA DE NOTIFICAÇÃO


NO PAGSEGURO
Quando um cliente realiza uma compra no seu site e decide pagar através do Pagseguro você
não tem meios de saber se o cliente pagou a compra até que o Pagseguro lhe informe sobre
isso. E normalmente, o Pagseguro lhe informa que um cliente quitou uma compra através do
envio de Notificações.
Sendo assim, para utilizar a API de Notificações do Pagseguro você precisa primeiro informar o
endereço (URL) do seu sistema para o qual o PagSeguro enviará os códigos de notificação.
Isso pode ser feito na página de configurações do PagSeguro.
https://pagseguro.uol.com.br/integracao/notificacao-de-transacoes.jhtml

Por exemplo, para uma loja hospedada em http://sualoja.com.br, um endereço que poderia ser
configurado para o envio de notificações é http://sualoja.com.br/notificacao.php.

Recebendo uma notificação de transação


Uma vez configurado o endereço para onde o PagSeguro deve enviar as notificações, o próximo
passo é programar a página ou script para receber um código de notificação e processa-lo.

O PagSeguro envia as notificações para a URL que você configurou usando o protocolo HTTP,
pelo método POST.

CRIANDO UMA PÁGINA DE NOTIFICAÇÕES


“O fato de rodar não quer dizer que está correto.” – Essa era uma frase frequentemente
proferida por um ex-professor de lógica de programação onde estudei. E faz todo sentido. Hoje
em dia a maioria dos erros que vejo em programação não são relacionados a linguagem de
programação ou ao ambiente, mas sim a lógica empregada nos algoritmos. Portanto, se estais a
desenvolver um algoritimo trates de verificar e tratar o maior número de falha que possam vir a
ocorrer na lógica empregada – faça muitos testes. Afinal cada linha de código que você escreve
em uma linguagem de alto nível torna a possibilidade de erros proporcional a metodologia de
programação que está sendo empregada. Por exemplo, quando estou programando em
Assembly uma instrução programada tem 1 possibilidade de estar errado – pois 1 instrução

76
Sistema de Vendas usando Pagseguro

gera 1 ação –, já quando programamos em Java ou C# uma instrução programada pode gerar N
possibilidades de erro – pois 1 instrução em alto nível gera N ações. Ou como é costume dizer,
1 linha em código C equivale a 50 linhas em código Assembly.

Como funcionam as Notificações do Pagseguro


Dando continuidade ao último tópico dessa série, vamos confeccionar nosso script que recebe
notificações. Como foi citado anteriormente, se você usa o Pagseguro para receber por suas
vendas, você não saberá que um cliente pagou a compra até que o Pagseguro lhe informe isso.
E o Pagseguro faz isso em 2 etapas.

PRIMEIRO: o Pagseguro lhe envia uma notificação com um código alfanumérico. Tal como:
766B9C-AD4B044B04DA-77742F5FA653-E1AB24

Esse código só vai ser útil se você tiver um cadastro no Pagseguro com um e-mail e um token
válido que lhe servem como autenticação. Mesmo que esse número seja enviado
erroneamente a uma pessoa qualquer ou outro site, essa pessoa não teria acesso a nenhuma
informação, pois ele precisaria ter o seu token e o seu e-mail.

SEGUNDO: De posse no código de notificação você deve fazer uma chamada a API do
Pagseguro informando o código que você acabou de receber, além do seu e-mail e o seu token.
O Pagseguro então vai verificar se aquele código esta realmente associado a sua conta e se ele
se refere a uma venda realizada em seu site. Se tudo estiver correto, o Pagseguro retorna um
arquivo XML com as informações referentes àquele código de notificação.

Essas informações retornadas indicam se o status da venda mudou, se o cliente pagou a


compra, se ele cancelou, se ele escolheu uma forma de envio da compra (PAC, SEDEX,Etc).
Com todas essas informações em mãos, você pode realizar os processos necessários para
atualizar a sua tabela de vendas.

Como programar o script de Notificação do Pagseguro


Se você pretende consultar a documentação oficial do Pagseguro sobre a API, ela se encontra
no endereço: https://pagseguro.uol.com.br/v2/guia-de-integracao/api-de-notificacoes.html

Resolvi por programar de forma estruturada para que o passo a passo fique fácil de entender
para qualquer pessoa em qualquer nível – visto que POO pode ser confusa para alguns.

Descrição: Pagina de Notificações para o Pagseguro


Localização: C:\wamp\www\Pagseguro\pagseguro_notificacao.php

77
Sistema de Vendas usando Pagseguro

Existem três passos para processar uma notificação do Pagseguro.


1 – Receber o código de notificação;
2 – Obter mais informações sobre a notificação usando o Código;
3 – Fazer atualizações na venda baseada na notificação;

Começamos pelo principio, definimos as configurações que usaremos e também verificamos se


essa página esta recebendo um post do Pagseguro. Lembre-se de alterar o código abaixo,
informando o seu token de usuário e o seu e-mail do Pagseguro.

pagseguro_notificacao.php
<?php

# DADOS DE CONFIGURAÇÕES
# ----------------------
# definindo configuração que serão usadas
$config = new stdClass ;

# Credenciais hipoteticas para testes com Pagseguro


$config -> pagseguro_email = 'suporte@lojamodelo.com.br';
$config -> pagseguro_token = '95112EE828D94278BD394E91C4388F20';

# 1. ESTAMOS RECEBENDO UM POST DO PAGSEGURO?


# ------------------------------------------
# verificando se houve uma tentativa de POST nessa pagina
if( !isset( $_POST['notificationCode'] ) ) return;

# de posse de um codigo recebido via POST,


# faz chamada ao pagseguro e recebe xml com demais dados
$__code = $_POST['notificationCode'];

O Pagseguro lhe informa um código de notificação realizando um POST na sua página de


notificações enviando o campo notificationCode . Portando, basta verificar se esse campo está
setado em um post, se estiver, então sabemos que é uma notificação realizada pelo sistema do
Pagseguro.

De posse do código de notificação, nosso segundo objetivo é obter mais informações sobre ele.
Faremos isso através de uma função que criaremos logo mais (psn_get_notification). Por
momento basta saber que essa função se conecta ao Pagseguro e retorna as informações sobre
a notificação em forma de um Array.

pagseguro_notificacao.php (continuação)
# 2. BASEADO NO CODIGO RECEBIDO, TENTAMOS OBTER MAIS INFORMAÇÕES
# --------------------------------------------------------------
# fazemos uma chamada ao pagseguro para saber mais informacoes

78
Sistema de Vendas usando Pagseguro

# sobre a notificação que ele nos enviou


$_retorno = psn_get_notification(
$__code,
$config->pagseguro_email,
$config->pagseguro_token ) ;

# se aconteceu um erro ao consultar o pagseguro


# apenas matamos o processo.
if($_retorno == false) exit();

# Se o pagseguro nos retornou informacoes


# sobre uma determinada notificação,
# então, por via das duvidas guardando o retorno para auditoria
psn_log_message( $_retorno, 'notification_' );

No código acima há também uma função chamada psn_log_message. Essa função serve para
registrar em log todos os eventos importantes para uma possível auditória futura.

pagseguro_notificacao.php (continuação)
# 3. BASEADO NA NOTIFICAÇÃO COMEÇAMOS A FAZER ATUALIZAÇÕES
# --------------------------------------------------------
# efetua ações para avisar o CMS o que esta
# acontecendo quanto ao status da venda
psn_updateStatus(
$_retorno['reference'],/* cod de ref para uso entre sistema e o pagseguro */
$_retorno['code'], /* codigo numerico que indica o status da transacao */
$_retorno['status'] /* descricao texto do status */
);

# verifica se codigo e' 7 o que indica cancelamento ...


# neste caso retorna itens da venda para o estoque
if( $_retorno['code'] == 7 ){

# identificação da venda que foi cancelada.


# use o reference para saber qual venda se refere.
$__identificacao_da_venda = $_retorno['reference'];

# aqui você obtem todos os itens dessa venda

# Aqui você insere seu código para que cada item


# vendido fique disponivel novamente em estoque.

# caso tenha mais ações necessárias para cancelar a venda


# insira aqui.
}

# verificando se existe algo para atualizar


# a respeito do metodo de envio pelos correios
if(isset($_retorno['shippingCost'])){
# atualiza dados sobre o envio
psn_updateEnvio(
$_retorno['reference'], /* codigo Key de referencia */

79
Sistema de Vendas usando Pagseguro

$_retorno['shippingType'], /* tipo de envio PAC, SEDEX */


$_retorno['shippingCost'] /* custo do envio */
);
}

Com base na notificação recebida, são realizados processos para atualizar a venda dentro do
banco de dados. Primeiro, estamos atualizando o status da venda com a função
psn_updateStatus. Essa função grava no banco de dados a informação que informa se essa
venda foi quitada pelo cliente ou se ela foi cancelada. Por padrão, ela fica no status de
“Aguardando Pagamento”.

Se porventura o código retornado pelo Pagseguro no arquivo XML for igual a 7, então isso
indica que o cliente cancelou a compra. Sendo assim, você precisa tomar as medidas
necessárias para o cancelamento da compra dentro do seu sistema. Isso engloba obter as
informações sobre a venda, verificar quais produtos consta nela e retorna-los ao estoque para
que outros clientes possam compra-lo.

No arquivo XML retornado pelo Pagseguro, pode estar presente a informação shippingCost.
Essa informação é importante, pois ela indica se o cliente escolheu um método de envio da sua
compra, PAC, SEDEX, etc. Além de indicar o valor de envio dessa mercadoria.

E por fim, vamos construir as funções auxiliares que realizam o processo mais pesado.

pagseguro_notificacao.php (continuação)
/**
* Função para conexão ao servidor do PagSeguro
* via Curl.
*
* @access public
* @param type $url
* @param string $method GET com padrão
* @param array $data
* @param type $timeout 30
* @param type $charset ISO
* @return xml
*/
function psn_curl_connection(
$url, $method = 'GET', Array $data = null,
$timeout = 30, $charset = 'ISO-8859-1') {

if (strtoupper($method) === 'POST') {


$postFields = ($data ? http_build_query($data, '', '&') : "");
$contentLength = "Content-length: ".strlen($postFields);
$methodOptions = Array(
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $postFields,
);

80
Sistema de Vendas usando Pagseguro

} else {
$contentLength = null;
$methodOptions = Array(
CURLOPT_HTTPGET => true
);
}

$options = Array(
CURLOPT_HTTPHEADER => Array(
"Content-Type: application/x-www-form-urlencoded; charset=".$charset,
$contentLength
),
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HEADER => false,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_CONNECTTIMEOUT => $timeout,
//CURLOPT_TIMEOUT => $timeout
);

$options = ($options + $methodOptions);

$curl = curl_init();
curl_setopt_array($curl, $options);
$resp = curl_exec($curl);
$info = curl_getinfo($curl);// para debug
$error = curl_errno($curl);
$errorMessage = curl_error($curl);
curl_close($curl);

if ($error) {
psn_log_message( $errorMessage );
return false;
} else {
return $resp;
}
}

A função acima foi obtida do próprio Pagseguro, e serve para se conectar ao servidor da UOL
através de uma URL e enviar informações para esse endereço.

pagseguro_notificacao.php (continuação)
/**
* Rece um código de notificação do Pagseguro, conecta-se
* ao servidor do pagseguro e retorna informações extras
* sobre essa notificação.
*
* @access public
* @param string - código de notificação enviado pelo Pagseguro.
* Algo como 766B9C-AD4B044B04DA-77742F5FA653-E1AB24
* @param string - email do cliente cadastrado no pagseguro
* @param string - token do cliente para autenticação
* @return array[code,status,reference,shippingType,shippingCost]
*/

81
Sistema de Vendas usando Pagseguro

function psn_get_notification(
$__notificationCode = null,
$__email = null,
$__token = null ) {

# se não for passado um código, usará o $_POST que o PS envia


if($__notificationCode === null && isset($_POST['notificationCode']))
$__notificationCode = $_POST['notificationCode'];

# validacoes basicas de entrada de dados


# temos um codigo de notificacao?
if(!isset($__notificationCode)){
psn_log_message( "Nenhum código de notificação recebido." );
return false;}

# recebemos um endereco de email e token a consulta?


if( (!isset($__email)) || (!isset($__token)) ) {
psn_log_message( "E-mail ou Token de autenticação não recebido." );
return false;}

# ex: '
$url =
"https://ws.pagseguro.uol.com.br/v2/transactions/notifications/{$__notificationCode
}?email={$__email}&token={$__token}";

# conecta-se ao pagseguro
$transaction = psn_curl_connection($url);

# algo deu errado na autenticação


if($transaction == 'Unauthorized'){
psn_log_message(
'Unauthorized - Erro ao consultar notificação "'.
$__notificationCode.'" do PagSeguro.');
return false;
}

# converte o xml recebido do PS para um objeto


$xml = simplexml_load_string($transaction);

# definindo dados de retorno


$retorno = array();
$retorno['code'] = (int)$xml->status;
$retorno['status'] = $this->ps_stats((int)$xml->status);
$retorno['reference'] = $xml->reference;
$retorno['shippingType'] = isset($xml->shipping->type) ? $xml->shipping->type
: null ;
$retorno['shippingCost'] = isset($xml->shipping->cost) ? $xml->shipping->cost
: null ;

return $retorno;
}

Psn_get_notification é a função principal e que esta responsável pelo maior número de ações.
Ela recebe como parâmetros o código da notificação, o e-mail e token da sua empresa no
Pagseguro e então cria uma URL que servirá de chamada para a API do Pagseguro. Em seguida,

82
Sistema de Vendas usando Pagseguro

solicita a conexão com o servidor da UOL, obtem os dados retornados na forma de XML e
converte ele para objeto. Por fim, gera e retorna um array com as informações da notificação.

pagseguro_notificacao.php (continuação)
/**
* Função usada para realizar log em arquivo texto
* para uma possivel auditoria.
*
* @param string|array - informação a ser logada
* @param string - error_|notification_ será o inicio do nome
* do arquivo de log gravado. ex: "notification_2007-05_"
* @return bool
*/
function psn_log_message( $__message = null, $__tipo = 'error_' )
{
# validações basicas da entrada recebida
if( is_null($__message) ) return false;
if( is_array($__message) ) $__message = implode(" - ", $__message);
if(!is_string($__message) ) return false;

# o nome do nosso arquivo de log sera organizado por


# Ano e mes. Ex: "error_2017-05_"
date_default_timezone_set( 'America/Sao_Paulo' );
$__curr_mes_e_ano = date( 'Y-m' );

# aproveitamos para indicar o momento em que aconteceu


# a gravação do evento.
$__message = date('Y-m-d H:i:s') . " (pagseguro_notificacao.php): " . $__message
;

# obtemos um caminho completo para a nossa


# pasta de log, e o nosso arquivo a ser gravado
$__filename = getcwd() . DIRECTORY_SEPARATOR . 'logs' .
DIRECTORY_SEPARATOR . strtolower( "{$__tipo}{$__curr_mes_e_ano}_" );

# efetivamos a gravação dos dados no arquivo de LOG


file_put_contents( $__filename, $__message . PHP_EOL, FILE_APPEND);
return true;
}

Em seguida temos a função psn_log_message que serve para a gravação de mensagens em


arquivos de log para fins de auditória. Os arquivos de log, caso não existam, serão criados
automaticamente dentro da pasta logs.

pagseguro_notificacao.php (continuação)
/**
* Atualiza status de uma venda.
*
* -----------------------------
* Em SQL essa consulta equile a um :
* UPDATE vendas
* SET `status_venda` = '$status_venda',

83
Sistema de Vendas usando Pagseguro

* `status` = '$__notificationCode',
* `active` = 0
* WHERE `key` = '$key' ; ";
*-----------------------------
*
* @param string $key - valor unico que identifica uma venda
* @param int $__notificationCode - codigo numerico do status do pagseguro
* @param string $status_venda - frase do status
* @return bool
*/
function psn_updateStatus( $key = 0, $__notificationCode = 0, $status_venda =
"Aguardando pagamento" ) {

require_once 'database/database.php' ;

$_dados = array(
'status_venda' => $status_venda ,
'status' => $__notificationCode);

# verifica se codigo recebido indica cancelamendo da compra.


# Assim, damos baixa na venda e cancelamos a compra
if($__notificationCode == 7) {
$_dados['active'] = 0;
}

# atualiza tabela de vendas onde a coluna Key e' igual a


# Key referencia retornado pelo Pagseguro.
return Database::update_where( "vendas", array('key' => $key), $_dados );
}

Agora entramos nas funções de atualização da base de dados. Elas serão responsáveis por
informar no seu sistema que uma venda teve o status alterado para Paga, Cancelada e etc.
Portanto, tenha cuidado e teste bastante essa função para garantir que não haja falhas.

pagseguro_notificacao.php (continuação)
/**
* Uma vez que o cliente pode escolher a forma de envio
* no ato do pagamento no Pagseguro. Você só sera informado
* sobre qual método o cliente escolheu, quando o Pagseguro
* lhe retornar uma notificação sobre essa escolha.
*
* Essa função serve para atualizar a tabela de vendas,
* e a coluna método de envio para o valor
* que o cliente escolheu.
*
* @param integer - referencia de uma venda
* @param string
* @param string $valor_envio [description]
* @return bool
*/
function psn_updateEnvio( $key = 0, $forma_envio = null, $valor_envio = '0.00' )
{
require_once 'database/database.php' ;

84
Sistema de Vendas usando Pagseguro

$_dados = array('valor_envio' => $valor_envio);


if( isset($forma_envio) )
$_dados['forma_envio'] = $forma_envio;

return Database::update_where( "vendas", array('key' => $key), $_dados );


}

E por fim a nossa última função de atualização, psn_updateEnvio. Essa função é chamada
sempre que o status de envio da venda ao cliente muda. Uma vez que o cliente tem a opção de
escolher a forma de envio da mercadoria através do site do Pagseguro, você será notificado
assim que ele escolher uma das formas disponíveis.
Além da informação do tipo de envio, o Pagseguro lhe informa também o preço a ser pago no
serviço de envio. Assim que receber essa informação grave ela na tabela de vendas.

Bom, isso finaliza esse material. Tentei expressar todo processo de transação com o Pagseguro
da maneira mais clara possível. Caso tenha dúvidas ainda, sobre algum dos tópicos entre em
contato e expresse a sua opinião, pois ela é muito importante para o aprimoramento desse
material e de outros que serão escritos futuramente.

Sem mais,
O autor: Wanderlei Santana.

85

S-ar putea să vă placă și