Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@integrobr/nfse-sdk

Cliente oficial Node.js/TypeScript 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

npm install @integrobr/nfse-sdk

Uso rápido

import { IntegroBRClient } from "@integrobr/nfse-sdk";

const client = new IntegroBRClient({ apiKey: process.env.INTEGROBR_API_KEY! });

const conta = await client.obterConta();
console.log(conta.nome, conta.ambiente); // "Empresa Exemplo LTDA" "PRODUCAO"

const empresas = await client.empresas.listar();
const notas = await client.documentos.listar({ 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)
const empresas = await client.empresas.listar();

// Cadastrar um CNPJ novo
const empresa = await client.empresas.criar({ cnpj: "12345678000195", nomeExibicao: "Filial São Paulo" });

// Enviar o certificado A1 (.pfx/.p12)
import { readFileSync } from "node:fs";
const arquivo = readFileSync("./certificado.pfx");
await client.empresas.enviarCertificado(empresa.id, arquivo, "certificado.pfx", "senha-do-certificado");

// Pausar / retomar
await client.empresas.pausar(empresa.id);
await client.empresas.retomar(empresa.id);

// Solicitar remoção (primeiro passo — a confirmação final é feita pelo painel)
await client.empresas.remover(empresa.id);

Documentos (notas fiscais)

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

let cursor: string | undefined;
do {
  const pagina = await client.documentos.listar({ cursor, limite: 100 });
  for (const nota of pagina.itens) {
    console.log(nota.numero, nota.valorServicos, nota.situacao);
  }
  cursor = pagina.proximoCursor ?? undefined;
} while (cursor);

Ou use o helper paginarTodos, que faz esse loop por você:

for await (const nota of client.documentos.paginarTodos({ situacao: "AUTORIZADA" })) {
  console.log(nota.numero);
}

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

const detalhe = await client.documentos.obter(nota.id);
console.log(detalhe.eventos);

Consumo do ciclo atual

const consumo = await client.obterConsumo();
if (consumo.temCicloAtivo) {
  console.log(`${consumo.eventosIncluidos}/${consumo.franquiaEventos} eventos usados neste ciclo`);
}

Tratamento de erros

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

import { IntegroBRApiError } from "@integrobr/nfse-sdk";

try {
  await client.empresas.obter("id-que-nao-existe");
} catch (erro) {
  if (erro instanceof IntegroBRApiError) {
    if (erro.naoEncontrado) {
      // 404 — não existe nesta conta, ou existe só no outro ambiente (sandbox/produção)
    }
    if (erro.rateLimited) {
      // 429 — 120 requisições/minuto por chave; espere e tente de novo
    }
    console.error(erro.statusCode, 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 { verificarAssinaturaWebhook } from "@integrobr/nfse-sdk";
import express from "express";

const app = express();
app.use(express.raw({ type: "application/json" })); // precisa do corpo BRUTO, não parseado

app.post("/webhooks/integrobr", (req, res) => {
  const assinatura = req.header("X-IntegroBR-Signature") ?? "";
  const valido = verificarAssinaturaWebhook(req.body, assinatura, process.env.INTEGROBR_WEBHOOK_SECRET!);

  if (!valido) return res.status(401).send("assinatura inválida");

  const payload = JSON.parse(req.body.toString("utf8"));
  console.log(payload.tipo, payload.dados);
  res.sendStatus(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.rateLimited.

Licença

MIT — veja LICENSE.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages