A spec do QR Code PIX: anatomia do payload EMVCo para desenvolvedores
Ponto-chave
O QR Code do Pix útiliza o padrão internacional EMVCo baseado na estrutura TLV (Tag-Length-Value). Dominar o parsing e a geração deste payload, incluindo o cálculo exato do CRC16, é a fronteira entre uma integração de pagamentos robusta e um sistema que perde conversão por falhas de leitura.
O Pix movimentou mais de R$ 17 trilhões no Brasil em 2023. Por trás de cada transação feita em maquininhas da Stone, totens de autoatendimento ou telas de e-commerce, existe uma string de texto aparentemente ininteligível. Essa string é o payload EMVCo. Se você opera um e-commerce, desenvolve para fintechs ou trabalha com meios de pagamento, dominar a anatomia desse payload separa os profissionais dos amadores.
Nós, da Ouro Capital, passamos os últimos anos acompanhando a evolução das resoluções do Banco Central. O BACEN não reinventou a roda ao criar o Pix. A genialidade técnica do projeto foi adotar o padrão global EMVCo — o mesmo consórcio formado por Visa, Mastercard, Américan Express e UnionPay. Isso garantiu que qualquer leitor de QR Code padrão do mundo pudesse, teoricamente, interpretar a base de um pagamento Pix.
O problema? A específicação é rigorosa. Um caractere fora do lugar, um espaço invisível no nome do recebedor, ou um cálculo de CRC16 errado, e o aplicativo do Nubank ou do Mercado Pago vai cuspir um erro genérico na tela do seu cliente. A conversão despenca. A culpa cai no gateway, mas o erro está no código.
Vamos destrinchar o Manual de Padrões para Iniciação do Pix e entender exatamente como ler, montar e validar essa estrutura programaticamente.
A Anatomia do Payload EMVCo
A base do QR Code EMVCo é o formato TLV: Tag, Length, Value (Etiqueta, Tamanho, Valor). Tudo no Pix é um bloco de informação encaixado dentro dessa lógica.
- Tag: Sempre 2 dígitos numéricos (ex: 00).
- Length: Sempre 2 dígitos numéricos indicando o tamanho do valor (ex: 14).
- Value: O conteúdo em si, com exatamente o tamanho específicado.
Se você ler a string 000201, seu parser deve quebrar assim:
Tag 00 (Payload Format Indicator).
Length 02 (dois caracteres).
Value 01 (a versão do payload).
Campos Obrigatórios do Pix
Existem dezenas de tags possíveis no padrão EMVCo, mas o Banco Central definiu um subconjunto específico para o Pix. Acompanhe a sequência lógica que o seu sistema precisa gerar ou ler:
Tag 00: Payload Format Indicator. Sempre será 000201.
Tag 01: Point of Initiation Method. Se for um QR Code estático (usado várias vezes), o valor é 11. Se for dinâmico (uso único), o valor é 12. Ficaria 010211 ou 010212.
Tag 26: Merchant Account Information. Aqui a complexidade aumenta. A Tag 26 é um TLV aninhado. Dentro dela, existem sub-tags. O BACEN exige que a sub-tag 00 contenha a GUI (Globally Unique Identifier) do arranjo, que é sempre br.gov.bcb.pix. A sub-tag 01 guarda a chave Pix do recebedor (CPF, CNPJ, e-mail, telefone ou chave aleatória). Se for um QR Code dinâmico, em vez da chave, teremos a sub-tag 25 contendo a URL do payload dinâmico.
Tag 52: Merchant Category Code (MCC). Código de 4 dígitos que identifica o ramo de atividade. Em integrações genéricas, usa-se 0000. Exemplo: 52040000.
Tag 53: Transaction Currency. Sempre o código ISO 4217 do Real brasileiro, que é 986. Exemplo: 5303986.
Tag 54: Transaction Amount. O valor da transação. Diferente do padrão brasileiro tradicional com vírgulas, o EMVCo exige formatação em string com ponto flutuante, sem zeros à esquerda desnecessários. Dez reais e cinquenta centavos vira 10.50. Se o valor tem 5 caracteres, a tag fica 540510.50.
Tag 58: Country Code. Sempre BR. Exemplo: 5802BR.
Tag 59: Merchant Name. O nome do recebedor. Máximo de 25 caracteres. Aqui os desenvolvedores costumam tropeçar. Caracteres especiais e acentos devem ser removidos ou substituídos, pois alguns aplicativos bancários falham ao fazer o parser de UTF-8 estendido no leitor de câmera.
Tag 60: Merchant City. Cidade do recebedor. Máximo de 15 caracteres.
Tag 62: Additional Data Field Template. Outro TLV aninhado. A sub-tag 05 guarda o Reference Label (o famoso TXID). O TXID serve para conciliação. Em QR Codes dinâmicos, o BACEN recomenda o uso de *** quando o TXID for gerenciado pela API.
Tag 63: CRC16. A assinatura de integridade de todo o payload.
Engenharia Reversa: Fazendo o Parsing na Prática
Imagine que o seu sistema precisa ler o Pix Copia e Cola colado por um cliente. Você não pode confiar cegamente que a string está íntegra. Observamos que muitas fraudes de e-commerce tentam manipular o valor (Tag 54) ou o recebedor (Tag 26) diretamente na string antes de processar o pagamento.
O algoritmo de parsing deve ser um loop while que lê a string da esquerda para a direita.
- O ponteiro inicia no índice 0.
- Lê os caracteres no índice 0 e 1. Esta é a Tag.
- Lê os caracteres no índice 2 e 3. Este é o Length (vamos chamar de
L). - Converte
Lpara inteiro. - Extrai a substring do índice 4 até
4 + L. Este é o Value. - O ponteiro avança para
4 + L. - O loop repete até o final da string.
Se durante esse processo o tamanho extraído ultrapassar o limite da string total, o payload está corrompido. Aborte a operação. Aplicativos de ponta, como os do Itaú e BTG Pactual, fazem essa validação em milissegundos assim que a câmera foca no QR Code.
O famigerado CRC16 (Cyclic Redundancy Check)
A Tag 63 é obrigatoriamente a última tag do payload. Ela garante que nenhum bit da string foi alterado acidentalmente ou maliciosamente. O cálculo não é um hash criptográfico como SHA-256, mas uma verificação de redundância cíclica.
O padrão exigido pelo BACEN é o CRC-16-CCITT (Polinômio 0x1021, Valor Inicial 0xFFFF, sem reflexão de entrada ou saída).
Para calcular corretamente, você deve pegar a string inteira do payload, desde o 00 inicial até o 6304 (que é a declaração da tag de CRC e seu tamanho de 4 caracteres). O valor do CRC em si não entra no cálculo, obviamente, porque ele é o resultado. Você roda o algoritmo sobre essa string parcial, obtém um valor hexadecimal de 4 dígitos, converte para maiúsculo e anexa ao final.
Se o seu código gerar um CRC em minúsculo (ex: a1b2), alguns bancos vão rejeitar. A específicação EMVCo exige hexadecimais em uppercase (A1B2).
QR Code Estático vs. Dinâmico: O que muda no código?
Na nossa análise diária de integrações de fintechs, a confusão entre estático e dinâmico é a maior causadora de chamados de suporte técnico.
O QR Code Estático carrega todos os dados da transação (chave, valor, nome) dentro da própria string. Ele é autossuficiente. A maquininha offline ou o papel impresso no caixa da padaria usam esse modelo. O limite físico de um QR Code é de poucas centenas de caracteres antes de se tornar denso demais para câmeras ruins lerem.
O QR Code Dinâmico muda o jogo. A Tag 26 não carrega a chave Pix, mas sim uma URL (sub-tag 25). Exemplo: pix.bcb.gov.br/qr/v2/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
Quando o aplicativo do banco lê esse QR Code, ele não sabe o valor da transação ou para quem vai o dinheiro. O app faz uma requisição HTTP GET (usando mTLS com certificados ICP-Brasil debaixo dos panos, através do DICT) para essa URL. O servidor da sua instituição de pagamento (como PagSeguro ou Adyen) responde com um JSON contendo o payload real (JWS - JSON Web Signature).
Isso permite que você altere o valor da cobrança, adicione juros, multas ou até cancele o QR Code após a geração, pois a fonte da verdade não está mais na imagem impressa, mas no servidor.
Gerando o QR Code Pix Programaticamente
Se você está construindo o backend de um e-commerce, o fluxo de geração deve seguir uma arquitetura defensiva.
Primeiro passo: Crie classes ou structs para representar os campos TLV. Nunca faça concatenação manual de strings do tipo string payload = "000201" + chave + valor. Isso é receita para o desastre. Se o nome do cliente tiver 16 caracteres e você chumbou um Length de 15 no código, o CRC vai bater, mas o parser do banco recebedor vai quebrar a leitura da Tag seguinte.
O código deve dinamicamente calcular o Length de cada Value no momento da montagem. Em linguagens modernas como Node.js, Python ou Go, certifique-se de contar o tamanho real em bytes ou caracteres corretamente (lembrando das regras de sanitização de UTF-8 do BACEN).
Após montar a árvore de tags, serialize a estrutura garantindo a ordem. O EMVCo não exige uma ordem estrita para a maioria das tags, exceto a 00 (que deve ser a primeira) e a 63 (que deve ser a última). No entanto, o BACEN recomenda uma sequência lógica que começa com os identificadores do arranjo e termina com os dados locais e de valor.
Implicações Práticas para Fintechs e E-commerces
Um payload EMVCo mal formatado tem consequências diretas no caixa da empresa. Monitoramos o comportamento de checkouts no Brasil e notamos que uma falha de leitura do Pix Copia e Cola resulta em 85% de abandono de carrinho imediato. O usuário não tenta de novo; ele desiste da compra.
Se você opera como um gateway, forneça SDKs que abstraiam essa complexidade para o seu cliente final. A Stripe e a Mercado Pago fazem isso com maestria. Eles não pedem para o lojista montar o TLV. Eles pedem o valor e a chave, e a engine interna cospe a string formatada e validada.
Outro ponto crítico é a conciliação via TXID (Tag 62). Muitos desenvolvedores geram TXIDs aleatórios e não os salvam no banco de dados antes de exibir o QR Code. Quando o webhook do BACEN (ou do seu provedor de BaaS) baté na sua API confirmando o pagamento daquele TXID, seu sistema não sabe de quem é a compra. O TXID deve ser tratado como uma chave primária temporária da intenção de compra.
O Futuro do Payload (Pix Automático e NFC)
O mercado hoje se prepara para o Pix Automático e as transações via aproximação (NFC). O payload EMVCo está sendo estendido para suportar essas modalidades.
No caso do Pix Aproximação, a string EMVCo não será passada via imagem lida por uma câmera, mas sim transmitida via radiofrequência (ISO 14443) da carteira digital (Apple Pay, Google Wallet) para o terminal POS. A estrutura TLV continuará a mesma, provando a resiliência da escolha arquitetural do BACEN em 2020.
Para o Pix Automático, novas sub-tags dentro do bloco de informações do recebedor estão sendo desenhadas para incluir os parâmetros de recorrência, limites de valor e datas de validade do mandato.
Dominar o parsing e a geração da específicação EMVCo do Pix não é apenas um requisito técnico para colocar um sistema no ar. É a fundação sobre a qual toda a inovação de pagamentos no Brasil está sendo construída. Quem entender as engrenagens desse código terá vantagem competitiva nas integrações complexas dos próximos anos.
Perguntas Frequentes
Matheus Feijão
CEO & Fundador — ouro.capital
Especialista em fintech e criptoativos desde 2002. CEO da ouro.capital.