Como gerar PIX copia e cola (BR Code) em código

O PIX copia e cola é um texto no padrão BR Code, o mesmo que vira o QR Code de pagamento. Para uma cobrança simples, com chave fixa e valor opcional, dá para gerá-lo sem API do banco. Este guia explica os campos, o CRC16 do final e os erros que fazem o aplicativo do banco recusar o código, com exemplos em JavaScript, Python e PHP que reproduzem o exemplo oficial do Banco Central.

Por Leonardo Gaertner · Publicado em

Estático ou dinâmico?

  • Estático: tem a chave PIX, o nome e a cidade de quem recebe, e pode ter valor e um identificador. Você mesmo monta o código, como neste guia.
  • Dinâmico: tem uma URL do banco, que devolve os dados da cobrança na hora. Só o banco gera, pela API PIX dele, e é o que permite vencimento, juros e confirmação automática.

O código estático não avisa quando foi pago. Para confirmar o pagamento, você consulta o extrato ou a API do banco, e o identificador da cobrança (txid) ajuda a encontrar o pagamento certo. Para gerar o código e o QR Code sem programar, use o gerador de QR Code Pix, e para conferir uma chave, o validador de chave Pix.

Como o código é montado

O BR Code segue o padrão EMV de QR Codes: uma sequência de campos, cada um com um ID de 2 dígitos, o tamanho com 2 dígitos e o valor. 5802BR é o campo 58 (país), com 2 caracteres, valendo BR. Alguns campos têm outros campos dentro, como o 26, que guarda o domínio br.gov.bcb.pix e a chave.

  • 00 versão (01), 26 conta PIX, 52 categoria do comerciante (0000), 53 moeda (986, o real), 54 valor (opcional), 58 país, 59 nome (até 25 caracteres), 60 cidade (até 15), 62 identificador da cobrança.
  • 63 CRC16: os 4 últimos caracteres. Ele é calculado sobre todo o texto anterior, incluindo o próprio 6304.
  • O CRC é o CRC16-CCITT, com polinômio 0x1021 e valor inicial 0xFFFF. É outro cálculo, diferente do CRC32 dos arquivos ZIP.

Em JavaScript

Com a chave 123e4567-e12b-12d1-a456-426655440000, o nome "Fulano de Tal" e a cidade "BRASILIA", a função gera exatamente o código do exemplo do manual do Banco Central, terminado em 63041D3D.

JavaScript
// Cada campo do BR Code: ID com 2 dígitos + tamanho com 2 dígitos + valor
const campo = (id, valor) => `${id}${String(valor.length).padStart(2, '0')}${valor}`;

// Nome e cidade sem acentos: o tamanho de cada campo é contado em caracteres simples
const semAcento = (s) => s.normalize('NFD').replace(/[̀-ͯ]/g, '');

// CRC16-CCITT (polinômio 0x1021, valor inicial 0xFFFF), em 4 dígitos hexadecimais
function crc16(texto) {
  let crc = 0xffff;
  for (const byte of new TextEncoder().encode(texto)) {
    crc ^= byte << 8;
    for (let i = 0; i < 8; i++) crc = (crc & 0x8000 ? (crc << 1) ^ 0x1021 : crc << 1) & 0xffff;
  }
  return crc.toString(16).toUpperCase().padStart(4, '0');
}

function pixCopiaECola({ chave, nome, cidade, valor, txid = '***' }) {
  const conta = campo('00', 'br.gov.bcb.pix') + campo('01', chave);
  const payload =
    campo('00', '01') + // versão do formato
    campo('26', conta) + // dados da conta: o domínio do PIX e a chave
    campo('52', '0000') + // categoria do comerciante (0000 = não informada)
    campo('53', '986') + // moeda: real
    (valor ? campo('54', valor.toFixed(2)) : '') + // sem valor, quem paga digita
    campo('58', 'BR') +
    campo('59', semAcento(nome).slice(0, 25)) +
    campo('60', semAcento(cidade).slice(0, 15)) +
    campo('62', campo('05', txid)) + // identificador da cobrança
    '6304'; // o CRC entra no fim e também é calculado sobre este "6304"
  return payload + crc16(payload);
}

Em Python e PHP

No Python, o binascii.crc_hqx com valor inicial 0xFFFF já faz o CRC16 do PIX. As três versões geram o mesmo código.

