PIX BR Code Parser
Uma biblioteca Rust para análise e validação de códigos QR PIX (BR Code) brasileiros seguindo o padrão EMV QRCPS.

Características
- ✅ Análise de códigos QR PIX estáticos e dinâmicos
- ✅ Validação de conformidade com EMV QRCPS
- ✅ Validação de checksum CRC16
- ✅ API ergonômica com structs tipadas
- ✅ Suporte opcional ao serde para serialização
- ✅ Análise zero-allocation para aplicações críticas de performance
- ✅ Geração de códigos QR PIX
- ✅ Classificação automática de tipos de chave PIX
Instalação
Adicione ao seu Cargo.toml
:
[dependencies]
pix-brcode-parser = "0.1.0"
pix-brcode-parser = { version = "0.1.0", features = ["serde"] }
Uso Rápido
Analisando um Código QR PIX
use pix_brcode_parser::{parse_brcode, BRCodeError};
fn main() {
let qr_string = "00020126580014br.gov.bcb.pix0136123e4567-e12b-12d1-a456-426614174000520400005303986540510.005802BR5913FULANO DE TAL6008BRASILIA62070503***630436D9";
match parse_brcode(qr_string) {
Ok(brcode) => {
println!("✅ Código PIX válido!");
println!("Chave PIX: {}", brcode.merchant_account_info.pix_key);
println!("Tipo da Chave: {:?}", brcode.pix_key_type());
println!("Comerciante: {}", brcode.merchant_name);
println!("Cidade: {}", brcode.merchant_city);
if let Some(amount) = &brcode.transaction_amount {
println!("Valor: R$ {}", amount);
} else {
println!("Valor: A ser definido pelo usuário");
}
println!("Tipo: {}", if brcode.is_static() { "Estático" } else { "Dinâmico" });
}
Err(e) => {
eprintln!("❌ Erro ao analisar código PIX: {}", e);
}
}
}
Gerando um Código QR PIX
use pix_brcode_parser::{BRCode, MerchantAccountInfo, generate_brcode};
fn main() {
let brcode = BRCode {
payload_format_indicator: "01".to_string(),
point_of_initiation_method: Some("11".to_string()), merchant_account_info: MerchantAccountInfo {
gui: "br.gov.bcb.pix".to_string(),
pix_key: "user@example.com".to_string(),
description: Some("Pagamento por serviços".to_string()),
url: None,
},
merchant_category_code: "0000".to_string(),
transaction_currency: "986".to_string(), transaction_amount: Some("25.50".to_string()),
country_code: "BR".to_string(),
merchant_name: "ACME CORP".to_string(),
merchant_city: "SAO PAULO".to_string(),
additional_data: None,
crc16: String::new(), };
match generate_brcode(&brcode) {
Ok(qr_string) => {
println!("Código QR gerado: {}", qr_string);
}
Err(e) => {
eprintln!("Erro ao gerar código: {}", e);
}
}
}
Exemplos de Códigos PIX
Código PIX Estático com Valor Fixo
let static_qr = "00020126580014br.gov.bcb.pix0136123e4567-e12b-12d1-a456-426614174000520400005303986540510.005802BR5913FULANO DE TAL6008BRASILIA62070503***630436D9";
let brcode = parse_brcode(static_qr).unwrap();
assert_eq!(brcode.transaction_amount, Some("10.00".to_string()));
assert_eq!(brcode.merchant_name, "FULANO DE TAL");
assert_eq!(brcode.merchant_city, "BRASILIA");
Diferentes Tipos de Chave PIX
use pix_brcode_parser::{parse_brcode, PixKeyType, classify_pix_key};
let uuid_key = "123e4567-e89b-12d3-a456-426614174000";
assert_eq!(classify_pix_key(uuid_key), PixKeyType::Uuid);
let email_key = "usuario@exemplo.com";
assert_eq!(classify_pix_key(email_key), PixKeyType::Email);
let phone_key = "+5511999999999";
assert_eq!(classify_pix_key(phone_key), PixKeyType::Phone);
let cpf_key = "12345678901";
assert_eq!(classify_pix_key(cpf_key), PixKeyType::Cpf);
let cnpj_key = "12345678000195";
assert_eq!(classify_pix_key(cnpj_key), PixKeyType::Cnpj);
Tratamento de Erros
use pix_brcode_parser::{parse_brcode, BRCodeError};
let invalid_qr = "codigo_invalido";
match parse_brcode(invalid_qr) {
Ok(brcode) => println!("Código válido: {:?}", brcode),
Err(e) => match e {
BRCodeError::InvalidChecksum => {
println!("Checksum inválido - código pode estar corrompido");
}
BRCodeError::InvalidGui(gui) => {
println!("GUI inválido: esperado 'br.gov.bcb.pix', encontrado: {}", gui);
}
BRCodeError::MissingField(field) => {
println!("Campo obrigatório ausente: {}", field);
}
BRCodeError::InvalidFormat(msg) => {
println!("Formato inválido: {}", msg);
}
_ => {
println!("Erro: {}", e);
}
}
}
Validação de Campos
use pix_brcode_parser::parse_brcode;
let long_name_qr = "...";
match parse_brcode(long_name_qr) {
Err(BRCodeError::FieldTooLong { tag, max_length, actual_length }) => {
println!("Campo {} muito longo: máximo {}, atual {}", tag, max_length, actual_length);
}
_ => {}
}
Serialização com Serde (Feature Opcional)
#[cfg(feature = "serde")]
{
use serde_json;
let qr_string = "00020126580014br.gov.bcb.pix0136123e4567-e12b-12d1-a456-426614174000520400005303986540510.005802BR5913FULANO DE TAL6008BRASILIA62070503***630436D9";
let brcode = parse_brcode(qr_string).unwrap();
let json = serde_json::to_string(&brcode).unwrap();
println!("JSON: {}", json);
let brcode_from_json: BRCode = serde_json::from_str(&json).unwrap();
assert_eq!(brcode, brcode_from_json);
}
Estrutura dos Dados
BRCode Principal
pub struct BRCode {
pub payload_format_indicator: String, pub point_of_initiation_method: Option<String>, pub merchant_account_info: MerchantAccountInfo,
pub merchant_category_code: String, pub transaction_currency: String, pub transaction_amount: Option<String>, pub country_code: String, pub merchant_name: String, pub merchant_city: String, pub additional_data: Option<AdditionalData>,
pub crc16: String, }
Informações da Conta PIX
pub struct MerchantAccountInfo {
pub gui: String, pub pix_key: String, pub description: Option<String>, pub url: Option<String>, }
Dados Adicionais
pub struct AdditionalData {
pub bill_number: Option<String>,
pub mobile_number: Option<String>,
pub store_label: Option<String>,
pub loyalty_number: Option<String>,
pub reference_label: Option<String>, pub customer_label: Option<String>,
pub terminal_label: Option<String>,
pub purpose_of_transaction: Option<String>,
pub additional_consumer_data_request: Option<String>,
}
Validações Implementadas
- ✅ Checksum CRC16: Validação completa usando CRC-16/CCITT-FALSE
- ✅ GUI PIX: Deve ser "br.gov.bcb.pix"
- ✅ Código da Moeda: Deve ser "986" (Real Brasileiro)
- ✅ Código do País: Deve ser "BR"
- ✅ Indicador de Formato: Deve ser "01"
- ✅ Limites de Campo:
- Nome do comerciante: máximo 25 caracteres
- Cidade: máximo 15 caracteres
- Etiqueta de referência: máximo 25 caracteres
- ✅ Formato da Chave PIX: Validação básica de caracteres
Executando os Exemplos
cargo run --example parse_pix_qr
cargo run --example generate_pix_qr
Executando os Testes
cargo test --lib
cargo test
cargo test -- --nocapture
Compatibilidade
- Rust: 1.70+
- Plataformas: Windows, Linux, macOS
- Arquiteturas: x86_64, ARM64
Licença
Dual licensed under MIT OR Apache-2.0.
Contribuindo
Contribuições são bem-vindas! Por favor:
- Fork o repositório
- Crie uma branch para sua feature
- Adicione testes para novas funcionalidades
- Execute
cargo test
para garantir que tudo funciona
- Envie um Pull Request
Recursos Úteis
Esta biblioteca foi desenvolvida para facilitar a integração com o sistema PIX brasileiro, seguindo rigorosamente os padrões EMV QRCPS e as especificações do Banco Central do Brasil.