DevWebPHP
Image
11/05/2020

Como integrar o PicPay com PHP: passo a passo completo

# Integração PicPay com PHP

[EDIT 20/07/2020] Vídeo do tutorial no YouTube:

Neste tutorial vamos fazer a integração do PicPay com PHP sem o uso de dependências só com o cURL do PHP. Eu usei o PHP na versão 7.2, eu espero que você esteja usando da 5.6 em diante!

# Iniciando o desenvolvimento

Vamos usar um arquivo para simular um banco de dados. Cada produto terá os seguintes campos:

  • id
  • nome
  • descricao
  • valor

Crie um arquivo chamado produtos.php com o seguinte conteúdo:

//produtos.php
<?php
return [
    1 => ['id' => 1, 'nome' => 'Produto 1', 'descricao' => 'Primeiro produto', 'valor' => 1.00],
    2 => ['id' => 2, 'nome' => 'Produto 2', 'descricao' => 'Segundo produto', 'valor' => 2.00],
    3 => ['id' => 3, 'nome' => 'Produto 3', 'descricao' => 'Terceiro produto', 'valor' => 3.00]
];
1
2
3
4
5
6
7

# Exibindo os produtos na tela:

Crie um arquivo chamado index.php e inclua o arquivo produtos.php. Para exibir os produtos na tela, vamos sar um foreach para iterar sobre os produtos e montar uma tabela:

//index.php
<?php
$produtos = include('produtos.php');
?>
<table border="1">
  <thead>
    <tr>
    <th>ID</th>
    <th>Nome</th>
    <th>Descrição</th>
    <th>Valor</th>
    </tr>
  </thead>
  <tbody>
  <?php foreach ($produtos as $produto) { ?>
    <tr>
      <td><?= $produto['id'] ?></td>
      <td><?= $produto['nome'] ?></td>
      <td><?= $produto['descricao'] ?></td>
      <td><?= $produto['valor'] ?></td>
    </tr>
  <? } ?>
  </tbody>
</table>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

Para visualizar o resultado disso, inicie o servidor PHP rodando o comando no terminal:

php -S localhost:1234
1

Se o comando deu certo, irá exibir algo como:

$ php -S localhost:1234
PHP 7.2.24-0ubuntu0.18.04.4 Development Server started at Fri May 15 08:22:38 2020
Listening on http://localhost:1234
Document root is /home/tiagoa/picpay
Press Ctrl-C to quit.
1
2
3
4
5

Agora abra o navegador e acesse http://localhost:1234 para visualizar o resultado:

Resultado no navegador

Desta maneira não há como interagir com os produtos, para isso, vamos fazer:

  • colocar a tabela de produtos dentro de um formulário;
  • trocar o id com um input checkbox para poder selecionar os produtos desejados;
  • e por fim, adicionar um botão para enviar este formulário.


 



 









 







 






//index.php
<?php
$produtos = include('produtos.php');
?>
<!-- criar um formulário para enviar os produtos selecionados -->
<form method="post" action="comprar.php">
  <table border="1">
    <thead>
      <tr>
        <th></th><!-- deixe vazia -->
        <th>Nome</th>
        <th>Descrição</th>
        <th>Valor</th>
      </tr>
    </thead>
    <tbody>
    <?php foreach ($produtos as $produto) { ?>
      <tr>
        <!-- troque o id por um input checkbox para enviar somente os ids dos produtos desejados -->
        <td><input type="checkbox" name="id[]" value="<?= $produto['id'] ?>"></td>
        <td><?= $produto['nome'] ?></td>
        <td><?= $produto['descricao'] ?></td>
        <td><?= $produto['valor'] ?></td>
      </tr>
    <? } ?>
    </tbody>
  </table>
  <!-- adiciona um botão para enviar o formulário -->
  <input type="submit" value="Comprar">
</form>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

Perceba que o formulário irá enviar os ids para o arquivo comprar.php. Vamos criar este arquivo com o seguinte código:

//comprar.php
<?php
//caso não tenha selecionado nenhum produto e enviado o formulário, retorna para index.php
if (empty($_POST)) {
    header('location: index.php');
}
//exibe os dados enviados
print_r($_POST);
?>
<a href="index.php" title="Voltar para os produtos">Voltar para os produtos</a>
1
2
3
4
5
6
7
8
9
10

Vá para o navegador, marque alguns produtos e clique no botão "Comprar", na tela aparecerá algo como:

Conteúdo dos dados enviados

# Calculando o total dos produtos

Precisaremos enviar o valor total para criar um QR Code de pagamento do PicPay. Então antes de iniciarmos a integração com o PicPay, vamos primeiro calcular este valor.

Os dados dos produtos estão em outro arquivo então precisaremos incluí-lo. Vamos percorrer todos os ids enviados e para cada id, vamos acessar o valor usando o id enviado como chave no array dos produtos e então adicionar o valor do produto ao total.









 











//comprar.php
<?php
//caso não tenha selecionado nenhum produto e enviado o formulário, retorna para index.php
if (empty($_POST)) {
    header('location: index.php');
}

//recuperar os produtos para obter os valores
$produtos = include('produtos.php');

$total = 0;
//iterar sobre os produtos selecionados
foreach ($_POST['id'] as $id) {
    $total += $produtos[$id]['valor'];
}
echo 'Total: ' . $total;
?>
<br>
<a href="index.php" title="Voltar para os produtos">Voltar para os produtos</a>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

Com isso feito, podemos testar selecionando uma combinação diferente de produtos:

Duas combinações de produtos enviadas

# Preparando o envio

Seguindo a documentação do PicPay, para gerar o QR Code de pagamento é necessário enviar as informações com a seguinte estrutura:

{
    "referenceId": "102030",
    "callbackUrl": "http://www.sualoja.com.br/callback",
    "value": 20.51,
    "buyer": {
        "firstName": "João",
        "lastName": "Da Silva",
        "document": "123.456.789-10",
        "email": "test@picpay.com",
        "phone": "+55 27 12345-6789"
    }
}
1
2
3
4
5
6
7
8
9
10
11
12

O campo referenceId deve ser único para cada transação, não utilize nenhuma forma de gerar números ou hash aleatórios, pois mesmo sendo pequena, há a chance de se repetir. Portando aqui iremos usar a função nativa do PHP microtime().

A URL no campo callbackUrl será a que o PicPay vai chamar quando houver alguma mudança de status na trasação.

Agora que temos o total, crie uma variável no arquivo comprar.php logo abaixo do echo contendo o que iremos enviar para solicitar a geração do QR Code:

//comprar.php
...
echo 'Total: ' . $total;

$solicitacao = [
    'referenceId' => microtime(true),
    'callbackUrl' => 'http://'.$_SERVER['HTTP_HOST'].'/notificacao.php',
    'value' => $total,
    'buyer' => [
        'firstName': 'João',
        'lastName': 'Da Silva',
        'document': '123.456.789-10',
        'email': 'test@picpay.com',
        'phone': '+55 27 12345-6789'
    ]
];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

Perceba que no callbackUrl está apontando para um arquivo que ainda não existe, mas não se preocupe, iremos ver isso mais para frente.

# Iniciando integração

Agora que temos os dados necessários, podemos começar a integração com o PicPay.

Vá até o painel do PicPay e copie seu token.

Onde fica o token do PicPay

Vamos criar a variável $picPayToken que irá armazenar o token. Coloque logo abaixo da variável $solicitacao no arquivo comprar.php:

//comprar.php
...
$picPayToken = 'seu-token-aqui';
1
2
3

# Gerando QR Code

Utilizaremos as funções nativas de cURL do PHP para enviar a solicitação de pagamento ao PicPay.

Insira o seguinte trecho logo abaixo da variável $picPayToken que irá:

  • inicializar o cURL
  • fornecer a url de destino
  • passar o parâmetro para retornar a resposta
  • fornecer os dados necessários para gerar o QR Code
  • informar que iremos fazer uma requisição utilizando o método POST
  • enviar os headers obrigatórios
  • fazer a requisição
  • armazenar a resposta
  • exibir o conteúdo da resposta
  • abortar caso aconteça algum erro
  • fechar a conexão
