release: Ultima versão do manual v2.9.0
Gere e valide pagamentos do Sistema de Pagamentos Instantâneo (Pix) do Banco Central de forma simples. Além da biblioteca, este repositório inclui um CLI e um serviço REST para gerar payloads Pix estáticos ou dinâmicos, bem como seus códigos QR.
- Geração de payloads Pix estáticos (copia e cola) e dinâmicos (com URL).
- CLI pixgencom comandosgenerateeservepara uso local ou como serviço.
- Serviço REST com POST /pixretornando payload + QR Code (base64) eGET /healthz.
- Geração de QR Code via github.com/skip2/go-qrcode.
- Utilitários de parsing EMV para inspeção de tags e metadados.
- Normalização de dados (chave Pix, valor, TxID) seguindo regras do BACEN.
- Resolução de Pix dinâmico suportando JSON, texto puro e tratamento de expiração.
go get github.com/thiagozs/go-pixgenRequer Go 1.17 ou superior.
make cli
bin/pixgen generate \
  --kind static \
  --key +5511999999999 \
  --merchant-name "Thiago Zilli Sarmento" \
  --merchant-city ARARANGUA \
  --amount 10.00 \
  --description "Pedido 123" \
  --txid PEDIDO-123 \
  --ascii-scale 1A saída inclui o código copia-e-cola, campos relevantes, o QR Code em base64 e a versão em ASCII. Use --ascii-scale (>=1), --ascii-quiet=true para recolocar a borda de silêncio e --ascii-black/--ascii-white para personalizar o render em terminal.
Para QR Codes dinâmicos, lembre-se de informar --url https://... e um --txid alfanumérico (até 25 caracteres); o payload emitido trará a URL (tag 25) e *** no campo TxID conforme o manual.
make run ARGS="serve --addr :8080"
curl -X POST http://localhost:8080/pix \
  -H "Content-Type: application/json" \
  -d '{
    "kind": "static",
    "pixKey": "+5511999999999",
    "merchantName": "Thiago Zilli Sarmento",
    "merchantCity": "ARARANGUA",
    "amount": "10.00",
    "description": "Pedido 123",
    "txid": "PEDIDO-123"
  }'{
  "payload": "000201...",
  "qrCode": "iVBORw0KGgoAAA...",
  "kind": "STATIC",
  "txid": "PEDIDO-123"
}O endpoint GET /healthz retorna 200 OK para checagens.
Exemplo com curl + jq para visualizar a resposta:
curl -sS -X POST http://localhost:8080/pix \
  -H 'Content-Type: application/json' \
  -d '{
    "kind": "dynamic",
    "url": "https://example.com/api/pix/abc",
    "merchantName": "Fulano de Tal",
    "merchantCity": "CURITIBA",
    "amount": "25.00",
    "txid": "DINAMICO-001"
  }' | jqopts := []pix.Options{
	pix.OptPixKey("+5511955555555"),
	pix.OptDescription("Teste"),
	pix.OptMerchantName("Thiago Zilli Sarmento"),
	pix.OptMerchantCity("Ararangua"),
	pix.OptAmount("1.00"),
	pix.OptAdditionalInfo("gerado por go-pixgen"),
	pix.OptKind(pix.STATIC),
}
p, err := pix.New(opts...)
if err != nil {
	fmt.Println(err.Error())
	return
}
cpy, err := p.GenPayload()
if err != nil {
	fmt.Println(err.Error())
	return
}
fmt.Printf("Copy and Paste: %s\n", cpy)
qrPNG, err := p.GenQRCode()
if err != nil {
	fmt.Println(err.Error())
	return
}
fmt.Printf("QRCode bytes: %d\n", len(qrPNG))
asciiQR, err := p.GenQRCodeASCII()
if err != nil {
	fmt.Println(err.Error())
	return
}
fmt.Println(asciiQR)
parsed, err := pix.ParsePayload(cpy)
if err != nil {
	fmt.Println(err.Error())
	return
}
fmt.Printf("Kind: %s | TxID: %s\n", parsed.Kind(), parsed.AdditionalDataField.TxID)ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
dynamicOpts := []pix.Options{
	pix.OptKind(pix.DYNAMIC),
	pix.OptUrl("https://my-provider.example/api/pix/123"),
	pix.OptMerchantName("Fulano de Tal"),
	pix.OptMerchantCity("CURITIBA"),
}
dyn, err := pix.New(dynamicOpts...)
if err != nil {
	fmt.Println(err)
	return
}
payload, err := dyn.FetchDynamicPayload(ctx, nil)
if err != nil {
	fmt.Println(err)
	return
}
fmt.Printf("Remote Pix expires at: %v\n", payload.ExpiresAt)- pix.New(opts...) (*pix.Pix, error)- cria um gerador Pix configurável.
- (*Pix).GenPayload() (string, error)- retorna o payload EMV e o mantém em cache para- GenQRCode().
- pix.ParsePayload(string) (*ParsedPayload, error)- faz o parsing do payload e valida o CRC.
- (*Pix).FetchDynamicPayload(ctx, client)- baixa, valida e parseia payloads dinâmicos remotos.
- (*Pix).Validates()- valida os parâmetros (chaves, tamanho de campos, etc.).
- (*Pix).GenQRCodeASCII() (string, error)- renderiza o QR Code em ASCII para uso direto no terminal.
- pix.OptQRCodeScale,- pix.OptASCIIQuietZone,- pix.OptASCIICharset- controlam escala, borda e caracteres usados no QR ASCII.
- EVP (UUID) - normalizado para minúsculo.
- Telefone (+55DDDNÚMERO) - aceita apenas dígitos com ou sem+55.
- CPF/CNPJ - somente dígitos, com validação dos dígitos verificadores.
- E-mail - validado via net/mail.
- Valor suporta até 13 dígitos antes da vírgula e 2 casas decimais (9999999999999.99limite).
- TxID (estático ou dinâmico) deve ser alfanumérico (A-Z, 0-9) e ter no máximo 25 caracteres. No caso estático, deixe em branco para que o payload utilize ***; no dinâmico, o QR Code continua transportando***enquanto a URL carrega os dados da cobrança.
FetchDynamicPayload entende:
- payload EMV bruto (text/*).
- JSON com campos como pixCopyPaste,pix,payload,pixCopiaEColaetc.
- Campos de expiração (expiresAt,expiration,expiry) em formatos RFC3339.
Para testes locais, URLs HTTP são aceitas quando o host é localhost ou 127.*; para produção exige HTTPS.
- make build,- make test,- make fmt
- make clicompila o binário em- bin/pixgen
- make run ARGS="serve --addr :8080"executa o servidor REST local
- make docker-build && make docker-runconstroem e sobem a imagem (porta 8080)
-  Gerar pagamentos a partir de parâmetros
- Estático
- Dinâmico
 
- Parse e validação de códigos EMV
- Exportar pagamento para imagem
- Exportar pagamento para código EMV
-  Buscar, parsear e validar payloads dinâmicos remotos
- Verificar se já expirou
 
- Melhorar testes
- Documentação completa (métodos, parâmetros, exemplos)
- Testes para pagamentos dinâmicos
- Ferramentas CLI para inspeção de payload
- Endurecimento da API REST e opções de autenticação
Siga o GitHub Flow: crie uma branch, faça commits e abra um pull request.
Utilizamos SemVer. Confira as versões em tags. Licença em LICENSE.
2022, Thiago Zilli Sarmento ❤️
