Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

integrobr-nfse-sdk

Cliente oficial Python para a API pública do IntegroBR NFS-e Recebidas — consulte e gerencie, de forma programática, as NFS-e (notas de serviço) monitoradas pela sua conta IntegroBR.

Instalação

pip install integrobr-nfse-sdk

Uso rápido

import os
from integrobr_nfse_sdk import IntegroBRClient

client = IntegroBRClient(api_key=os.environ["INTEGROBR_API_KEY"])

conta = client.obter_conta()
print(conta["nome"], conta["ambiente"])  # "Empresa Exemplo LTDA" "PRODUCAO"

empresas = client.listar_empresas()
notas = client.listar_documentos(situacao="AUTORIZADA", limite=50)

Gere uma chave em Painel → Chaves de API (/painel/chaves-api). Ela só é exibida uma vez — se perder, revogue e crie outra. Existem dois ambientes de chave, que nunca se misturam:

Prefixo Ambiente
ibr_test_... Sandbox — dados de teste, nunca reais, nunca geram cobrança.
ibr_live_... Produção — dados fiscais reais da sua conta.

Empresas (CNPJs monitorados)

# Listar (GET /companies não é paginado)
empresas = client.listar_empresas()

# Cadastrar um CNPJ novo
empresa = client.criar_empresa(cnpj="12345678000195", nome_exibicao="Filial São Paulo")

# Enviar o certificado A1 (.pfx/.p12)
with open("certificado.pfx", "rb") as f:
    conteudo = f.read()
client.enviar_certificado(empresa["id"], conteudo, "certificado.pfx", "senha-do-certificado")

# Pausar / retomar
client.pausar_empresa(empresa["id"])
client.retomar_empresa(empresa["id"])

# Solicitar remoção (primeiro passo — a confirmação final é feita pelo painel)
client.remover_empresa(empresa["id"])

Documentos (notas fiscais)

GET /documents usa paginação por cursor — passe proximoCursor de volta em cursor na próxima chamada:

cursor = None
while True:
    pagina = client.listar_documentos(cursor=cursor, limite=100)
    for nota in pagina["itens"]:
        print(nota["numero"], nota["valorServicos"], nota["situacao"])
    cursor = pagina["proximoCursor"]
    if not cursor:
        break

Contas que monitoram mais de um tipo de documento fiscal podem filtrar com tipo_documento ("NFSE", "NFE" ou "CTE") — ausência devolve os três tipos misturados:

notas_nfe = client.listar_documentos(tipo_documento="NFE")

Ou use o gerador paginar_documentos, que faz esse loop por você:

for nota in client.paginar_documentos(situacao="AUTORIZADA"):
    print(nota["numero"])

Detalhe de uma nota (inclui XML original e linha do tempo de eventos):

detalhe = client.obter_documento(nota["id"])
print(detalhe["eventos"])

Consumo do ciclo atual

consumo = client.obter_consumo()
if consumo["temCicloAtivo"]:
    print(f"{consumo['eventosIncluidos']}/{consumo['franquiaEventos']} eventos usados neste ciclo")

Tratamento de erros

Toda chamada que falha lança IntegroBRApiError, com status_code, messages (sempre uma lista, mesmo quando a API devolve uma string única) e propriedades pros casos mais comuns:

from integrobr_nfse_sdk import IntegroBRApiError

try:
    client.obter_empresa("id-que-nao-existe")
except IntegroBRApiError as erro:
    if erro.nao_encontrado:
        pass  # 404 — não existe nesta conta, ou existe só no outro ambiente (sandbox/produção)
    if erro.rate_limited:
        pass  # 429 — 120 requisições/minuto por chave; espere e tente de novo
    print(erro.status_code, erro.messages)

Webhooks

Configure webhooks pelo painel (Painel → Webhooks) pra ser avisado em tempo real (NOTA_RECEBIDA, EVENTO_FISCAL_RECEBIDO) em vez de ficar consultando GET /documents. Cada entrega assina o corpo com HMAC-SHA256 no cabeçalho X-IntegroBR-Signaturesempre verifique antes de confiar no payload:

import json
import os
from flask import Flask, request

from integrobr_nfse_sdk import verificar_assinatura_webhook

app = Flask(__name__)


@app.post("/webhooks/integrobr")
def receber_webhook():
    assinatura = request.headers.get("X-IntegroBR-Signature", "")
    segredo = os.environ["INTEGROBR_WEBHOOK_SECRET"]

    if not verificar_assinatura_webhook(request.get_data(), assinatura, segredo):
        return "assinatura inválida", 401

    payload = json.loads(request.get_data())
    print(payload["tipo"], payload["dados"])
    return "", 200

O segredo do webhook só é exibido uma vez, na criação (ou ao rotacionar) — guarde com o mesmo cuidado de uma senha.

Limite de requisições

120 requisições por minuto, por chave de API (janela fixa de 60s). Passar do limite devolve 429, exposto como erro.rate_limited.

Licença

MIT — veja LICENSE.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages