Toda vez que um cliente me pergunta sobre integrar PIX, a primeira coisa que eu pergunto de volta é: PIX de quem?
Parece resposta de consultor evasivo. Não é. É a pergunta que define tudo.
O Banco Central criou as regras e opera o SPI, o Sistema de Pagamentos Instantâneos. Mas você não integra com o Banco Central. Você integra com um Participante Direto que implementou a especificação e te expõe a própria API: um banco, uma fintech, um gateway de pagamento. Itaú, Efí, Mercado Pago, Pagar.me, Asaas. Cada um com documentação própria, comportamento próprio em edge cases, particularidades que não aparecem em nenhuma especificação oficial porque são decisão de implementação do próprio provedor.
Já trabalhei com mais de um PSP ao longo de projetos diferentes. A variação entre eles é real. Webhook que confirma em milissegundos num vs. pode demorar alguns minutos no outro. Status intermediário que a documentação descreve mas cujo comportamento real você descobre quando um pagamento fica preso nele numa segunda-feira de manhã com cliente ligando. Campo retornado em formato diferente do exemplo que estava na doc.
A escolha do PSP não é detalhe técnico. É uma decisão de produto, e vale ser feita com cuidado antes de escrever a primeira linha de integração.
QR code estático vs dinâmico
O PIX tem dois tipos de cobrança, e confundir os dois em produção gera problema.
O QR code estático é fixo. Você gera uma vez, pode imprimir, colocar no site, compartilhar. Qualquer pagamento feito pra ele cai na conta, mas sem contexto nenhum: você sabe que recebeu R$ 150, mas não sabe qual pedido, qual cliente, qual fatura. Funciona bem pra caixinha no balcão do comércio, pra doação, pra situações onde reconciliação não é necessária. Não funciona pra sistema de vendas com volume.
O QR code dinâmico é gerado por requisição, tem dados da cobrança embutidos, expira no prazo que você definir, e quando o pagamento confirma o webhook vem com o ID da sua cobrança. Você fecha o ciclo completo: pedido gerado, PIX pago, cobrança baixada, confirmação disparada, tudo automático sem intervenção humana.
Pra qualquer sistema de vendas, assinaturas ou cobranças recorrentes, só o dinâmico faz sentido. Essa decisão parece óbvia, mas já vi sistema entrar em produção com QR estático por falta de clareza sobre a diferença, e o financeiro tentando conciliar manualmente no fim do dia. Não é bonito.
Onde mora a maioria dos bugs de produção
Webhook. Sempre webhook.
O PSP chama o endpoint do seu sistema quando um PIX confirma. Seu sistema processa, fecha o pedido, dispara o que tiver que disparar. Simples.
Exceto quando o PSP chama o mesmo webhook duas vezes pra mesma transação. Ou quando chama em ordem diferente do que aconteceu. Ou quando o seu endpoint estava temporariamente indisponível e o PSP tentou de novo alguns minutos depois, quando o sistema já estava de volta mas sem saber que aquele evento tinha falhado antes.
Seu sistema tem que ser idempotente. Processar o mesmo webhook duas vezes não pode gerar dois e-mails, duas baixas de cobrança, dois créditos na conta do cliente. A solução é simples: você guarda o ID da transação e, antes de processar qualquer coisa, verifica se já foi processada. Se sim, retorna 200 e segue o dia. Simples assim.
O problema é que quando você está construindo o fluxo rápido, a idempotência fica pra depois. E “depois” às vezes aparece na forma de um cliente ligando pra dizer que recebeu confirmação dupla do mesmo pedido.
Pois é.
mTLS: o detalhe que trava deploy
A especificação do Banco Central exige autenticação mútua via certificado TLS nas chamadas entre PSPs. O mTLS garante que os dois lados da conexão se autenticam mutuamente, não só o servidor pro cliente como no HTTPS normal.
Cada PSP implementa isso de um jeito. Alguns abstraem bem e te entregam autenticação via OAuth ou API key pras chamadas de saída. Mas pra receber webhooks autenticados e validar que aquela chamada veio de fato do PSP e não de alguém se passando por ele, muitos exigem que você configure o certificado no seu servidor.
Não é complicado. Mas não é trivial da primeira vez. E se o ambiente for na AWS, em container Docker ou em servidor gerenciado, tem implicações de onde e como o certificado fica armazenado e renovado. Já vi isso travar horas de deploy porque o desenvolvedor tinha testado só com mock local e nunca tinha configurado mTLS em produção de verdade. Em staging passou tudo, porque o mock não validava certificado. Na produção, primeira requisição real: erro 401 sem mensagem clara.
Vale testar o fluxo completo com ambiente real cedo. Não na véspera do go-live.
Reconciliação: o trabalho que aparece tarde
Quando o volume cresce, você vai precisar de um processo de reconciliação. Porque nem todo webhook chega. Porque sistema cai, às vezes exatamente quando um pagamento confirma. Porque você vai querer garantir que o estado do seu banco de dados bate com o estado do PSP antes de fechar o mês.
A maioria dos PSPs oferece endpoint de listagem de cobranças com filtro por período. Você consulta periodicamente, compara com o que está na sua base, trata o que está divergente. A lógica em si não é complicada. O que exige cuidado é decidir com qual frequência rodar, o que fazer com cobranças em status ambíguo, e como tratar transações recebidas fora de ordem.
Esse é o tipo de requisito que ninguém menciona no escopo inicial. Aparece quando o financeiro reclama que um pagamento não baixou, você investiga, e descobre que o webhook falhou silenciosamente dois dias antes por alguma falha transitória no seu servidor, e não houve retry suficiente pra cobrir.
Antes de começar
Escolha o PSP antes de escrever integração. Leia a documentação técnica, não só o quickstart. Procure especificamente pelo comportamento de webhook em falha: o PSP faz retry automático? Com qual intervalo? Até quantas tentativas? Existe painel pra visualizar tentativas de entrega do webhook e reprocessar manualmente se necessário?
Essas informações estão na documentação técnica avançada, não na landing page de marketing. E elas definem como você vai operar e debugar em produção quando o inevitável acontecer.
O PIX é rápido no pagamento. Segundos. Mas construir uma integração que aguenta volume real, que não perde confirmações, que concilia automaticamente, que lida com as particularidades do PSP escolhido, isso leva o mesmo tempo e cuidado que qualquer integração financeira sempre levou. Não ficou simples porque o pagamento ficou rápido.
Gabriel Schunck trabalha com integrações de pagamento em PHP e Laravel. Se você está planejando integrar PIX no seu sistema e quer avaliar o escopo antes de começar, entra em contato pelo gabriels.dev.br.