O CRC16 do Pix é o código de verificação que fecha todo BR Code: os 4 últimos caracteres do copia e cola, depois de 6304. O algoritmo é o CRC-16/CCITT-FALSE, com polinômio 0x1021 e valor inicial 0xFFFF, calculado sobre o texto inteiro até o 6304, inclusive. O resultado vai em hexadecimal, com 4 dígitos. Se um único caractere do código mudar, o CRC deixa de bater e o app do banco recusa a leitura. Para conferir um código sem programar, use o decodificador de Pix copia e cola.
O que o Banco Central define
O Manual BR Code diz que o campo 63 guarda os "4 nibbles" do resultado e que o cálculo usa o polinômio 1021 (hexa) com valor inicial FFFF (hexa). O Manual de Padrões para Iniciação do Pix acrescenta dois detalhes no exemplo de QR estático: o CRC é calculado incluindo 6304 (o ID 63 e o tamanho 04), e a ordem dos campos muda o resultado.
Os manuais citam o polinômio e o valor inicial. Os outros parâmetros são os do algoritmo conhecido como CRC-16/CCITT-FALSE, e o código abaixo reproduz o CRC dos exemplos oficiais.
| Parâmetro | Valor |
|---|---|
| Largura | 16 bits |
| Polinômio | 0x1021 |
| Valor inicial | 0xFFFF |
| Reflexão de entrada e de saída | Não |
| XOR final | 0x0000 |
Resultado para 123456789 |
29B1 |
A última linha é o teste clássico do algoritmo. Se a sua função não devolve 29B1 para o texto 123456789, ela está calculando outra variante.
Passo a passo
- Monte o código com todos os campos, do
00até o62, na ordem. - Acrescente
6304ao fim. - Calcule o CRC sobre o texto inteiro, incluindo o
6304. - Escreva o resultado em hexadecimal maiúsculo, com 4 dígitos, completando com zeros à esquerda.
- Acrescente esses 4 caracteres ao fim do texto.
Para validar, faça o caminho inverso: separe os 4 últimos caracteres, calcule o CRC do resto e compare.
Código em JavaScript
Funciona no navegador e no Node.js. O cálculo é feito sobre os bytes do texto em UTF-8; num código só com caracteres ASCII, como os exemplos oficiais, cada caractere é um byte.
function crc16(payload) {
let crc = 0xffff;
for (const byte of new TextEncoder().encode(payload)) {
crc ^= byte << 8;
for (let i = 0; i < 8; i++) {
crc = crc & 0x8000 ? ((crc << 1) ^ 0x1021) & 0xffff : (crc << 1) & 0xffff;
}
}
return crc.toString(16).toUpperCase().padStart(4, "0");
}
function crcConfere(brcode) {
if (!/6304[0-9A-Fa-f]{4}$/.test(brcode)) return false;
return crc16(brcode.slice(0, -4)) === brcode.slice(-4).toUpperCase();
}
// para fechar um código que você montou:
// const completo = semCrc + "6304" + crc16(semCrc + "6304");Código em Python
def crc16(payload: str) -> str:
crc = 0xFFFF
for byte in payload.encode("utf-8"):
crc ^= byte << 8
for _ in range(8):
crc = ((crc << 1) ^ 0x1021) if crc & 0x8000 else (crc << 1)
crc &= 0xFFFF
return f"{crc:04X}"
def crc_confere(brcode: str) -> bool:
if len(brcode) < 8 or brcode[-8:-4] != "6304":
return False
return crc16(brcode[:-4]) == brcode[-4:].upper()Teste com os exemplos oficiais
As duas funções foram testadas com Node.js e Python 3 contra os três exemplos publicados pelo Banco Central. Todos conferem:
| Exemplo | Fonte | CRC esperado | Resultado |
|---|---|---|---|
| QR estático com chave aleatória | Manual de Padrões para Iniciação do Pix, seção 2.6.3 | 1D3D |
Confere |
| QR dinâmico com URL | Manual de Padrões para Iniciação do Pix, seção 2.7.2 | 64E4 |
Confere |
| BR Code com três arranjos (270 caracteres) | Manual BR Code, seção 2.2 | AD38 |
Confere |
Use o primeiro como teste automatizado no seu projeto:
const exemplo =
"00020126580014br.gov.bcb.pix0136123e4567-e12b-12d1-a456-426655440000" +
"5204000053039865802BR5913Fulano de Tal6008BRASILIA62070503***63041D3D";
console.assert(crc16("123456789") === "29B1");
console.assert(crcConfere(exemplo) === true);
console.assert(crcConfere(exemplo.replace("BRASILIA", "BRASILIa")) === false);Cada campo e subcampo desse exemplo está explicado em estrutura do Pix copia e cola.
Erros comuns
Calcular sem o 6304. É o erro mais frequente. No exemplo estático, o CRC sem esses 4 caracteres dá 4AAD, e não 1D3D.
Espaços e quebras de linha. Código copiado de PDF, de e-mail ou de uma caixa de texto estreita costuma ganhar quebras de linha. Um espaço no fim, vindo de um formulário, também muda o cálculo. O cuidado oposto vale tanto quanto: não apague todos os espaços com uma expressão regular. O nome "Fulano de Tal" tem espaços que fazem parte do campo 59 e entram no tamanho e no CRC. Remova só o que foi inserido fora do código, como uma quebra de linha no fim.
Maiúsculas e zeros no hexadecimal. Em JavaScript, toString(16) devolve letras minúsculas e não completa com zeros: o valor 0x0A1B vira a1b. Por isso a função usa toUpperCase() e padStart(4, "0"). Em Python, o formato 04X resolve as duas coisas. Ao validar um código recebido, compare depois de passar os dois lados para maiúsculas.
Mudar a ordem dos campos. Dois códigos com os mesmos campos em ordem diferente têm CRCs diferentes. Se você monta o código, a ordem precisa ser a mesma usada no cálculo.
Usar outra variante de CRC16. Muitas bibliotecas chamam de "CRC16" algoritmos diferentes. Com o mesmo polinômio 0x1021, a variante XModem começa em 0x0000 e dá 31C3 para 123456789; a variante Kermit também começa em 0x0000, processa os bits na ordem inversa e dá 2189. Confira o teste do 29B1 antes de usar uma biblioteca pronta.
Calcular sobre caracteres em vez de bytes. Em JavaScript, charCodeAt devolve unidades de texto, e não bytes. Para texto só com ASCII o resultado coincide, mas o código acima usa TextEncoder para trabalhar sempre com bytes.
Quando você precisa calcular o CRC
Para receber, quase nunca. A API Pix da xFlow devolve o copia e cola pronto em pix.copyPaste, e a documentação pede que ele seja tratado como opaco: você repassa sem alterar e não recalcula nada. O passo a passo está em Pix copia e cola por API.
O CRC é útil quando o código vem de fora. No saque Pix por API, você pode enviar em qr_code um copia e cola de terceiro. Conferir o CRC antes da chamada pega um código cortado ou colado com quebra de linha antes de ele chegar à API, e a sua tela pode pedir ao usuário que copie de novo.
O CRC não é uma assinatura
O CRC detecta erro acidental, não fraude. Quem troca a chave de um QR Code calcula um CRC novo em segundos, e o código trocado passa em qualquer validação de CRC. Por isso, nunca libere um pedido porque um código "é válido". A confirmação vem da API, pelo webhook assinado ou pela consulta da cobrança, como mostra o guia como saber se o Pix foi pago pela API. A referência completa dos campos está na documentação da API.
Conteúdo informativo, atualizado em 25/10/2026. Não substitui orientação jurídica.
Perguntas frequentes
O cálculo do CRC do Pix inclui o 6304?
Sim. O ID 63 e o tamanho 04 entram no cálculo. O Manual de Padrões para Iniciação do Pix mostra o CRC do exemplo estático como 0x1D3D, incluindo 6304. Sem esses 4 caracteres, o mesmo exemplo daria 4AAD.
O CRC16 do Pix é o mesmo que o CRC16 XModem?
Não. Os dois usam o polinômio 0x1021, mas o XModem começa em 0x0000 e o Pix começa em 0xFFFF. Para a sequência 123456789, o algoritmo do Pix dá 29B1 e o XModem dá 31C3.
O hexadecimal do CRC é maiúsculo ou minúsculo?
Os exemplos oficiais do Banco Central usam letras maiúsculas, como 1D3D e 64E4. Gere em maiúsculas, com 4 dígitos, e ao validar compare sem diferenciar maiúsculas de minúsculas.
Um CRC válido prova que o Pix é verdadeiro?
Não. O CRC só detecta erro de cópia ou de digitação. Qualquer pessoa pode calcular um CRC válido para um código trocado. A confirmação do pagamento tem de vir da API.