nfe-lib-node 1.6.0 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -144
- package/dist/Danfe.d.ts +24 -5
- package/dist/Danfe.d.ts.map +1 -1
- package/dist/Danfe.js +660 -183
- package/dist/Danfe.js.map +1 -1
- package/dist/NFe.d.ts +26 -3
- package/dist/NFe.d.ts.map +1 -1
- package/dist/NFe.js +196 -6
- package/dist/NFe.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +38 -16
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,168 +1,70 @@
|
|
|
1
1
|
# nfe-lib-node 🚀
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Biblioteca Node.js em TypeScript para emissão e gestão de **Nota Fiscal Eletrônica (NF-e Modelo 55 — Layout 4.00)** com comunicação direta com a SEFAZ (mTLS/SOAP 1.2), assinatura XMLDSig e geração nativa de DANFE em PDF.
|
|
4
4
|
|
|
5
5
|
Pague apenas os seus impostos, não pela emissão! 😉
|
|
6
6
|
|
|
7
7
|
## 📦 Instalação
|
|
8
8
|
|
|
9
|
-
Instale diretamente via NPM:
|
|
10
|
-
|
|
11
9
|
```bash
|
|
12
10
|
npm install nfe-lib-node
|
|
13
11
|
```
|
|
14
12
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
git clone https://github.com/rafconrado/nfe-lib-node.git
|
|
19
|
-
cd nfe-lib-node
|
|
20
|
-
npm install
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
## 🚀 Como usar
|
|
24
|
-
|
|
25
|
-
A arquitetura foi pensada para ser o mais simples possível. Você só precisa do seu Certificado Digital A1 (`.pfx`).
|
|
26
|
-
|
|
27
|
-
### 1. Validar Certificado e Consultar Status do Serviço (SEFAZ)
|
|
28
|
-
|
|
29
|
-
```typescript
|
|
30
|
-
import { NFe, Certificado } from 'nfe-lib-node';
|
|
31
|
-
import fs from 'fs';
|
|
32
|
-
|
|
33
|
-
async function testarSefaz() {
|
|
34
|
-
const certificado = new Certificado(fs.readFileSync('./certificado.pfx'), 'SENHA_DO_CERTIFICADO');
|
|
35
|
-
|
|
36
|
-
// Opcional: Inspecionar dados e validade do Certificado A1 (ICP-Brasil)
|
|
37
|
-
const dadosCert = certificado.getDados();
|
|
38
|
-
console.log(`Titular: ${dadosCert.nomeComum} (${dadosCert.cnpjOuCpf})`);
|
|
39
|
-
console.log(`Válido: ${dadosCert.estaValido} (${dadosCert.diasParaVencer} dias restantes)`);
|
|
40
|
-
|
|
41
|
-
const nfe = new NFe({ uf: 'DF', ambiente: 'homologacao', certificado });
|
|
42
|
-
|
|
43
|
-
const status = await nfe.consultarStatus();
|
|
44
|
-
console.log(status.xml);
|
|
45
|
-
}
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
### 2. Emitir uma NF-e (Autorização) e Gerar DANFE em PDF
|
|
49
|
-
|
|
50
|
-
A biblioteca cuida da infraestrutura completa (Tipagem do Layout 4.00, Assinatura XMLDSig, comunicação SOAP e geração de DANFE em PDF sem dependências pesadas):
|
|
13
|
+
## ⚡ Uso Rápido
|
|
51
14
|
|
|
52
15
|
```typescript
|
|
16
|
+
import fs from 'node:fs';
|
|
53
17
|
import { NFe, Certificado, Danfe, type DadosNFe } from 'nfe-lib-node';
|
|
54
|
-
import fs from 'fs';
|
|
55
|
-
|
|
56
|
-
async function emitirNota() {
|
|
57
|
-
const certificado = new Certificado(fs.readFileSync('./certificado.pfx'), 'SENHA_DO_CERTIFICADO');
|
|
58
|
-
const nfe = new NFe({ uf: 'DF', ambiente: 'homologacao', certificado });
|
|
59
|
-
|
|
60
|
-
const nota: DadosNFe = {
|
|
61
|
-
infNFe: {
|
|
62
|
-
'@Id': 'NFe5326...',
|
|
63
|
-
'@versao': '4.00',
|
|
64
|
-
ide: { /* ... */ },
|
|
65
|
-
emit: { /* ... */ },
|
|
66
|
-
dest: { /* ... */ },
|
|
67
|
-
det: [ /* ... */ ],
|
|
68
|
-
total: { /* ... */ },
|
|
69
|
-
transp: { /* ... */ },
|
|
70
|
-
pag: { /* ... */ }
|
|
71
|
-
}
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
const resposta = await nfe.emitir(nota);
|
|
75
|
-
console.log(`Status: ${resposta.status} - ${resposta.motivo}`);
|
|
76
|
-
|
|
77
|
-
// Gera o PDF do DANFE diretamente a partir do XML assinado + retorno da SEFAZ
|
|
78
|
-
if (resposta.xmlAssinado) {
|
|
79
|
-
const pdfBuffer = Danfe.fromXml(resposta.xmlAssinado, resposta.xml);
|
|
80
|
-
fs.writeFileSync('./danfe.pdf', pdfBuffer);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
### 3. Consultar Protocolo, Recibo, Cancelar, Carta de Correção, Inutilizar e Manifestar
|
|
86
|
-
|
|
87
|
-
```typescript
|
|
88
|
-
import { NFe, Certificado } from 'nfe-lib-node';
|
|
89
|
-
import fs from 'fs';
|
|
90
|
-
|
|
91
|
-
async function gerenciarNotas() {
|
|
92
|
-
const certificado = new Certificado(fs.readFileSync('./certificado.pfx'), 'SENHA_DO_CERTIFICADO');
|
|
93
|
-
const nfe = new NFe({ uf: 'DF', ambiente: 'homologacao', certificado });
|
|
94
|
-
|
|
95
|
-
const chave = '53260999999999999999550010000000011847291634';
|
|
96
|
-
|
|
97
|
-
// 1. Consulta de Protocolo por Chave de Acesso (NFeConsultaProtocolo4)
|
|
98
|
-
const consulta = await nfe.consultarProtocolo(chave);
|
|
99
|
-
console.log(`Situação: ${consulta.status} - ${consulta.motivo}`);
|
|
100
|
-
|
|
101
|
-
// 2. Consulta de Recibo de Lote de 15 dígitos (NFeRetAutorizacao4)
|
|
102
|
-
const recibo = await nfe.consultarRecibo('531000000000001');
|
|
103
|
-
console.log(`Recibo: ${recibo.status} - ${recibo.motivo}`);
|
|
104
|
-
|
|
105
|
-
// 3. Carta de Correção Eletrônica - CC-e (tpEvento 110110)
|
|
106
|
-
const cce = await nfe.cartaCorrecao({
|
|
107
|
-
chave,
|
|
108
|
-
correcao: 'Correcao na descricao complementar da mercadoria transportada.',
|
|
109
|
-
nSeqEvento: 1,
|
|
110
|
-
});
|
|
111
|
-
console.log(`CC-e: ${cce.status} - ${cce.motivo}`);
|
|
112
18
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
19
|
+
const certificado = new Certificado(fs.readFileSync('./certificado.pfx'), 'SENHA_DO_PFX');
|
|
20
|
+
const nfe = new NFe({ uf: 'DF', ambiente: 'homologacao', certificado });
|
|
21
|
+
|
|
22
|
+
// 1. Emitir NF-e (@Id, cUF, cNF, cDV, dhEmi e tpAmb são calculados automaticamente se omitidos)
|
|
23
|
+
const nota: DadosNFe = {
|
|
24
|
+
infNFe: {
|
|
25
|
+
ide: { natOp: 'VENDA', serie: '1', nNF: '100', tpNF: '1', idDest: '1', cMunFG: '5300108', tpImp: '1', tpEmis: '1', finNFe: '1', indFinal: '1', indPres: '1', procEmi: '0', verProc: '1.0.0' },
|
|
26
|
+
emit: { /* dados do emitente */ } as any,
|
|
27
|
+
dest: { /* dados do destinatário */ } as any,
|
|
28
|
+
det: [ /* itens da nota */ ],
|
|
29
|
+
total: { /* totais ICMSTot */ } as any,
|
|
30
|
+
transp: { modFrete: '9' },
|
|
31
|
+
pag: { detPag: [{ tPag: '01', vPag: '100.00' }] },
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const emissao = await nfe.emitir(nota);
|
|
36
|
+
console.log(emissao.chave, emissao.status, emissao.motivo);
|
|
37
|
+
|
|
38
|
+
// 2. Gerar DANFE A4 em PDF (com suporte opcional a logo PNG/JPEG)
|
|
39
|
+
if (emissao.xmlAssinado) {
|
|
40
|
+
const pdf = Danfe.fromXml(emissao.xmlAssinado, emissao.xml, {
|
|
41
|
+
logo: fs.readFileSync('./logo.png'), // opcional
|
|
128
42
|
});
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
// 6. Manifestação do Destinatário no Ambiente Nacional (210210, 210200, 210220, 210240)
|
|
132
|
-
const ciencia = await nfe.manifestar({
|
|
133
|
-
chave,
|
|
134
|
-
tipo: 'ciencia', // 'ciencia' | 'confirmacao' | 'desconhecimento' | 'nao_realizada'
|
|
135
|
-
});
|
|
136
|
-
console.log(`Manifestação: ${ciencia.status} - ${ciencia.motivo}`);
|
|
43
|
+
fs.writeFileSync('./danfe.pdf', pdf);
|
|
137
44
|
}
|
|
138
45
|
```
|
|
139
46
|
|
|
140
|
-
##
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
47
|
+
## 🛠️ Operações Disponíveis
|
|
48
|
+
|
|
49
|
+
| Método / Utilitário | Descrição |
|
|
50
|
+
| :--- | :--- |
|
|
51
|
+
| `nfe.consultarStatus()` | Consulta disponibilidade do webservice da UF (`NFeStatusServico4`) |
|
|
52
|
+
| `nfe.emitir(dados)` | Assina, calcula chave/`cDV` automaticamente, envia lote síncrono e monta `<nfeProc>` |
|
|
53
|
+
| `nfe.consultarProtocolo(chave)` | Consulta situação atual e protocolo da NF-e (`NFeConsultaProtocolo4`) |
|
|
54
|
+
| `nfe.consultarRecibo(recibo)` | Consulta resultado de processamento de lote (`NFeRetAutorizacao4`) |
|
|
55
|
+
| `nfe.cancelar({ chave, protocolo, justificativa })` | Envia evento de Cancelamento (`110111`) e retorna `<procEventoNFe>` |
|
|
56
|
+
| `nfe.cartaCorrecao({ chave, correcao, nSeqEvento })` | Envia Carta de Correção Eletrônica — CC-e (`110110`) |
|
|
57
|
+
| `nfe.inutilizar({ cnpj, serie, numeroInicial, numeroFinal, justificativa })` | Inutiliza faixa de numeração (`NFeInutilizacao4`) e retorna `<ProcInutNFe>` |
|
|
58
|
+
| `nfe.manifestar({ chave, tipo, justificativa? })` | Manifestação do Destinatário no Ambiente Nacional (`ciencia`, `confirmacao`, `desconhecimento`, `nao_realizada`) |
|
|
59
|
+
| `nfe.distribuicaoDFe({ ultimoNSU \| nsu \| chave })` | Consulta `NFeDistribuicaoDFe` e descompacta `<docZip>` automaticamente |
|
|
60
|
+
| `Danfe.fromXml(xml, xmlRetorno?, { logo? })` | Gera PDF A4 do DANFE (monocromático padrão NFePHP, paginação automática e logo opcional) |
|
|
61
|
+
| `certificado.getDados()` | Extrai titular, CNPJ/CPF, validade e dias restantes do Certificado A1 (`.pfx`) |
|
|
62
|
+
| `gerarChaveAcesso` / `validarChaveAcesso` | Gera, valida e extrai campos da chave de 44 dígitos (Módulo 11) |
|
|
149
63
|
|
|
150
64
|
## 🛡️ Segurança
|
|
151
65
|
|
|
152
|
-
|
|
153
|
-
* O arquivo `.gitignore` já vem configurado para ignorar extensões de certificados por padrão.
|
|
154
|
-
|
|
155
|
-
## 🤝 Contribuições
|
|
156
|
-
|
|
157
|
-
As próximas etapas envolvem suporte a Distribuição de DF-e (`NFeDistribuicaoDFe`) e geração de QR-Code para NFC-e (Modelo 65). Toda contribuição da comunidade Node.js brasileira é bem-vinda!
|
|
158
|
-
|
|
159
|
-
## 👨💻 Autor
|
|
160
|
-
|
|
161
|
-
Criado e idealizado por **Rafael Conrado**.
|
|
162
|
-
Se você curtiu o projeto, me dê um "Alô" nas redes:
|
|
163
|
-
* [GitHub - @rafconrado](https://github.com/rafconrado)
|
|
164
|
-
* [LinkedIn](https://www.linkedin.com/in/rafconradoo/)
|
|
66
|
+
Nunca faça commit do seu arquivo `.pfx` ou da sua senha. O `.gitignore` do projeto já bloqueia extensões de certificados (`.pfx`, `.p12`, `.cer`, `.key`, `.pem`) e variáveis `.env`.
|
|
165
67
|
|
|
166
|
-
##
|
|
68
|
+
## 👨💻 Autor & Licença
|
|
167
69
|
|
|
168
|
-
MIT
|
|
70
|
+
Criado por **Rafael Conrado** ([GitHub](https://github.com/rafconrado) • [LinkedIn](https://www.linkedin.com/in/rafconradoo/)). Distribuído sob a licença **MIT**.
|
package/dist/Danfe.d.ts
CHANGED
|
@@ -1,16 +1,35 @@
|
|
|
1
|
+
export interface OpcoesDanfe {
|
|
2
|
+
/**
|
|
3
|
+
* Logomarca da empresa emitente em formato PNG ou JPEG (`Buffer`, base64 ou Data URI `data:image/...;base64,...`).
|
|
4
|
+
* Quando informada, é renderizada no quadro "IDENTIFICAÇÃO DO EMITENTE" seguindo o padrão NFePHP (`sped-da`).
|
|
5
|
+
*/
|
|
6
|
+
logo?: Buffer | string | undefined;
|
|
7
|
+
}
|
|
1
8
|
export declare class Danfe {
|
|
2
|
-
static fromXml(xmlNFe: string,
|
|
9
|
+
static fromXml(xmlNFe: string, xmlRetornoSefazOuOpcoes?: string | OpcoesDanfe, opcoes?: OpcoesDanfe): Buffer;
|
|
10
|
+
private static drawSectionTitle;
|
|
11
|
+
private static drawFieldBox;
|
|
12
|
+
private static drawRoundedRect;
|
|
13
|
+
private static drawHLine;
|
|
14
|
+
private static drawVLine;
|
|
15
|
+
private static drawLabel;
|
|
16
|
+
private static drawAlignedItemCell;
|
|
17
|
+
private static estimateTextWidth;
|
|
18
|
+
private static drawText;
|
|
19
|
+
private static drawTextRight;
|
|
20
|
+
private static drawTextCentered;
|
|
21
|
+
private static wrapText;
|
|
22
|
+
private static escapePdfText;
|
|
3
23
|
private static getDescricaoFrete;
|
|
4
24
|
private static getDescricaoPagamento;
|
|
5
25
|
private static formatDecimal;
|
|
26
|
+
private static formatNumeroNF;
|
|
27
|
+
private static formatCep;
|
|
6
28
|
private static getTag;
|
|
7
29
|
private static formatDoc;
|
|
8
30
|
private static formatDateTime;
|
|
9
|
-
private static drawSectionHeader;
|
|
10
|
-
private static drawBox;
|
|
11
|
-
private static drawText;
|
|
12
|
-
private static escapePdfText;
|
|
13
31
|
private static drawCode128C;
|
|
32
|
+
private static parseLogoImage;
|
|
14
33
|
private static buildPdfBuffer;
|
|
15
34
|
}
|
|
16
35
|
//# sourceMappingURL=Danfe.d.ts.map
|
package/dist/Danfe.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Danfe.d.ts","sourceRoot":"","sources":["../src/Danfe.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Danfe.d.ts","sourceRoot":"","sources":["../src/Danfe.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACpC;AAkED,qBAAa,KAAK;IAChB,OAAc,OAAO,CACnB,MAAM,EAAE,MAAM,EACd,uBAAuB,CAAC,EAAE,MAAM,GAAG,WAAW,EAC9C,MAAM,CAAC,EAAE,WAAW,GACnB,MAAM,CAgbR;IAED,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAI/B,OAAO,CAAC,MAAM,CAAC,YAAY;IA2B3B,OAAO,CAAC,MAAM,CAAC,eAAe;IAyB9B,OAAO,CAAC,MAAM,CAAC,SAAS;IAIxB,OAAO,CAAC,MAAM,CAAC,SAAS;IAIxB,OAAO,CAAC,MAAM,CAAC,SAAS;IAIxB,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAWlC,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAKhC,OAAO,CAAC,MAAM,CAAC,QAAQ;IAMvB,OAAO,CAAC,MAAM,CAAC,aAAa;IAK5B,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAM/B,OAAO,CAAC,MAAM,CAAC,QAAQ;IAkBvB,OAAO,CAAC,MAAM,CAAC,aAAa;IAU5B,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAYhC,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAcpC,OAAO,CAAC,MAAM,CAAC,aAAa;IAM5B,OAAO,CAAC,MAAM,CAAC,cAAc;IAK7B,OAAO,CAAC,MAAM,CAAC,SAAS;IAQxB,OAAO,CAAC,MAAM,CAAC,MAAM;IAYrB,OAAO,CAAC,MAAM,CAAC,SAAS;IAWxB,OAAO,CAAC,MAAM,CAAC,cAAc;IAO7B,OAAO,CAAC,MAAM,CAAC,YAAY;IAgC3B,OAAO,CAAC,MAAM,CAAC,cAAc;IAqM7B,OAAO,CAAC,MAAM,CAAC,cAAc;CA2D9B"}
|