Python
import binascii
import unicodedata


def _campo(id_: str, valor: str) -> str:
    return f"{id_}{len(valor):02d}{valor}"


def _sem_acento(s: str) -> str:
    return "".join(c for c in unicodedata.normalize("NFD", s) if not unicodedata.combining(c))


def pix_copia_e_cola(
    chave: str, nome: str, cidade: str, valor: float | None = None, txid: str = "***"
) -> str:
    conta = _campo("00", "br.gov.bcb.pix") + _campo("01", chave)
    payload = (
        _campo("00", "01")
        + _campo("26", conta)
        + _campo("52", "0000")
        + _campo("53", "986")
        + (_campo("54", f"{valor:.2f}") if valor else "")
        + _campo("58", "BR")
        + _campo("59", _sem_acento(nome)[:25])
        + _campo("60", _sem_acento(cidade)[:15])
        + _campo("62", _campo("05", txid))
        + "6304"
    )
    # crc_hqx com valor inicial 0xFFFF é o CRC16-CCITT que o PIX usa
    return payload + f"{binascii.crc_hqx(payload.encode(), 0xFFFF):04X}"
PHP
<?php
function campoPix(string $id, string $valor): string
{
    return $id . str_pad((string) strlen($valor), 2, '0', STR_PAD_LEFT) . $valor;
}

function crc16Pix(string $texto): string
{
    $crc = 0xFFFF;
    foreach (str_split($texto) as $c) {
        $crc ^= ord($c) << 8;
        for ($i = 0; $i < 8; $i++) {
            $crc = ($crc & 0x8000 ? ($crc << 1) ^ 0x1021 : $crc << 1) & 0xFFFF;
        }
    }
    return sprintf('%04X', $crc);
}

function pixCopiaECola(
    string $chave,
    string $nome,
    string $cidade,
    ?float $valor = null,
    string $txid = '***'
): string {
    // Nome e cidade sem acentos (Normalizer vem da extensão intl)
    $semAcento = fn($s) => preg_replace(
        '/\p{Mn}/u',
        '',
        Normalizer::normalize($s, Normalizer::FORM_D)
    );
    $conta = campoPix('00', 'br.gov.bcb.pix') . campoPix('01', $chave);
    $payload = campoPix('00', '01') . campoPix('26', $conta)
        . campoPix('52', '0000') . campoPix('53', '986')
        . ($valor ? campoPix('54', number_format($valor, 2, '.', '')) : '')
        . campoPix('58', 'BR')
        . campoPix('59', substr($semAcento($nome), 0, 25))
        . campoPix('60', substr($semAcento($cidade), 0, 15))
        . campoPix('62', campoPix('05', $txid))
        . '6304';
    return $payload . crc16Pix($payload);
}

Os erros que fazem o banco recusar

  • Chave de telefone sem o formato internacional: use +5511912345678, não (11) 91234-5678. CPF e CNPJ vão só com os dígitos.
  • Tamanho do campo contado errado: um acento ocupa mais de um byte em alguns sistemas. Por isso os exemplos tiram os acentos do nome e da cidade.
  • Valor com vírgula (10,50): o campo 54 usa ponto e duas casas, 10.50.
  • Identificador (txid) com espaço ou símbolo: use até 25 letras e números, ou *** quando não houver.
  • Para o QR Code, gere a imagem a partir do texto com uma biblioteca de QR Code. O texto é o mesmo do copia e cola.

Achou um erro neste guia? Avise por e-mail.

Perguntas frequentes

Dá para gerar PIX copia e cola sem a API do banco?

Sim, no formato estático: com a chave, o nome, a cidade e, se quiser, o valor. A cobrança dinâmica, com vencimento e confirmação automática, só o banco gera.

O que é o CRC no final do PIX copia e cola?

São 4 caracteres hexadecimais que conferem se o código chegou inteiro. É um CRC16-CCITT calculado sobre todo o texto anterior, incluindo o 6304. Se um caractere mudar, o aplicativo do banco recusa o código.

Como saber se o PIX estático foi pago?

O código estático não avisa. Consulte o extrato ou a API do seu banco e use o identificador da cobrança (txid) para encontrar o pagamento.

Qual o formato da chave PIX de telefone no código?

O formato internacional, com +55, o DDD e o número, sem espaços nem símbolos: +5511912345678.