
PIX, BR Code e o EMVCo MPM: o QR que o Brasil Inteiro Usa
O QR code que levou um país para pagamentos instantâneos é EMV disfarçado. Uma decodificação campo a campo de um BR Code PIX real — a estrutura EMVCo Merchant-Presented Mode, o CRC16, estático versus dinâmico — e por que a mesma disciplina TLV dos cartões com chip cabe num guardanapo.
✨TL;DR / Sumário Executivo
O QR code que levou um país para pagamentos instantâneos é EMV disfarçado. Uma decodificação campo a campo de um BR Code PIX real — a estrutura EMVCo Merchant-Presented Mode, o CRC16, estático versus dinâmico — e por que a mesma disciplina TLV dos cartões com chip cabe num guardanapo.
💡 TL;DR (Too Long; Didn't Read)
O QR que move o Brasil, em 90 segundos:
- Um BR Code PIX não é um formato sob medida. É o padrão QR EMVCo Merchant-Presented Mode (MPM) — a mesma disciplina ID-Comprimento-Valor do TLV dos cartões com chip, mas em ASCII imprimível em vez de binário.
- Todo campo é ID de dois dígitos + comprimento de dois dígitos + valor.
00é o indicador de formato,26carrega a carga PIX (br.gov.bcb.pix+ a chave ou uma URL),54é o valor,59/60o recebedor,62o txid,63o checksum.- O último campo,
63, é um CRC16 (CCITT-FALSE, polinômio 0x1021, init 0xFFFF) calculado sobre a carga inteira, incluindo o literal6304— e errar esse escopo é o bug número um de integração PIX.- Códigos estáticos carregam a chave PIX e são reutilizáveis; códigos dinâmicos carregam uma URL para uma carga assinada, de uso único, gerada por cobrança.
- Se você leu as partes anteriores desta série, já conhece este formato. É exatamente esse o ponto.
Quero encerrar esta série em algum lugar que, à primeira vista, parece não ter nada a ver com cartões com chip. Sem terminal, sem APDU, sem criptograma — apenas um quadrado preto e branco impresso ao lado de um caixa, ou uma string colável numa mensagem de chat, que levou um país inteiro de 200 milhões de pessoas para pagamentos instantâneos em poucos anos. O BR Code PIX é o artefato de pagamento mais usado do Brasil. E também é, quando você olha por dentro, o mesmo EMV sobre o qual você vem lendo todo esse tempo, num disfarce muito eficaz.
Essa é a recompensa de Payments Under the Hood. A disciplina que governa uma transação com chip — dados estruturados, identificadores bem conhecidos, comprimentos explícitos, um checksum que você precisa calcular corretamente — não é específica de silício e leitoras de cartão. É como a indústria de pagamentos codifica instruções financeiras legíveis por máquina, ponto. O PIX prova isso tirando essa disciplina do chip e imprimindo-a num guardanapo. Tudo aqui segue a EMVCo QR Code Specification for Payment Systems, Merchant-Presented Mode, conforme perfilada pelo Banco Central do Brasil para o arranjo PIX. Cito a estrutura; não reproduzo o texto da especificação.
O formato é TLV que você consegue ler em voz alta
Lembre o BER-TLV da Parte 2: uma tag, um comprimento, um valor, aninhados e autodelimitados. O formato QR EMVCo MPM é a mesma ideia com duas simplificações deliberadas que o fazem sobreviver a ser impresso, fotografado e colado.
Primeiro, tudo é ASCII decimal, não binário. Um identificador são dois dígitos decimais. Um comprimento são dois dígitos decimais. O valor é texto literal. Sem mexer em bits, sem regra de continuação 0x1F, sem ambiguidade de comprimento curto-versus-longo — porque um QR code precisa tolerar a câmera de um celular e um app de mensagem, e binário não tolera. Segundo, a estrutura tem exatamente um ou dois níveis de profundidade, usando a mesma ideia de "alguns IDs são contêineres" que o EMV usa para templates construídos.
Então um campo se lê como ID | COMP | VALOR, concatenado com o próximo, repetidamente, até o checksum no fim. Aqui está um BR Code PIX estático completo e válido. Leia como um fluxo e vamos resolver cada campo:
00020126360014br.gov.bcb.pix0114+55619999999995204000053039865405
10.005802BR5913Fulano de Tal6008BRASILIA62070503***6304XXXX(Isso é uma string contínua; foi quebrada aqui apenas para caber na página.)
Decodificando, campo a campo
Percorra da esquerda para a direita, sempre lendo dois dígitos de ID, dois dígitos de comprimento, e então essa quantidade de caracteres de valor.
00 02 01 — Payload Format Indicator. ID 00, comprimento 2, valor 01. Todo BR Code começa aqui; o valor é sempre 01.
26 36 ... — Merchant Account Information. ID 26, comprimento 36. Este é um contêiner — seus 36 caracteres de valor são eles mesmos um conjunto de campos ID-comprimento-valor, exatamente como um template EMV construído:
0014br.gov.bcb.pix— o GUI, o identificador globalmente único que diz "esta é uma carga PIX". Quatorze caracteres, e precisa ser exatamente esta string.0114+5561999999999— a chave PIX. Aqui é uma chave de telefone; poderia igualmente ser um CPF/CNPJ, um e-mail ou uma chave aleatória EVP. A presença deste subcampo (ID01) é o que torna o código estático.
52 04 0000 — Merchant Category Code. MCC da ISO 18245; 0000 quando não especificado.
53 03 986 — Transaction Currency. ISO 4217 numérico; 986 é o real brasileiro. (Você já viu códigos de moeda ISO antes — eles também viajam dentro da entrada do MAC do ARQC. Mesmo código, envelope diferente.)
54 05 10.00 — Transaction Amount. Note que é texto: 10.00, uma string decimal, não um valor codificado em binário. Num código estático este campo é opcional — omita-o e o pagador digita o valor, que é como funciona um cartaz reutilizável de "minha chave PIX".
58 02 BR — Country Code. ISO 3166-1 alfa-2.
59 13 Fulano de Tal — Merchant Name. Até 25 caracteres.
60 08 BRASILIA — Merchant City. Até 15 caracteres.
62 07 0503*** — Additional Data Field Template. Outro contêiner. Dentro: 05 03 *** — o Reference Label, o campo que o PIX usa para o identificador da transação (txid). O valor *** é a convenção da especificação para "nenhum txid específico" num código estático; uma cobrança dinâmica ou itemizada coloca um identificador real aqui.
63 04 XXXX — CRC16. ID 63, comprimento 4, e o valor é um checksum de quatro dígitos hex que deixei deliberadamente como XXXX, porque a única coisa que você nunca deve fazer com um CRC é copiar um fabricado. Como calculá-lo é a próxima seção, e é onde a maioria das integrações PIX quebra.
O CRC16 que todo mundo erra
O campo final é um CRC16 e é a razão isolada mais comum pela qual um BR Code montado à mão ou montado errado falha ao ser escaneado. Três coisas precisam estar exatamente certas.
O algoritmo é o CRC-16/CCITT-FALSE: polinômio 0x1021, valor inicial 0xFFFF, sem reflexão de entrada nem de saída, sem XOR final. Pegue uma biblioteca genérica de "CRC16" e você provavelmente vai obter uma variante diferente (existem muitas) que produz um valor de quatro dígitos hex plausível que nenhum app PIX aceita.
O escopo é a armadilha. O CRC é calculado sobre a string inteira da carga incluindo o próprio ID e comprimento do campo de CRC — os caracteres literais 6 3 0 4 — mas excluindo os quatro caracteres do checksum em si. Em outras palavras: monte a string toda até e incluindo 6304, rode o CRC sobre isso, e anexe o resultado. Calcule sobre tudo-menos-6304, ou apenas sobre o valor, e você obtém uma resposta errada que falha silenciosamente no leitor.
A codificação é a última milha: o resultado são quatro caracteres hexadecimais maiúsculos, preenchidos com zero (então um valor de 0x0A1B se escreve 0A1B, e 0xB5 seria 00B5). Minúsculas ou sem preenchimento e, de novo, alguns leitores recusam.
crc = 0xFFFF
para cada byte b em carga_ate_e_incluindo("6304"):
crc = crc XOR (b << 8)
repita 8 vezes:
se crc & 0x8000: crc = (crc << 1) XOR 0x1021
senão: crc = crc << 1
crc = crc & 0xFFFF
resultado = hex_maiusculo(crc, largura=4) // anexe como valor do campo 63Esse é o checksum inteiro. É determinístico, é testável e — o tema recorrente desta série — é o tipo de coisa que você valida contra vetores conhecidos e nunca mais calcula à mão.
Estático versus dinâmico: a única bifurcação estrutural
Tudo acima era um código estático, e estático é o caso simples: a chave PIX fica no campo 26 sub-01, o valor pode ou não estar fixo, e o mesmo código pode ser escaneado mil vezes. É um cartaz na parede, um adesivo no balcão.
Um código dinâmico muda uma coisa e ela cascateia. Em vez da chave no sub-01, o campo 26 carrega uma URL no sub-25 — um endereço (sem o prefixo https://, que é implícito) apontando para o provedor de serviços de pagamento do recebedor. O campo de ponto de iniciação 01 é definido como 12 (dinâmico) em vez de 11 (estático). Quando o app do pagador lê o código, ele ainda não tem o suficiente para pagar; ele chama aquela URL e recupera uma carga assinada — um documento JWS do PSP — que contém o valor real, o txid verdadeiro, uma expiração e os dados do recebedor, assinado criptograficamente para não poder ser adulterado em trânsito.
Pare um momento nisso contra o resto da série. Um código PIX dinâmico é um ponteiro para uma instrução assinada, de uso único, específica da transação — o que é conceitualmente o mesmo movimento do ARQC (uma afirmação de uso único, vinculada à transação, protegida criptograficamente) e o mesmo movimento dos mandatos de pagamento por agente do texto-ponte. A indústria segue buscando a mesma forma: vincule a autorização a este pagamento, assine, torne de uso único. O PIX simplesmente faz isso com uma URL e um JWS em vez de uma chave de sessão e um MAC. Primitivas diferentes, instinto idêntico.
O copia-e-cola são os mesmos bytes
Um detalhe brasileiro adicional que confunde recém-chegados. O PIX é famoso pelo copia-e-cola — em que, em vez de mostrar um QR, você compartilha uma longa string de texto num chat. Engenheiros às vezes assumem que o copia-e-cola é um formato separado. Não é. A string do copia-e-cola é exatamente a carga do BR Code — o mesmo conteúdo 000201...6304XXXX que teria sido renderizado no QR — entregue como texto. O QR é apenas um transporte visual para essa string. Decodifique um copia-e-cola com a mesma caminhada de campos acima e ele resolve identicamente, checksum e tudo. Um formato, dois transportes.
Cicatrizes de batalha
O comprimento é em caracteres, não em bytes — até que seja em bytes. Para nomes de recebedor em ASCII puro o comprimento de dois dígitos equivale à contagem de caracteres e à contagem de bytes, e todos ficam felizes. Coloque um nome ou cidade com acento — SÃO PAULO — e o UTF-8 faz alguns caracteres ocuparem múltiplos bytes, e agora "comprimento em caracteres" e "comprimento em bytes" divergem. Erre a convenção de contagem e os limites de campo deslocam, corrompendo tudo depois dali. Decida explicitamente como seu gerador conta e teste com dados de recebedor não-ASCII, porque o Brasil tem muitos deles.
Um CRC válido sobre conteúdo errado ainda falha, silenciosamente. Como o CRC só prova que a string é internamente consistente, um BR Code com checksum correto sobre uma carga malformada vai passar sua checagem de checksum e ainda ser rejeitado pelo app pagador por uma razão de schema. O CRC é necessário, não suficiente. Valide estrutura e checksum, e não se deixe embalar por um sinal verde no CRC.
Códigos dinâmicos falham na URL, não no QR. Quando um código PIX dinâmico "não funciona", o QR normalmente está bem e o endpoint do PSP atrás do sub-25 é o problema — uma carga expirada, uma questão de TLS, uma assinatura que não verifica. Depure o fetch, não o quadrado.
A série fecha onde começou
Começamos inserindo um chip e vendo um terminal e um cartão negociarem uma transação sobre dados estruturados, com tags e prefixados por comprimento. Estamos terminando com um QR code no balcão de uma padaria — e ele é dado estruturado, com tags e prefixado por comprimento, com um checksum, seguindo uma especificação EMVCo, resolvível com exatamente a habilidade que construímos na Parte 2. Isso não é coincidência. É a tese: pagamentos são uma disciplina de codificação antes de serem qualquer outra coisa, e quando você consegue ler a codificação, o domínio inteiro deixa de ser uma caixa-preta — chip, contactless, ISO 8583, ou o QR com que um país inteiro paga.
Quando o gsstk lançar o Gerador e Validador de BR Code PIX, ele vai montar e checar exatamente a estrutura decodificada aqui — incluindo aquele CRC16 implacável sobre o escopo correto — no cliente, para que a string de pagamento nunca deixe seu navegador. Leia à mão uma vez para acreditar; use a ferramenta para nunca mais contar um comprimento errado.
Leitura Relacionada no gsstk
- O Que Realmente Acontece Quando Você Insere um Chip — Parte 1: onde esta série começou, inserindo um chip.
- Lendo BER-TLV à Mão — e Por Que Você Não Deveria — Parte 2: a mesma habilidade ID-comprimento-valor, em templates binários.
- ARQC a Partir do Zero: Criptogramas de Aplicação Sem Caixa-Preta — Parte 4: a afirmação assinada de uso único que um QR dinâmico espelha.
- Comércio Agêntico e o Retorno do HTTP 402 — o mesmo instinto "assinado, de uso único" para pagamentos por agentes.
Ferramentas: navegue pela suíte de ferramentas EMV e pelo Dicionário de Tags EMV; os analisadores de pinpad ABECS, específicos do Brasil, cobrem o lado do terminal. (Um Gerador/Validador de BR Code PIX no cliente — com o CRC16 no escopo correto — está no roadmap.)
Arquivado em: PIX · Payments · EMV · ABECS · Acquiring
Este artigo foi arquitetado por humanos e sintetizado com assistência de IA sob a persona Nexus (AI).