Cliente TypeScript/Node.js para o Padrão Nacional de NFS-e (nfse.gov.br), falando direto com a API oficial da Receita Federal.
v0.1 entrega apenas leitura: consulta de NFS-e por chave de acesso, distribuição de DF-e por NSU e parsing completo do XML (RTC v1.01) para objetos tipados. Emissão (v0.2), eventos (v0.3), DANFSe (v0.4) e parâmetros municipais (v0.5) estão no roadmap — veja ROADMAP.md. A API pública pode mudar até a 1.0.
A partir de 1º de janeiro de 2026, toda NFS-e no Brasil passa a ser emitida pelo Padrão Nacional (LC 214/2025), com uma única API mantida pela Receita Federal em substituição aos ~5.570 sistemas municipais.
Este pacote é uma camada fina sobre essa API: mTLS com certificado A1, parsing/geração de XML conforme os XSDs oficiais, e DTOs tipados. Sem gateway intermediário.
npm install open-nfse
# ou
pnpm add open-nfse
# ou
yarn add open-nfse- Node.js 20+
- Certificado digital A1 (ICP-Brasil) do CNPJ emitente em formato
.pfxou.p12 - CNPJ habilitado no Emissor Nacional com Inscrição Municipal ativa
import { NfseClient, Ambiente } from 'open-nfse';
import { readFileSync } from 'node:fs';
const cliente = new NfseClient({
ambiente: Ambiente.ProducaoRestrita, // ou Ambiente.Producao
certificado: {
pfx: readFileSync('./certificado.pfx'),
password: process.env.CERT_PASSWORD!,
},
});const resultado = await cliente.fetchByChave(
'21113002200574753000100000000000146726037032711025',
);
console.log(resultado.chaveAcesso);
console.log(resultado.xmlNfse); // XML assinado pela Sefin (raw string, escape hatch)
// XML totalmente parseado em objetos tipados
const nfse = resultado.nfse;
console.log(nfse.infNFSe.emit.xNome); // "VOGA LTDA"
console.log(nfse.infNFSe.valores.vLiq); // 51.60
console.log(nfse.infNFSe.DPS.infDPS.serv.cServ.cTribNac); // "250101"
// Discriminated unions para variantes do XSD (xs:choice)
const toma = nfse.infNFSe.DPS.infDPS.toma;
if (toma && 'CPF' in toma.identificador) {
console.log('Tomador CPF:', toma.identificador.CPF);
}let ultimoNsu = 0; // na primeira vez; depois persista o último retornado
while (true) {
const r = await cliente.fetchByNsu({ ultimoNsu });
for (const doc of r.documentos) {
console.log(doc.nsu, doc.tipoDocumento, doc.chaveAcesso);
console.log(doc.xmlDocumento); // XML já descomprimido/decodificado
}
if (r.ultimoNsu === ultimoNsu) break; // sem novos documentos
ultimoNsu = r.ultimoNsu;
}
await cliente.close(); // libera o dispatcher mTLSComportamento do ADN.
/DFe/{NSU}devolve HTTP 404 com body quando não há documentos pendentes e HTTP 400 com body em caso de rejeição. Nenhum dos dois é erro HTTP — ambos carregam a mesma respostaNsuQueryResult.fetchByNsutrata isso automaticamente: não lançaNotFoundError, retorna o resultado comstatus === 'NENHUM_DOCUMENTO_LOCALIZADO'ou'REJEICAO'.Mesmo no caminho "caught up", a Receita inclui uma mensagem informativa em
erros(ex.E2220 — Nenhum documento localizado). A fonte de verdade é o campostatus;erros[]pode carregar avisos mesmo em sucesso.
Itens no roadmap que ainda não existem na v0.1:
cliente.emitir({...})— emissão síncrona de NFS-e (v0.2)cliente.cancelar({...})e demais eventos (v0.3)cliente.gerarDanfse(chave)— PDF local (v0.4)- Parâmetros municipais com cache (v0.5)
NfseClientFakeemopen-nfse/testing(v0.6)
- DTO in, DTO out. Callers não veem XML, GZip, Base64, mTLS ou XMLDSig. O
xmlNfseraw é exposto emNfseQueryResultcomo escape hatch. - Erros tipados. Hierarquia em três níveis (
Error→OpenNfseError→ grupo → concreto):ExpiredCertificateError,NotFoundError,ReceitaRejectionError, etc. - Sem estado. Nenhum banco, framework ou estado global. É biblioteca, não sistema.
- Schema-driven. Types derivam dos XSDs oficiais (RTC v1.01).
xs:choicevira discriminated union em TS. - Identificadores como
string(CNPJ, CPF, CEP, cMun, cTribNac) para preservar zeros à esquerda. Decimais comonumber— consumidores que precisam de aritmética fiscal exata devem envolver em Decimal.js. - Builder de DPS separável do transporte (v0.2). Validar e gerar XML assinado sem enviar, para preview e testes.
- Provider de certificado pluggable. Interface
CertificateProvider; implementações para arquivo, buffer e futuros KMS/Vault.
┌──────────────────────────────────────────────┐
│ API pública (NfseClient) │
├──────────────────────────────────────────────┤
│ NFS-e │ DF-e (distribuição)│
│ fetch-by-chave │ fetch-by-nsu │
│ │ │
│ parser XML → domínio tipado (RTC v1.01) │
├──────────────────────────────────────────────┤
│ HTTP client (undici + mTLS, GZip/Base64) │
├──────────────────────────────────────────────┤
│ Certificado A1 (node-forge, ICP-Brasil) │
└──────────────────────────────────────────────┘
A API oficial está dividida em hosts distintos (SEFIN Nacional e ADN Contribuintes) com contratos wire diferentes — camelCase vs PascalCase, tipoAmbiente int vs string. O NfseClient resolve o host correto por chamada e os DTOs públicos normalizam para uma única convenção.
| Ambiente | SEFIN Nacional (consulta por chave, emissão) | ADN Contribuintes (DF-e por NSU) |
|---|---|---|
| Produção Restrita (homologação) | sefin.producaorestrita.nfse.gov.br/SefinNacional |
adn.producaorestrita.nfse.gov.br/contribuintes |
| Produção (notas válidas) | sefin.nfse.gov.br/SefinNacional |
adn.nfse.gov.br/contribuintes |
Plano completo em ROADMAP.md.
- v0.1 — consulta por chave, distribuição por NSU, parser RTC v1.01 (shipped)
- v0.2 — emissão síncrona de NFS-e
- v0.3 — eventos (cancelamento, substituição)
- v0.4 — geração local de DANFSe (PDF)
- v0.5 — parâmetros municipais com cache
- v1.0 — API pública estável, cobertura do manual v1.2
Todo município é obrigado a aderir ao Padrão Nacional, mas a migração é gradual ao longo de 2026. A lib funciona com qualquer município aderente — a API é a mesma. Para municípios ainda não aderentes, é necessário usar o sistema municipal até a migração.
Bugs e sugestões: abra uma issue. PRs são bem-vindos — rode npm run lint && npm run typecheck && npm test antes de abrir.
Desenvolvido por Felipe Souza com auxílio do Claude Code (Anthropic) na escrita, revisão e parsing dos XSDs do Padrão Nacional.
MIT © Felipe Souza
- Portal oficial NFS-e Nacional
- Documentação técnica
- Manual do Contribuinte (v1.2)
- Lei Complementar 214/2025
Biblioteca não oficial, sem vínculo com a Receita Federal do Brasil. Software open source, distribuído sob licença MIT, sem garantias. Homologação e conformidade fiscal são responsabilidade de quem utiliza.