# 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.

- Endereço oficial: https://pradev.com.br/guias/como-gerar-pix-copia-e-cola
- Tipo: Guia
- Publicado em: 2026-10-01
- Atualizado em: 2026-10-01
- Autor: Leonardo Gaertner (https://pradev.com.br/sobre)
- Ferramentas: [Gerador de QR Code PIX](https://pradev.com.br/gerador-de-qr-code-pix), [Validador de Chave PIX](https://pradev.com.br/validador-de-chave-pix)

## 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](https://pradev.com.br/gerador-de-qr-code-pix), e para conferir uma chave, o [validador de chave Pix](https://pradev.com.br/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](https://pradev.com.br/calcular-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);
}
```

_JavaScript_

## 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}"
```

_Python_

```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);
}
```

_PHP_

## 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.

## 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.

## Fontes

- [Banco Central: Pix](https://www.bcb.gov.br/estabilidadefinanceira/pix)
- [EMVCo: especificação de QR Codes](https://www.emvco.com/emv-technologies/qr-codes/)

## Guias relacionados

- [Dinheiro em código: formatar em reais (R$) sem erro de centavos](https://pradev.com.br/guias/como-formatar-dinheiro-em-reais): Como 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)](https://pradev.com.br/guias/como-repetir-requisicoes-com-backoff): 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.