//comprar.php
(...)
$picPayToken = 'seu-token-aqui';
// inicializar o cURL
$ch = curl_init();
// fornecer a url de destino
curl_setopt($ch, CURLOPT_URL, 'https://appws.picpay.com/ecommerce/public/payments');
// passar o parâmetro para retornar a resposta
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// fornecer os dados necessários para gerar o QR Code
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($solicitacao));
// informar que iremos fazer uma requisição utilizando o método POST
curl_setopt($ch, CURLOPT_POST, true);

// enviar os headers obrigatórios
$headers = [];
$headers[] = 'Content-Type: application/json';
$headers[] = 'X-Picpay-Token: ' . $picPayToken;
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
// fazer a requisição
$result = curl_exec($ch);
// armazenar a resposta
$resposta = json_decode($result);
// exibir o conteúdo da resposta
var_dump($resposta);
// abortar caso aconteça algum erro
if (curl_errno($ch)) {
    die('Erro: ' . curl_error($ch));
}
// fechar a conexão
curl_close($ch);
?>
(...)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

Acesse a página de produtos (index.php) no navegador, selecione o primeiro produto e clique em comprar.

O retorno deve ser mais ou menos assim:

Retorno PicPay

Perceba que o PicPay já retorna o QR Code pronto para ser exibido numa tag de imagem, e também um link que podemos redirecionar para realizar o pagamento no próprio site deles.

Com isso, vamos exibir o QR Code e também o link retornado. Antes do link de voltar para a página de produto insira o sequinte trecho:

//comprar.php
(...)
?>
<img src="<?= $resposta->qrcode->base64 ?>" alt="QR Code">
<br>
<a href="<?= $resposta->qrcode->content ?>" title="Ir para o site do PicPay">Pagar no PicPay</a>
<br>
(...)
1
2
3
4
5
6
7
8

# Como consultar o status do pagamento no PicPay

Agora que já temos o QR Code gerado, podemos prosseguir para a consulta do status do pagamento. Para consultar o status é obrigatório enviar somente o token de acesso e o código de referência gerado ao solicitar o pagamento.

Crie um arquivo chamado status.php que será bem parecido com o comprar.php. O arquivo vai executar os seguintes passos:

  • recebe o código de referência por GET
  • aborta caso não tenha passado o código
  • monta a url
  • inicializa o cURL
  • fornece a url de destino
  • passa o parâmetro para retornar a resposta
  • envia os headers obrigatórios
  • faz a requisição
  • armazena a resposta
  • exibe o conteúdo da resposta
  • aborta caso aconteça algum erro
  • fecha a conexão
//status.php
<?php
// recebe o código de referência por GET
if (empty($_GET) && !isset($_GET['referencia'])) {
    // aborta caso não tenha passado o código
    die('Forneça a refência');
}
$picPayToken = 'seu-token-aqui';
// monta a url
$url = 'https://appws.picpay.com/ecommerce/public/payments/'.$_GET['referencia'].'/status';
// inicializa o cURL
$ch = curl_init();
// fornece a url de destino
curl_setopt($ch, CURLOPT_URL, $url);
// passa o parâmetro para retornar a resposta
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// envia os headers obrigatórios
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'X-Picpay-Token: ' . $picPayToken
]);
// faz a requisição
$result = curl_exec($ch);
// armazena a resposta
$resposta = json_decode($result);
// exibe o conteúdo da resposta
var_dump($resposta);
// aborta caso aconteça algum erro
if (curl_errno($ch)) {
    die('Error: ' . curl_error($ch));
}
// fecha a conexão
curl_close($ch);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

Para poder testar esse script, vamos voltar no arquivo comprar.php e inserir um link para chamar nossa consulta de status logo abaixo do link que direciona para o site do PicPay:

//comprar.php
(...)
<a href="<?= $resposta->qrcode->content ?>" title="Ir para o site do PicPay">Pagar no PicPay</a>
<br>
<a href="status.php?referencia=<?= $resposta->referenceId ?>" title="Consultar o status">Consultar o status</a>
<br>
(...)
1
2
3
4
5
6
7

Agora acesse para a página inicial, selecione um produto e clique em comprar, após o QR Code ser gerado, clique no link "Consultar o status" e você verá algo como:

Resposta consultar status

