Skip to main content

Geração e envio de GNRE a partir de NF-e, com suporte a webservices e certificado PFX.

Project description

gnre-automacao

Biblioteca em Python para geração e envio de GNRE e DUA-e a partir de dados de NF-e.

  • Construção de XML do lote e montagem de envelopes SOAP
  • Comunicação com os webservices oficiais (produção e teste)
  • Parsing das respostas com extração de recibo, situação, linha digitável, valor, vencimento e PDF (base64)
  • Suporte a certificados em formato PFX
  • Suporte a DUA-e (Espírito Santo) com emissão, consulta e download de boleto

Instalação

pip install gnre-automacao

Requisitos: Python >= 3.10, cryptography >= 41.0.0


Uso rápido — roteamento automático

generate_receipts e consult_receipts encapsulam toda a lógica de roteamento: ES usa DUA-e, demais UFs usam GNRE.

generate_receipts segue a mesma assinatura de emit_gnre_receipt — recebe receita explicitamente e emite uma guia. Para emitir todas as guias necessárias, avalie com evaluate_gnre_need e itere sobre guias.

from pathlib import Path
from datetime import date
from gnre_automacao import parse_nfe_xml_bytes, evaluate_gnre_need, generate_receipts, consult_receipts

pfx_bytes = Path("certificado.pfx").read_bytes()
pfx_password = "SENHA_DO_CERTIFICADO"
nfe_bytes = Path("nfe.xml").read_bytes()
AMBIENTE = "producao"  # ou "homologacao" / "teste"

dados = parse_nfe_xml_bytes(nfe_bytes)
need = evaluate_gnre_need(dados)
venc = date.today().isoformat()

# Emite uma guia por receita (roteamento automático: ES → DUA-e, demais → GNRE)
results = []
for guia in need.get("guias") or []:
    r = generate_receipts(dados, AMBIENTE, guia["receita"], venc, venc, pfx_bytes, pfx_password)
    results.append(r)

receipt_numbers = [r["recibo"] for r in results if r.get("recibo")]

# Consulta (roteamento determinado automaticamente pela NF-e)
consultas = consult_receipts(nfe_bytes, receipt_numbers, AMBIENTE, pfx_bytes, pfx_password)
for c in consultas:
    print(c["source"], c["receipt_number"], c["status"], c["linhaDigitavel"])

Cada item retornado por consult_receipts contém:

Campo Tipo Descrição
receipt_number str Recibo consultado
source str "gnre" ou "dua_es"
status dict|None Dict com codigo e descricao
linhaDigitavel str|None Código de barras para pagamento
valor str|None Valor da guia
dataVencimento str|None Data de vencimento
pdfBase64 str|None PDF em base64 (GNRE e DUA-e)
raw dict Resposta completa do serviço
error str Presente apenas em caso de falha na consulta
pdfError str Presente apenas se o download do PDF falhar (DUA-e)

Uso direto — GNRE (todas as UFs exceto SP e ES)

evaluate_gnre_need determina se a guia é necessária. O campo necessario retorna:

  • "N" — nenhuma guia necessária
  • "S" — GNRE via webservice nacional
  • "M" — GNRE manual (SP não suporta webservice)
  • "D" — DUA-e (ES usa webservice próprio)

Para as UFs PE, RJ, RO e SC com 2+ tributos, emit_gnre_receipt envia todos em uma única guia de múltiplas receitas. Para as demais, cada tributo vai em uma guia separada.

from pathlib import Path
import base64
from datetime import date
from gnre_automacao import (
    parse_nfe_xml_bytes, evaluate_gnre_need,
    needs_multiplas_receitas, emit_gnre_receipt, consult_gnre_receipt,
    GNREError,
)

pfx_bytes = Path("certificado.pfx").read_bytes()
pfx_password = "SENHA_DO_CERTIFICADO"
nfe_bytes = Path("nfe.xml").read_bytes()
AMBIENTE = "1"  # "1" = produção, "2" = teste

dados = parse_nfe_xml_bytes(nfe_bytes)
need = evaluate_gnre_need(dados, receita=None)

if need["necessario"] == "N":
    print("GNRE não necessária")
elif need["necessario"] == "M":
    print("GNRE manual necessária (SP)")
elif need["necessario"] == "D":
    print("ES: usar DUA-e (ver seção abaixo)")
else:
    venc = date.today().isoformat()
    guias = need.get("guias") or []
    recibos = []

    if needs_multiplas_receitas(dados):
        # PE, RJ, RO, SC com 2+ tributos: um único envio com todas as receitas
        r = emit_gnre_receipt(dados, AMBIENTE, guias[0]["receita"], venc, venc, pfx_bytes, pfx_password)
        recibos.append(r)
    else:
        for guia in guias:
            r = emit_gnre_receipt(dados, AMBIENTE, guia["receita"], venc, venc, pfx_bytes, pfx_password)
            recibos.append(r)

    for r in recibos:
        if not r.get("recibo"):
            continue
        result = consult_gnre_receipt(AMBIENTE, r["recibo"], pfx_bytes, pfx_password, incluir_pdf=True)
        status = result.get("status") or {}
        print(status.get("codigo"), status.get("descricao"))
        print("Linha digitável:", result.get("linhaDigitavel"))
        print("Valor:", result.get("valor"), "| Vencimento:", result.get("dataVencimento"))
        if result.get("pdfBase64"):
            Path(f"gnre_{r['recibo']}.pdf").write_bytes(base64.b64decode(result["pdfBase64"]))

