Skip to content

thiagozs/go-pixgen

Repository files navigation

Go-PixGen

pix-utils

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.

Funcionalidades

  • Geração de payloads Pix estáticos (copia e cola) e dinâmicos (com URL).
  • CLI pixgen com comandos generate e serve para uso local ou como serviço.
  • Serviço REST com POST /pix retornando payload + QR Code (base64) e GET /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.

Instalação

go get github.com/thiagozs/go-pixgen

Requer Go 1.17 ou superior.

Guia rápido

CLI - gerar payload no terminal

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 1

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

Serviço REST

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"
  }' | jq

Uso em código

Gerar payload Pix programaticamente

opts := []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)

Fetch a dynamic Pix payload

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)

Destaques da API

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

Formatos aceitos de chave Pix

  • 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 e TxID

  • Valor suporta até 13 dígitos antes da vírgula e 2 casas decimais (9999999999999.99 limite).
  • 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.

Busca de payload dinâmico

FetchDynamicPayload entende:

  • payload EMV bruto (text/*).
  • JSON com campos como pixCopyPaste, pix, payload, pixCopiaECola etc.
  • 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.

Build & Docker

  • make build, make test, make fmt
  • make cli compila o binário em bin/pixgen
  • make run ARGS="serve --addr :8080" executa o servidor REST local
  • make docker-build && make docker-run constroem e sobem a imagem (porta 8080)

Roadmap

  • 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

Contribuindo

Siga o GitHub Flow: crie uma branch, faça commits e abra um pull request.

Versionamento e licença

Utilizamos SemVer. Confira as versões em tags. Licença em LICENSE.

2022, Thiago Zilli Sarmento ❤️

Sponsor this project

 

Packages

No packages published