Vamos melhorar o visual removendo o var_dump e adicionando o seguinte trecho no final do arquivo status.php:

//status.php
(...)
// fecha a conexão
curl_close($ch);
?>
A situação da transação <?= $resposta->referenceId ?> é <strong><?= $resposta->status ?></strong>
1
2
3
4
5
6

# Solicitando o cancelamento

Para testar a integração o PicPay não dispõe de um ambiente de testes assim como o PagSeguro e o Mercado Pago por exemplo, então, todos os pagamentos são efetuados de verdade! Mas não se preocupe, pois podemos cancelar o pagamento tanto pelo painel quanto pela nossa aplicação.

Cancelar uma transação é muito simples, precisamos enviar o código de referência na URL e o token no header da requisição.

Crie um arquivo chamado cancelar.php que irá receber o código de referência via parâmetro:

//cancelar.php
<?php
if (empty($_GET) && !isset($_GET['referencia'])) {
    die('Forneça a refência');
}
$picPayToken = 'seu-token-aqui';
// inicializa o cURL
$ch = curl_init();
// monta a URL
$url = 'https://appws.picpay.com/ecommerce/public/payments/' . $_GET['referencia'] . '/cancellations';
// fornece a url de destino
curl_setopt($ch, CURLOPT_URL, $url);
// passa o parâmetro para retornar a resposta
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// informa que iremos fazer uma requisição utilizando o método POST
curl_setopt($ch, CURLOPT_POST, true);

// envia os headers obrigatórios
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'X-Picpay-Token: ' . $picPayToken
]);
// faz a requisição
$result = curl_exec($ch);
// armazena a resposta
$resposta = json_decode($result);
// exibe o conteúdo da resposta
var_dump($resposta);
// aborta caso aconteça algum erro
if (curl_errno($ch)) {
    die('Erro: ' . curl_error($ch));
}
// fecha a conexão
curl_close($ch);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

Agora vamos adicionar um link no final do status.php para chamar o script de cancelamento:

//status.php
(...)
<br>
<a href="cancelar.php?referencia=<?= $_GET['referencia'] ?>">Cancelar</a>
1
2
3
4

Fazendo o todo o processo desde o inicío, selecionando um produto, clicando em comprar, clicando no status, clique em cancelar e o resultado deve ser algo como:

Resultado cancelamento

Agora que podemos cancelar a transação pelo nosso código, podemos pagar de fato pelo aplicativo do PicPay no celular. Porém para cancelar uma transação que foi paga, precisaremos alterar enviar o código de autorização. Este código nós recebemos quando consultamos o status da transação no arquivo status.php.

Troque o trecho que exibe as informações da transação e o link cancelar, pelo trecho que irá verificar se veio o código de autorização na resposta, caso tenha vindo, exibe ele na tela e em seguida passa via parâmetro para o script de cancelar. Caso contrário só exibe o link de cancelar sem o parâmetro da autorização:

De:

//status.php
A situação da transação <?= $resposta->referenceId ?> é <strong><?= $resposta->status ?></strong>
<br>
<a href="cancelar.php?referencia=<?= $_GET['referencia'] ?>">Cancelar</a>
1
2
3
4

Para:

//status.php
<?php if ($resposta->authorizationId) { ?>
    <br> e o código da autorização é <?= $resposta->authorizationId ?>.
    <br>
    <a href="cancelar.php?referencia=<?= $_GET['referencia'] ?>&autorizacao=<?= $resposta->authorizationId?>">Cancelar</a>
<?php } else {?>
    <br>
    <a href="cancelar.php?referencia=<?= $_GET['referencia'] ?>">Cancelar</a>
<?php } ?>
1
2
3
4
5
6
7
8
9

Agora que o script cancelar.php recebe o código de autorização via parâmetro, precisamos enviar para a API do PicPay caso seja necessário:

//cancelar.php
(...)
// informa que iremos fazer uma requisição utilizando o método POST
curl_setopt($ch, CURLOPT_POST, true);
// envia o código de autorização caso necessário
if (isset($_GET['autorizacao'])) {
    $autorizacao = ['authorizationId' => $_GET['autorizacao']];
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($autorizacao));
}
// envia os headers obrigatórios
(...)
1
2
3
4
5
6
7
8
9
10
11