Uso direto — DUA-e (Espírito Santo)

O ES usa um webservice próprio. emit_dua_es já retorna o resultado completo (linha digitável, URL do boleto e PDF) sem consulta separada.

from pathlib import Path
import base64
from datetime import date
from gnre_automacao import parse_nfe_xml_bytes, evaluate_gnre_need, emit_dua_es, consult_dua_es

pfx_bytes = Path("certificado.pfx").read_bytes()
pfx_password = "SENHA_DO_CERTIFICADO"
AMBIENTE = "producao"  # ou "homologacao"

dados = parse_nfe_xml_bytes(Path("nfe.xml").read_bytes())
need = evaluate_gnre_need(dados)

if need["necessario"] == "D":
    venc = date.today().isoformat()
    for guia in need.get("guias") or []:
        result = emit_dua_es(dados, guia["receita"], AMBIENTE, pfx_bytes, pfx_password, data_vencimento=venc)
        print("nDua:", result["recibo"])
        print("Linha digitável:", result["linhaDigitavel"])
        print("Boleto URL:", result["boletoUrl"])
        if result.get("pdfBase64"):
            Path(f"dua_{result['recibo']}.pdf").write_bytes(base64.b64decode(result["pdfBase64"]))

Consulta de DUA-e emitida

result = consult_dua_es(n_dua, cnpj_emitente, AMBIENTE, pfx_bytes, pfx_password)
inf = result.get("dua", {}).get("infDUAe", {})
print("Situação pagamento:", inf.get("pgto", {}).get("cPgto"))  # "0" = pendente
print("Valor total:", inf.get("valor", {}).get("vTot"))

Retornos de referência

evaluate_gnre_need

{
  "necessario": "S",
  "receita": "100102",
  "valor_principal": "27.62",
  "valor_fcp": "1.92",
  "valor_total_item": "29.54",
  "guias": [
    { "receita": "100102", "valor": "27.62" },
    { "receita": "100129", "valor": "1.92" }
  ],
  "taxes": {
    "icms": "0.00", "icms_difal": "27.62", "icms_st": "0.00",
    "fcp": "1.92", "ipi": "0.00", "pis": "0.00", "cofins": "0.00",
    "ibs": "0.00", "cbs": "0.00", "total_taxes_estimation": "29.54"
  }
}

emit_gnre_receipt

{ "receita": "100102", "recibo": "26000045455789", "multiplas_receitas": false }

consult_gnre_receipt

{
  "recibo": "26000045455789",
  "status": { "numeroRecibo": "26000045455789", "codigo": "402", "descricao": "Lote Processado com sucesso" },
  "linhaDigitavel": "8587...4007",
  "valor": "1.92",
  "dataVencimento": "2026-02-02",
  "pdfBase64": "JVBERi0xLjQK..."
}

emit_dua_es

{
  "recibo": "4024341561",
  "status": { "codigo": "105", "descricao": "Dua emitido com sucesso" },
  "linhaDigitavel": "xxxxxxxxx",
  "valor": "45.00",
  "dataVencimento": "2026-03-31",
  "boletoUrl": "https://internet.sefaz.es.gov.br/agenciavirtual/area_publica/e-dua/views/imprimir-dua.php?numDua=xxxxxxx&codCpfCnpjPessoa=xxxxx",
  "pdfBase64": "JVBERi0x...",
  "receita": "100102",
  "cServ": "3867"
}

Principais funções

Roteamento automático

  • generate_receipts(dados, ambiente, receita, data_vencimento, data_pagamento, pfx_bytes, pfx_password, ...) — emite uma guia: ES → DUA-e, demais → GNRE
  • consult_receipts(nfe_bytes, receipt_numbers, ambiente, pfx_bytes, pfx_password) — consulta com roteamento automático

GNRE

  • parse_nfe_xml(path) / parse_nfe_xml_bytes(bytes) — extrai dados relevantes da NF-e
  • evaluate_gnre_need(dados, receita=None) — avalia necessidade de guia
  • needs_multiplas_receitas(dados)True se UF destino em PE/RJ/RO/SC com 2+ tributos
  • emit_gnre_receipt(dados, ambiente, receita, data_vencimento, data_pagamento, pfx_bytes, pfx_password) — emite a guia
  • consult_gnre_receipt(ambiente, recibo, pfx_bytes, pfx_password, incluir_pdf=True, ...) — consulta resultado
  • generate_gnre_receipts(dados, ambiente, data_vencimento, data_pagamento, pfx_bytes, pfx_password) — emite todas as guias GNRE

