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.
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.
00versão (01),26conta PIX,52categoria do comerciante (0000),53moeda (986, o real),54valor (opcional),58país,59nome (até 25 caracteres),60cidade (até 15),62identificador da cobrança.63CRC16: os 4 últimos caracteres. Ele é calculado sobre todo o texto anterior, incluindo o próprio6304.- O CRC é o CRC16-CCITT, com polinômio
0x1021e valor inicial0xFFFF. É 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.
// 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.
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
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 campo54usa 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.
Outros guias
- Dinheiro em código: formatar em reais (R$) sem erro de centavosComo formatar valores em reais em JavaScript, Python e PHP, por que 0,1 + 0,2 não dá 0,3 e como dividir em parcelas sem perder centavos, com código testado.
- Como repetir requisições com backoff exponencial (retry)Como repetir chamadas de API que falham com backoff exponencial e jitter, quais erros vale repetir e como não cobrar duas vezes, em JavaScript, Python e PHP.