Por fim, adicione o seguinte trecho também do arquivo cancelar.php bem no final:

//cancelar.php
(...)
// fecha a conexão
curl_close($ch);
?>
Transação cancelada com sucesso!
<br>
Caso queira, <a href="status.php?referencia=<?= $_GET['referencia'] ?>">consulte o status novamente</a>.
1
2
3
4
5
6
7
8

Pronto! Podemos fazer pagar com o aplicativo, consultar o status e logo em seguida cancelar:

Fluxo completo

# Recebendo as notificações do PicPay

Chegamos a última parte da integração que é receber as notificações que ocorrem quando a transação muda de status.

Lembra que lá quando enviamos os dados para gerar o QR Code enviamos um campo chamado callbackUrl? Agora vamos criar ele.

O PicPay vai fazer uma requisição POST para a URL que informamos no campo callbackUrl enviando os seguintes dados:

{
  "referenceId": "102030",
  "authorizationId": "5b01780ba8914c001a007673"
}
1
2
3
4

Perceba que não vem o status nos dados requisição. O PicPay não envia nada além disso por questão de segurança. Para obter o status e mais informações, teremos que fazer a requisição que fizemos no status.php novamente.

Com isso em mente, duplique o arquivo status.php e renomeie para notificacao.php.

Só que dessa vez, os parâmetros virão via POST e não via GET.

Não utilizaremos a superglobal nativa do PHP $_POST para recuperar os dados requisição, ao invés disso, vamos pegar o corpo da requisição diretamente com file_get_contents('php://input').

Após consultar o status, vamos gravar num arquivo só para ver o resultado, pois não adianta retornar nada neste script porque vai ser o PicPay que irá chamá-lo.

//notificacao.php
<?php
// pega o corpo da requisição
$payload = json_decode(file_get_contents('php://input'), true);
// token
$picPayToken = 'seu-token-aqui';
// monta a url
$url = 'https://appws.picpay.com/ecommerce/public/payments/'.$payload['referenceId'].'/status';
// inicializa o cURL
$ch = curl_init();
// fornece a url de destino
curl_setopt($ch, CURLOPT_URL, $url);
// passa o parâmetro para retornar a resposta
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// enviar os headers obrigatórios
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'X-Picpay-Token: ' . $picPayToken
]);
// faz a requisição
$result = curl_exec($ch);
// prepara o registro
$linha = date('d/m/Y H:i:s') . ' - ' . $result . "\n";
// armazena a resposta
file_put_contents('notificacoes.txt', $linha, FILE_APPEND);
// aborta caso aconteça algum erro
if (curl_errno($ch)) {
    die('Error: ' . curl_error($ch));
}
// fecha a conexão
curl_close($ch);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

Gere um QR Code e pagueu com seu aplicativo do PicPay, Após pagar, copie o código de referência e o id de autorização.

Para testar este arquivo, vamos fazer uma requisição em cURL no terminal mesmo, mas você pode usar o Postman ou similar.

curl -XPOST -H "Content-type: application/json" -d '{"referenceId":"código da referência","authorizationId":"id da autorização"}' 'http://localhost:1234/notificacao.php'
1

Abra o arquivo notificacoes.txt e veja o que foi gravado. Numa implementação real, o ideal seria gravar o código de referência e o id de autorização no banco de dados para futuras consultas e atualização do status quando receber as notificações do PicPay.

Os possíveis status do PicPay são:

Status Descrição
created Registro criado
expired Prazo para pagamento expirado
analysis Pago e em processo de análise anti-fraude
paid Pago
completed Pago e saldo disponível
refunded Pago e devolvido
chargeback Pago e com chargeback

# Concluindo

Pronto! E isso é toda a integração do PicPay de uma maneira simples. Claro que dá pra otimizar os scripts movendo os códigos que se repetem entre os arquivos, mas aqui eu quis deixar bem direto mesmo o que é necessário em cada parte.

O código-fonte completo você pode baixar aqui.

Fique à vontade para deixar um comentário caso tenha ficado com dúvida ou queira dar uma sugestão. Espero ter ajudado!

Copyright © DevWebPHP 2020