DUA-e (ES)

  • emit_dua_es(dados, receita, ambiente, pfx_bytes, pfx_password, data_vencimento, ...) — emite um DUA-e
  • consult_dua_es(n_dua, cnpj, ambiente, pfx_bytes, pfx_password) — consulta DUA emitido
  • generate_dua_es_receipts(dados, ambiente, pfx_bytes, pfx_password, data_vencimento, ...) — emite todos os DUAs necessários
  • download_boleto_html_dua_es(n_dua, cpf_cnpj_pes, timeout=15) — baixa HTML do boleto público (sem certificado)
  • get_boleto_url_dua_es(n_dua, cpf_cnpj_pes) — retorna URL pública do boleto
  • consult_area_servico_dua_es(cnpj_org, ambiente, pfx_bytes, pfx_password) — consulta áreas/serviços disponíveis
  • consult_municipio_dua_es(ambiente, pfx_bytes, pfx_password) — consulta códigos de município

Baixo nível

  • build_lote_xml_with_config(...) — XML do lote com regras da UF
  • build_lote_xml(...) — XML do lote (guia única)
  • build_lote_xml_multiplas_receitas(...) — XML com múltiplas receitas (PE/RJ/RO/SC)
  • MULTIPLAS_RECEITAS_UFSfrozenset{"PE", "RJ", "RO", "SC"}
  • build_soap_envelope_tlote(xml) — envelope SOAP para recepção de lote
  • post_soap(url, envelope_xml, ...) — requisição SOAP com certificado
  • parse_tr_ret_lote(soap_xml) — extrai número de recibo do retorno
  • build_consulta_resultado_xml(ambiente, recibo, incluir_pdf=True, ...) — XML de consulta de resultado
  • get_endpoints(ambiente) — URLs dos webservices GNRE (producao ou teste)
  • GNREError — exceção com codigo, descricao e recibo quando aplicável

Endpoints e ambientes

Serviço Parâmetro ambiente
GNRE nacional "producao" / "teste"get_endpoints(ambiente)
DUA-e ES "producao" / "homologacao"get_dua_es_endpoints(ambiente)

O roteamento automático (generate_receipts / consult_receipts) aceita qualquer um dos valores acima e repassa ao serviço correto.

Certificados PFX

Informe pfx_bytes e pfx_password diretamente. O certificado é temporariamente materializado em PEM durante a requisição e removido em seguida. Nunca persista ou logue os bytes do certificado.

Avisos

  • SP não suporta webservice nacional — requer GNRE manual (necessario="M").
  • ES usa o webservice DUA-e próprio — não usa o webservice GNRE nacional (necessario="D").
  • Para RJ e RO com múltiplos tributos, chame emit_gnre_receipt uma única vez — ela já inclui todos os tributos detectados internamente.
  • O CNPJ deve estar cadastrado no portal GNRE antes de usar os serviços GNRE.
  • Para DUA-e ES, não é necessário cadastro prévio.
  • Não comite senhas ou certificados no repositório.
  • Sempre valide no ambiente de teste antes de ir para produção.

Dicas de depuração

Para inspecionar a estrutura de XML esperada por uma UF/receita específica, use o gerador oficial do portal GNRE, gere a guia manualmente e compare o XML resultante com o produzido pela biblioteca:

https://www.gnre.pe.gov.br:444/gnre/v/lote/gerar#

Licença

MIT. Veja o arquivo LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gnre_automacao-3.0.0.tar.gz (29.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gnre_automacao-3.0.0-py3-none-any.whl (28.6 kB view details)

Uploaded Python 3

File details

Details for the file gnre_automacao-3.0.0.tar.gz.

File metadata

  • Download URL: gnre_automacao-3.0.0.tar.gz
  • Upload date:
  • Size: 29.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for gnre_automacao-3.0.0.tar.gz
Algorithm Hash digest
SHA256 ff6d3f9a3c6822e1ee6b0aba6930b16978c85e33f29709b08469646583cac39a
MD5 d1d0842b94e18f5d5dccb255d7fac090
BLAKE2b-256 27ddbe892d7c902c9d75dce0ce2dba5092200b2fd3129604e22fb3e1684bbc5d

See more details on using hashes here.

Provenance

The following attestation bundles were made for gnre_automacao-3.0.0.tar.gz:

Publisher: python-publish.yml on heitorforner/gnre-automacao

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gnre_automacao-3.0.0-py3-none-any.whl.

File metadata

  • Download URL: gnre_automacao-3.0.0-py3-none-any.whl
  • Upload date:
  • Size: 28.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for gnre_automacao-3.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ee15ea9a41081604f13b80b787831529c8a233039ac9e61b096767cda60f56c5
MD5 2a39a894bdda34708ee1b594cea903ea
BLAKE2b-256 2b50955c5bfe56f7987aa5e85a865050260b4252a4d443c76468f2ac417342b1

See more details on using hashes here.

Provenance

The following attestation bundles were made for gnre_automacao-3.0.0-py3-none-any.whl:

Publisher: python-publish.yml on heitorforner/gnre-automacao

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page