Gerar QR Code Pix Sem Valor Fixo via API: guia para desenvolvedores
Quando usar Pix estático (sem código) vs API Pix dinâmica; e como implementar cada um.
Atualizado em
Precisa gerar QR Code Pix sem valor fixo via API? Este guia explica a diferença entre Pix estático (gerado no navegador, sem código) e Pix dinâmico via API do Banco Central; com endpoints, estrutura do payload e exemplos em Python e JavaScript.
Se você está integrando Pix em um sistema e precisa gerar QR Codes sem valor fixo; ou seja, onde o pagador define o valor; existem duas abordagens completamente diferentes, e a escolha errada vai gerar retrabalho.
Este guia explica cada opção com clareza e mostra como implementar a certa para o seu caso.
Resposta rápida: para gerar um QR Code Pix sem valor fixo via API, você tem dois caminhos: (1) montar um payload Pix estático no padrão BR Code EMV omitindo o campo de valor; o pagador digita quanto quer pagar, e isso não exige API nem servidor; ou (2) criar uma cobrança dinâmica via API Pix do seu banco ou PSP, quando você precisa de webhook de confirmação e conciliação por cobrança. Para a maioria dos casos de valor aberto (doações, balcão, gorjetas), o estático resolve com poucas linhas de código.
Dois tipos de QR Code Pix: estático e dinâmico
Antes de qualquer código, entenda a diferença fundamental:
| Pix Estático | Pix Dinâmico (API) | |
|---|---|---|
| Valor | Fixo ou aberto (pagador define) | Definido pelo emissor por cobrança |
| Geração | No navegador ou via biblioteca | Via API do banco/PSP |
| Exige conta/autenticação | Não | Sim (OAuth2 com certificado) |
| Webhook de confirmação | Não | Sim |
| Validade | Indefinida | Definida por cobrança |
| Caso de uso | Balcão, doações, cobranças simples | E-commerce, SaaS, recebíveis |
Se você só precisa de um QR Pix que o cliente preenche o valor, o Pix estático resolve sem uma linha de servidor; use o gerador de QR Code Pix do GeraCode ou gere o payload via biblioteca client-side.
Se você precisa rastrear cada cobrança individualmente, confirmar automaticamente o pagamento ou gerar cobranças com dados do pagador (CPF, data de vencimento, juros), aí você precisa da API Pix dinâmica.
Opção 1: Pix estático sem valor fixo (sem API)
O Pix estático com valor em branco já resolve o caso de "o pagador digita o valor". O payload BR Code EMV é gerado inteiramente no front-end; não precisa de servidor nem autenticação.
Estrutura do payload BR Code EMV
O payload segue a especificação EMV QRCPS-MPM (abre em nova aba) do Banco Central. Os campos obrigatórios para um Pix estático sem valor:
000201 → Payload Format Indicator (fixo)
010212 → Point of Initiation: 12 = reutilizável (estático)
2658 → Merchant Account Information
0014br.gov.bcb.pix → GUI do Pix
0114+5511999999999 → Chave Pix (ex: telefone)
52040000 → Merchant Category Code (0000 = genérico)
5303986 → Transaction Currency (986 = BRL)
5802BR → Country Code
5913Nome Recebedor → Merchant Name (max 25 chars)
6009Sao Paulo → Merchant City
62070503*** → Additional Data (txid mínimo)
6304XXXX → CRC16 (calculado sobre tudo acima)O campo de valor (54) simplesmente é omitido, e o app do banco exibe "valor a definir pelo pagador".
Gerando o payload em JavaScript
function gerarPixEstatico({ chave, nome, cidade, txid = '***' }) {
const gui = 'br.gov.bcb.pix';
const merchant = `0014${gui}${String(chave.length).padStart(2,'0')}${chave}`;
const merchantInfo = `26${String(merchant.length).padStart(2,'0')}${merchant}`;
const additionalData = `6207${String(`0503${txid}`.length).padStart(2,'0')}0503${txid}`;
const nomeFmt = nome.substring(0, 25);
const cidadeFmt = cidade.substring(0, 15);
let payload = [
'000201',
'010212',
merchantInfo,
'52040000',
'5303986',
// sem campo 54 (valor) = valor aberto
'5802BR',
`59${String(nomeFmt.length).padStart(2,'0')}${nomeFmt}`,
`60${String(cidadeFmt.length).padStart(2,'0')}${cidadeFmt}`,
additionalData,
'6304',
].join('');
return payload + crc16(payload);
}O CRC16 usa o polinômio 0x1021 (CCITT). O GeraCode calcula automaticamente; se quiser apenas gerar o QR sem código, use a ferramenta diretamente.
Opção 2: Pix dinâmico via API do Banco Central
A API Pix oficial é definida pelo Banco Central e implementada por cada banco/PSP (PagSeguro, Mercado Pago, Sicoob, Itaú, etc.). Cada um tem seu endpoint base, mas o contrato da API é padronizado.
Autenticação
A API Pix exige mTLS (certificado digital do cliente) + OAuth2 com fluxo client_credentials. Você precisa:
- Certificado digital emitido por AC credenciada pelo ICP-Brasil (e.g., Certisign, Serasa); ou o certificado sandbox do banco para testes.
- Credenciais OAuth2 fornecidas pelo banco ao abrir a conta de desenvolvedor.
curl --cert client.crt --key client.key \
-X POST https://api.banco.com.br/oauth/token \
-d "grant_type=client_credentials&scope=cob.write cob.read"Criando uma cobrança sem valor fixo
Para gerar QR Pix dinâmico com valor em aberto, você cria uma cobrança do tipo cob com o campo valor.original definido. Não existe cobrança dinâmica sem valor; essa é uma diferença importante em relação ao estático.
Se o valor é realmente variável por natureza (doações, gorjetas), o Pix estático é a resposta certa. O dinâmico serve para quando você define o valor programaticamente, mas cada cobrança tem um valor específico.
import httpx
BASE_URL = "https://api.banco.com.br/v2"
TOKEN = "seu_access_token"
def criar_cobranca_pix(valor: str, descricao: str, cpf_pagador: str = None):
payload = {
"calendario": {"expiracao": 3600}, # 1 hora
"valor": {"original": valor}, # ex: "29.90"
"chave": "sua-chave-pix@email.com",
"solicitacaoPagador": descricao,
}
if cpf_pagador:
payload["devedor"] = {"cpf": cpf_pagador, "nome": "Pagador"}
resp = httpx.post(
f"{BASE_URL}/cob",
json=payload,
headers={"Authorization": f"Bearer {TOKEN}"},
)
resp.raise_for_status()
data = resp.json()
# O QR Code vem em data["pixCopiaECola"] (texto) ou via endpoint /qrcode
return data["txid"], data["pixCopiaECola"]Consultando o status do pagamento
def consultar_cobranca(txid: str):
resp = httpx.get(
f"{BASE_URL}/cob/{txid}",
headers={"Authorization": f"Bearer {TOKEN}"},
)
data = resp.json()
# status: "ATIVA", "CONCLUIDA", "REMOVIDA_PELO_USUARIO_RECEBEDOR", etc.
return data["status"], data.get("pix", [])Webhook de confirmação
Para receber notificações automáticas de pagamento (sem polling), configure o webhook:
def configurar_webhook(url_webhook: str):
resp = httpx.put(
f"{BASE_URL}/webhook/sua-chave-pix@email.com",
json={"webhookUrl": url_webhook},
headers={"Authorization": f"Bearer {TOKEN}"},
)
resp.raise_for_status()O banco vai enviar um POST para sua URL a cada pagamento confirmado, com o txid e os dados da transação.
Qual usar no meu projeto?
| Cenário | Usar |
|---|---|
| QR Code no balcão / cardápio | Pix estático sem valor |
| Doações / valor livre | Pix estático sem valor |
| Checkout de e-commerce com valor definido | Pix dinâmico via API |
| Assinatura / cobrança recorrente programática | Pix dinâmico via API |
| Confirmar pagamento automaticamente | Pix dinâmico via API |
| Sem servidor / front-end puro | Pix estático (obrigatório) |
Sandboxes e ambientes de teste
Cada banco tem seu próprio sandbox. Os mais usados por desenvolvedores:
- Banco Central (simulador oficial): sandbox em
pix.api.bcb.gov.br, ideal para validar o contrato da API antes de ir para produção. - Sicoob, Bradesco, Itaú, Inter: cada um disponibiliza sandbox via portal do desenvolvedor.
- EfiPay (Gerencianet): sandbox bem documentado e popular entre devs independentes.
Do payload à imagem: gerando o QR Code
O payload BR Code é só o texto. Para virar QR Code escaneável, qualquer biblioteca de QR genérica resolve; o conteúdo do QR é a string do payload, sem prefixo nem encoding especial.
Em JavaScript, com a lib qrcode:
import QRCode from 'qrcode';
const payload = gerarPixEstatico({
chave: 'sua-chave@email.com',
nome: 'Minha Loja',
cidade: 'Sao Paulo',
});
// PNG em data URL, pronto para <img src>
const dataUrl = await QRCode.toDataURL(payload, {
errorCorrectionLevel: 'M',
width: 512,
});Em Python, com qrcode:
import qrcode
img = qrcode.make(payload, error_correction=qrcode.constants.ERROR_CORRECT_M)
img.save("pix.png")Nível de correção M (15%) é o padrão recomendado para Pix; L funciona mas tolera menos dano na impressão, e H só faz sentido se você for sobrepor logo no centro.
Erros comuns ao montar o payload estático
Quatro erros respondem por quase todo QR Pix que "o banco não lê":
- CRC16 errado. O CRC é calculado sobre o payload inteiro incluindo o
6304final (sem os 4 dígitos do próprio CRC). Polinômio 0x1021, valor inicial 0xFFFF, sem reflexão. Se o app do banco recusa o código na hora, comece por aqui. - Acentos e caracteres especiais. Os campos
59(nome) e60(cidade) devem usar apenas ASCII: "São Paulo" viraSao Paulo. Acento no payload quebra a leitura em vários bancos. - Tamanho declarado diferente do real. Cada campo declara o próprio tamanho em 2 dígitos. Se você truncar o nome para 25 caracteres mas declarar o tamanho antigo, o parser desalinha e tudo depois do campo fica corrompido.
- Chave de telefone sem o formato certo. Telefone como chave Pix precisa do prefixo internacional:
+5511999999999. Sem o+55, alguns bancos tratam a chave como inexistente.
Para conferir um payload gerado por código, escaneie com o app do banco em modo "Pix copia e cola" antes de publicar; ou compare com a saída do gerador do GeraCode usando os mesmos dados.
Boas práticas de segurança na API Pix
Se você foi pelo caminho da API dinâmica, três cuidados evitam os incidentes mais comuns:
- Nunca exponha credenciais no front-end. O fluxo
client_credentialse o certificado mTLS vivem só no servidor. Se o QR precisa aparecer no navegador, gere a cobrança no backend e envie apenas opixCopiaEColapara o cliente. - Valide o webhook antes de dar baixa. O POST de confirmação deve chegar via mTLS do banco; confira o certificado do cliente e, em caso de dúvida, consulte
GET /cob/{txid}antes de marcar o pedido como pago. Webhook forjado é o golpe clássico contra integração Pix mal feita. - Trate o
txidcomo idempotência. Reenvios de webhook acontecem. Guarde otxidprocessado e ignore duplicatas, senão um mesmo pagamento pode liberar dois pedidos.
Próximos passos
- Para gerar QR Code estático agora sem código: use o gerador de QR Code Pix gratuito.
- Para entender a diferença completa entre os dois tipos: Pix estático vs dinâmico.
- Para MEIs e pequenos negócios sem sistema: como receber Pix como MEI.
Esse guia foi útil?
Perguntas Frequentes
Qual é a diferença entre QR Code estático e dinâmico?
O QR Code estático, gerado aqui, é fixo e pode ser usado múltiplas vezes. O QR Code dinâmico é gerado pela API do banco para cada cobrança, com controle de pagamento e notificação automática.
O QR Code Pix gerado aqui é válido?
Sim. O payload segue o padrão BR Code EMV definido pelo Banco Central do Brasil. O QR Code é testado com o algoritmo CRC16 e funciona em todos os bancos participantes do Pix.
Meus dados ficam salvos em algum servidor?
Não. Todo o processamento acontece no seu navegador (client-side). Nenhum dado (chave Pix, nome, valor) é enviado para servidores externos.
O gerador funciona para Pix com CPF, CNPJ, e-mail e telefone?
Sim, todos os tipos de chave Pix são suportados: CPF, CNPJ, e-mail, telefone (com +55) e chave aleatória (UUID).
Mais artigos sobre QR Code Pix
Outras ferramentas
Código de Barras
EAN-13, Code 128, ITF-14 e 12+ formatos
EAN-13 / EAN-8
Códigos EAN para produtos e varejo
QR Code
QR Code para links, textos e conteúdos
Leitor de Código de Barras
Leia códigos pela câmera, sem app
Leitor de QR Code
Escaneie QR Codes pela câmera, sem app
Gerador de SKU
Crie SKUs padronizados para estoque