ghinfe 0.6.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.
Files changed (80) hide show
  1. package/.env.example +15 -0
  2. package/LICENSE +21 -0
  3. package/README.md +413 -0
  4. package/docs/developer-guide.html +421 -0
  5. package/docs/openapi.yaml +428 -0
  6. package/examples/emitir-nfce.js +51 -0
  7. package/examples/emitir-nfe.js +83 -0
  8. package/examples/emitir-nfse.js +46 -0
  9. package/examples/endpoints-sefaz.js +14 -0
  10. package/examples/eventos-nfe.js +49 -0
  11. package/examples/gerar-chave.js +25 -0
  12. package/examples/gerar-danfe.js +75 -0
  13. package/examples/layouts-nfse.js +51 -0
  14. package/examples/mock-sefaz.js +52 -0
  15. package/examples/nfse-eventos.js +57 -0
  16. package/examples/reforma-ibscbs.js +27 -0
  17. package/examples/reforma-nfe-xml.js +52 -0
  18. package/examples/status-sefaz.js +12 -0
  19. package/examples/validar-xsd.js +48 -0
  20. package/package.json +68 -0
  21. package/schemas/nfe/PL_009_V4/consReciNFe_v4.00.xsd +9 -0
  22. package/schemas/nfe/PL_009_V4/consSitNFe_v4.00.xsd +9 -0
  23. package/schemas/nfe/PL_009_V4/consStatServ_v4.00.xsd +9 -0
  24. package/schemas/nfe/PL_009_V4/enviNFe_v3.10.xsd +9 -0
  25. package/schemas/nfe/PL_009_V4/enviNFe_v4.00.xsd +9 -0
  26. package/schemas/nfe/PL_009_V4/inutNFe_v4.00.xsd +9 -0
  27. package/schemas/nfe/PL_009_V4/leiauteNFe_v4.00.xsd +7339 -0
  28. package/schemas/nfe/PL_009_V4/nfe_v4.00.xsd +9 -0
  29. package/schemas/nfe/PL_009_V4/tiposBasico_v4.00.xsd +598 -0
  30. package/schemas/nfe/PL_009_V4/xmldsig-core-schema_v1.01.xsd +98 -0
  31. package/scripts/download-schemas.js +39 -0
  32. package/scripts/test-xsd.js +34 -0
  33. package/src/api/server.js +316 -0
  34. package/src/constants/sefaz.js +69 -0
  35. package/src/danfe/DanfeService.js +205 -0
  36. package/src/danfe/xml-extract.js +69 -0
  37. package/src/errors/GhinfeError.js +13 -0
  38. package/src/errors/SefazError.js +25 -0
  39. package/src/errors/XsdValidationError.js +15 -0
  40. package/src/index.js +60 -0
  41. package/src/nfce/builders/NFCeXmlBuilder.js +178 -0
  42. package/src/nfce/constants/qrcode.js +26 -0
  43. package/src/nfce/services/NFCeService.js +188 -0
  44. package/src/nfce/services/NFCeXmlService.js +38 -0
  45. package/src/nfce/types/NFCeDocument.js +42 -0
  46. package/src/nfce/utils/qrcode.utils.js +92 -0
  47. package/src/nfe/builders/NFeEventoXmlBuilder.js +110 -0
  48. package/src/nfe/builders/NFeXmlBuilder.js +215 -0
  49. package/src/nfe/mocks/sefaz-responses.js +195 -0
  50. package/src/nfe/services/NFeEventoService.js +95 -0
  51. package/src/nfe/services/NFeService.js +196 -0
  52. package/src/nfe/services/NFeSignService.js +111 -0
  53. package/src/nfe/services/NFeSoapService.js +437 -0
  54. package/src/nfe/services/NFeXmlService.js +41 -0
  55. package/src/nfe/services/NFeXsdService.js +56 -0
  56. package/src/nfe/types/NFeDocument.js +92 -0
  57. package/src/nfe/types/NFeEvento.js +44 -0
  58. package/src/nfse/NFSeMunicipioResolver.js +42 -0
  59. package/src/nfse/builders/NFSeEventoXmlBuilder.js +92 -0
  60. package/src/nfse/builders/NFSeXmlBuilder.js +16 -0
  61. package/src/nfse/constants/municipios.js +82 -0
  62. package/src/nfse/layouts/adapters.js +202 -0
  63. package/src/nfse/mocks/nfse-responses.js +142 -0
  64. package/src/nfse/services/NFSeService.js +191 -0
  65. package/src/nfse/services/NFSeSoapService.js +232 -0
  66. package/src/nfse/services/NFSeXmlService.js +12 -0
  67. package/src/nfse/types/NFSeDocument.js +54 -0
  68. package/src/queue/NFCeQueue.js +63 -0
  69. package/src/queue/NFSeQueue.js +59 -0
  70. package/src/queue/NFeQueue.js +76 -0
  71. package/src/reforma/ibscbs.js +175 -0
  72. package/src/sefaz/SefazEndpointResolver.js +95 -0
  73. package/src/sefaz/endpoints.registry.js +205 -0
  74. package/src/shared/fiscal.helpers.js +53 -0
  75. package/src/utils/certificate.utils.js +47 -0
  76. package/src/utils/chave.utils.js +117 -0
  77. package/src/utils/date.utils.js +26 -0
  78. package/src/utils/xml.utils.js +44 -0
  79. package/src/validation/XsdValidator.js +114 -0
  80. package/src/validation/schemas.js +14 -0
@@ -0,0 +1,428 @@
1
+ openapi: 3.0.3
2
+ info:
3
+ title: GHINFE API
4
+ description: |
5
+ API de testes da biblioteca GHINFE para emissão de NF-e.
6
+ Use os endpoints em modo mock para validar integração sem certificado real.
7
+ version: 0.6.0
8
+ contact:
9
+ name: GHINFE
10
+ servers:
11
+ - url: http://localhost:3333
12
+ description: Servidor local de desenvolvimento
13
+
14
+ tags:
15
+ - name: NF-e
16
+ description: Operações de Nota Fiscal Eletrônica
17
+ - name: NFC-e
18
+ description: Cupom Fiscal Eletrônico (modelo 65)
19
+ - name: NFS-e
20
+ description: Nota Fiscal de Serviço Eletrônica
21
+ - name: SEFAZ
22
+ description: Endpoints e status SEFAZ
23
+ - name: Reforma
24
+ description: IBS/CBS (base PL_010)
25
+ - name: Sistema
26
+ description: Health check e informações
27
+
28
+ paths:
29
+ /health:
30
+ get:
31
+ tags: [Sistema]
32
+ summary: Health check
33
+ responses:
34
+ '200':
35
+ description: API operacional
36
+ content:
37
+ application/json:
38
+ schema:
39
+ type: object
40
+ properties:
41
+ status:
42
+ type: string
43
+ example: ok
44
+ library:
45
+ type: string
46
+ example: ghinfe
47
+
48
+ /nfe/xml:
49
+ post:
50
+ tags: [NF-e]
51
+ summary: Gerar XML da NF-e
52
+ description: Monta o XML conforme layout SEFAZ 4.00 a partir do objeto de domínio.
53
+ requestBody:
54
+ required: true
55
+ content:
56
+ application/json:
57
+ schema:
58
+ $ref: '#/components/schemas/NFeDocumento'
59
+ responses:
60
+ '200':
61
+ description: XML gerado com sucesso
62
+ content:
63
+ application/json:
64
+ schema:
65
+ type: object
66
+ properties:
67
+ chaveAcesso:
68
+ type: string
69
+ xml:
70
+ type: string
71
+ '400':
72
+ $ref: '#/components/responses/ErroValidacao'
73
+
74
+ /nfe/validar-xsd:
75
+ post:
76
+ tags: [NF-e]
77
+ summary: Validar XML contra XSD
78
+ requestBody:
79
+ required: true
80
+ content:
81
+ application/json:
82
+ schema:
83
+ type: object
84
+ required: [xml]
85
+ properties:
86
+ xml: { type: string }
87
+ responses:
88
+ '200':
89
+ description: XML válido
90
+ '422':
91
+ description: Erro de validação XSD
92
+
93
+ /nfce/xml:
94
+ post:
95
+ tags: [NFC-e]
96
+ summary: Gerar XML NFC-e (modelo 65)
97
+ requestBody:
98
+ required: true
99
+ content:
100
+ application/json:
101
+ schema:
102
+ $ref: '#/components/schemas/NFCeDocumento'
103
+ responses:
104
+ '200':
105
+ description: XML gerado
106
+
107
+ /nfce/enviar-mock:
108
+ post:
109
+ tags: [NFC-e]
110
+ summary: Enviar NFC-e (mock SEFAZ)
111
+ requestBody:
112
+ required: true
113
+ content:
114
+ application/json:
115
+ schema:
116
+ $ref: '#/components/schemas/NFCeDocumento'
117
+ responses:
118
+ '200':
119
+ description: Retorno mock
120
+
121
+ /nfe/chave:
122
+ post:
123
+ tags: [NF-e]
124
+ summary: Gerar chave de acesso
125
+ description: Gera chave NF-e de 44 dígitos com DV módulo 11.
126
+ requestBody:
127
+ required: true
128
+ content:
129
+ application/json:
130
+ schema:
131
+ type: object
132
+ required: [uf, cnpj, serie, numero]
133
+ properties:
134
+ uf: { type: string, example: 'SP' }
135
+ cnpj: { type: string, example: '12345678000199' }
136
+ modelo: { type: string, example: '55' }
137
+ serie: { type: integer, example: 1 }
138
+ numero: { type: integer, example: 42 }
139
+ tipoEmissao: { type: integer, example: 1 }
140
+ codigoNumerico: { type: string, example: '12345678' }
141
+ responses:
142
+ '200':
143
+ description: Chave gerada
144
+ content:
145
+ application/json:
146
+ schema:
147
+ type: object
148
+ properties:
149
+ chaveAcesso: { type: string }
150
+ valida: { type: boolean, example: true }
151
+
152
+ /nfe/cancelar-mock:
153
+ post:
154
+ tags: [NF-e]
155
+ summary: Cancelar NF-e (mock)
156
+ description: Gera XML do evento 110111 e simula retorno SEFAZ.
157
+ requestBody:
158
+ required: true
159
+ content:
160
+ application/json:
161
+ schema:
162
+ $ref: '#/components/schemas/NFeCancelamento'
163
+ responses:
164
+ '200':
165
+ description: Evento registrado (mock)
166
+ '422':
167
+ $ref: '#/components/responses/ErroSefaz'
168
+
169
+ /nfe/cce-mock:
170
+ post:
171
+ tags: [NF-e]
172
+ summary: Carta de Correção (mock)
173
+ description: Gera XML do evento 110110 e simula retorno SEFAZ.
174
+ requestBody:
175
+ required: true
176
+ content:
177
+ application/json:
178
+ schema:
179
+ $ref: '#/components/schemas/NFeCartaCorrecao'
180
+ responses:
181
+ '200':
182
+ description: Evento registrado (mock)
183
+ '422':
184
+ $ref: '#/components/responses/ErroSefaz'
185
+
186
+ /nfe/enviar-mock:
187
+ post:
188
+ tags: [NF-e]
189
+ summary: Enviar NF-e (mock SEFAZ)
190
+ description: |
191
+ Gera XML, simula assinatura e envia para mock da SEFAZ.
192
+ Útil para testar fluxo completo sem certificado A1.
193
+ parameters:
194
+ - in: query
195
+ name: cenario
196
+ schema:
197
+ type: string
198
+ enum: [autorizado, duplicidade, schema, certificado, paralisado]
199
+ default: autorizado
200
+ description: Cenário de retorno simulado da SEFAZ
201
+ requestBody:
202
+ required: true
203
+ content:
204
+ application/json:
205
+ schema:
206
+ $ref: '#/components/schemas/NFeDocumento'
207
+ responses:
208
+ '200':
209
+ description: Retorno da SEFAZ (mock)
210
+ content:
211
+ application/json:
212
+ schema:
213
+ $ref: '#/components/schemas/ResultadoEmissao'
214
+ '422':
215
+ description: Rejeição SEFAZ
216
+ content:
217
+ application/json:
218
+ schema:
219
+ $ref: '#/components/schemas/ErroSefaz'
220
+
221
+ /nfe/cenarios-mock:
222
+ get:
223
+ tags: [NF-e]
224
+ summary: Listar cenários mock disponíveis
225
+ responses:
226
+ '200':
227
+ description: Lista de cenários
228
+ content:
229
+ application/json:
230
+ schema:
231
+ type: object
232
+ properties:
233
+ cenarios:
234
+ type: array
235
+ items:
236
+ type: object
237
+ properties:
238
+ id:
239
+ type: string
240
+ descricao:
241
+ type: string
242
+ cStat:
243
+ type: string
244
+
245
+ components:
246
+ responses:
247
+ ErroValidacao:
248
+ description: Erro de validação
249
+ content:
250
+ application/json:
251
+ schema:
252
+ $ref: '#/components/schemas/Erro'
253
+
254
+ schemas:
255
+ NFeEndereco:
256
+ type: object
257
+ required: [logradouro, numero, bairro, codigoMunicipio, municipio, uf, cep]
258
+ properties:
259
+ logradouro: { type: string, example: 'Rua das Flores' }
260
+ numero: { type: string, example: '100' }
261
+ complemento: { type: string }
262
+ bairro: { type: string, example: 'Centro' }
263
+ codigoMunicipio: { type: string, example: '3550308' }
264
+ municipio: { type: string, example: 'São Paulo' }
265
+ uf: { type: string, example: 'SP' }
266
+ cep: { type: string, example: '01001000' }
267
+ telefone: { type: string }
268
+
269
+ NFeDocumento:
270
+ type: object
271
+ required: [ide, emitente, destinatario, itens]
272
+ properties:
273
+ chaveAcesso:
274
+ type: string
275
+ description: Opcional — gerada automaticamente se omitida
276
+ example: '35260712345678000199550010000000011000000011'
277
+ ambiente:
278
+ type: integer
279
+ enum: [1, 2]
280
+ example: 2
281
+ ide:
282
+ type: object
283
+ properties:
284
+ uf: { type: string, example: 'SP' }
285
+ codigoMunicipio: { type: string, example: '3550308' }
286
+ serie: { type: integer, example: 1 }
287
+ numero: { type: integer, example: 1 }
288
+ naturezaOperacao: { type: string, example: 'VENDA' }
289
+ emitente:
290
+ type: object
291
+ properties:
292
+ cnpj: { type: string, example: '12345678000199' }
293
+ razaoSocial: { type: string, example: 'EMPRESA EXEMPLO LTDA' }
294
+ ie: { type: string, example: '123456789' }
295
+ crt: { type: string, example: '3' }
296
+ endereco:
297
+ $ref: '#/components/schemas/NFeEndereco'
298
+ destinatario:
299
+ type: object
300
+ properties:
301
+ cpf: { type: string, example: '12345678909' }
302
+ razaoSocial: { type: string, example: 'CONSUMIDOR FINAL' }
303
+ indIEDest: { type: integer, example: 9 }
304
+ endereco:
305
+ $ref: '#/components/schemas/NFeEndereco'
306
+ itens:
307
+ type: array
308
+ items:
309
+ type: object
310
+ properties:
311
+ codigo: { type: string, example: '001' }
312
+ descricao: { type: string, example: 'PRODUTO TESTE' }
313
+ ncm: { type: string, example: '84713012' }
314
+ cfop: { type: string, example: '5102' }
315
+ unidade: { type: string, example: 'UN' }
316
+ quantidade: { type: number, example: 1 }
317
+ valorUnitario: { type: number, example: 100 }
318
+ valorTotal: { type: number, example: 100 }
319
+ cst: { type: string, example: '00' }
320
+ aliquotaIcms: { type: number, example: 18 }
321
+ valorIcms: { type: number, example: 18 }
322
+ frete:
323
+ type: object
324
+ properties:
325
+ modalidade: { type: integer, example: 9 }
326
+ valor: { type: number }
327
+ pagamentos:
328
+ type: array
329
+ items:
330
+ type: object
331
+ properties:
332
+ forma: { type: string, example: '01' }
333
+ valor: { type: number, example: 100 }
334
+
335
+ ResultadoEmissao:
336
+ type: object
337
+ properties:
338
+ chaveAcesso: { type: string }
339
+ retorno:
340
+ type: object
341
+ properties:
342
+ sucesso: { type: boolean }
343
+ autorizado: { type: boolean }
344
+ cStat: { type: string }
345
+ xMotivo: { type: string }
346
+ protocolo: { type: string }
347
+ xmlGerado: { type: string }
348
+ mock: { type: boolean }
349
+
350
+ NFeCancelamento:
351
+ type: object
352
+ required: [chaveAcesso, cnpj, uf, protocolo, justificativa]
353
+ properties:
354
+ chaveAcesso: { type: string }
355
+ cnpj: { type: string, example: '12345678000199' }
356
+ uf: { type: string, example: 'SP' }
357
+ ambiente: { type: integer, example: 2 }
358
+ protocolo: { type: string, example: '135260000000001' }
359
+ justificativa:
360
+ type: string
361
+ minLength: 15
362
+ example: 'Cancelamento por erro de digitacao no pedido'
363
+
364
+ NFeCartaCorrecao:
365
+ type: object
366
+ required: [chaveAcesso, cnpj, uf, correcao]
367
+ properties:
368
+ chaveAcesso: { type: string }
369
+ cnpj: { type: string, example: '12345678000199' }
370
+ uf: { type: string, example: 'SP' }
371
+ ambiente: { type: integer, example: 2 }
372
+ sequencia: { type: integer, example: 1 }
373
+ correcao:
374
+ type: string
375
+ minLength: 15
376
+ example: 'Correcao do endereco de entrega para Rua Nova, 500'
377
+
378
+ NFCeDocumento:
379
+ type: object
380
+ required: [ide, emitente, itens, csc]
381
+ properties:
382
+ ambiente: { type: integer, example: 2 }
383
+ ide:
384
+ type: object
385
+ properties:
386
+ uf: { type: string, example: 'SP' }
387
+ codigoMunicipio: { type: string, example: '3550308' }
388
+ serie: { type: integer, example: 1 }
389
+ numero: { type: integer, example: 1 }
390
+ emitente:
391
+ type: object
392
+ properties:
393
+ cnpj: { type: string }
394
+ razaoSocial: { type: string }
395
+ ie: { type: string }
396
+ crt: { type: string, example: '1' }
397
+ endereco:
398
+ $ref: '#/components/schemas/NFeEndereco'
399
+ destinatario:
400
+ type: object
401
+ properties:
402
+ cpf: { type: string }
403
+ razaoSocial: { type: string }
404
+ itens:
405
+ type: array
406
+ items:
407
+ type: object
408
+ csc:
409
+ type: object
410
+ required: [idCSC, codigo]
411
+ properties:
412
+ idCSC: { type: string, example: '000001' }
413
+ codigo: { type: string, example: 'SEU-CSC-SEFAZ' }
414
+
415
+ ErroSefaz:
416
+ type: object
417
+ properties:
418
+ error: { type: string, example: 'SefazError' }
419
+ code: { type: string, example: 'SEFAZ_204' }
420
+ cStat: { type: string }
421
+ xMotivo: { type: string }
422
+
423
+ Erro:
424
+ type: object
425
+ properties:
426
+ error: { type: string }
427
+ code: { type: string }
428
+ message: { type: string }
@@ -0,0 +1,51 @@
1
+ import { NFCeService } from '../src/index.js';
2
+
3
+ const documento = {
4
+ ambiente: 2,
5
+ ide: { uf: 'SP', codigoMunicipio: '3550308', serie: 1, numero: 1, presenca: 1 },
6
+ emitente: {
7
+ cnpj: '12345678000199',
8
+ razaoSocial: 'LOJA EXEMPLO LTDA',
9
+ nomeFantasia: 'LOJA EXEMPLO',
10
+ ie: '123456789012',
11
+ crt: '1',
12
+ endereco: {
13
+ logradouro: 'Av Paulista', numero: '1000', bairro: 'Bela Vista',
14
+ codigoMunicipio: '3550308', municipio: 'Sao Paulo', uf: 'SP', cep: '01310100',
15
+ },
16
+ },
17
+ destinatario: {
18
+ cpf: '12345678909',
19
+ razaoSocial: 'CONSUMIDOR FINAL',
20
+ },
21
+ itens: [{
22
+ codigo: '001',
23
+ descricao: 'PRODUTO TESTE NFC-E',
24
+ ncm: '22021000',
25
+ cfop: '5102',
26
+ unidade: 'UN',
27
+ quantidade: 2,
28
+ valorUnitario: 5.5,
29
+ valorTotal: 11.0,
30
+ cst: '00',
31
+ aliquotaIcms: 18,
32
+ valorIcms: 1.98,
33
+ }],
34
+ pagamentos: [{ forma: '17', valor: 11.0 }],
35
+ csc: { idCSC: '000001', codigo: 'CODIGO-CSC-EXEMPLO-SEFAZ' },
36
+ informacoesComplementares: 'NFC-e emitida pela biblioteca GHINFE',
37
+ };
38
+
39
+ const service = new NFCeService({ mock: true });
40
+
41
+ console.log('=== GHINFE — NFC-e Modelo 65 ===\n');
42
+
43
+ const doc = service.resolverDocumento(documento);
44
+ const xml = service.gerarXml(doc);
45
+
46
+ console.log('Chave:', doc.chaveAcesso);
47
+ console.log('XML base (sem QR Code):', xml.substring(0, 350) + '...\n');
48
+ console.log('Nota: QR Code v3 é adicionado após assinatura via adicionarQrCode() ou gerarXmlAssinado()\n');
49
+
50
+ const retorno = await service.enviar(xml, doc.chaveAcesso);
51
+ console.log('Retorno mock SEFAZ (XML sem assinatura — apenas demo):', retorno.cStat, '—', retorno.xMotivo);
@@ -0,0 +1,83 @@
1
+ import { NFeService } from '../src/index.js';
2
+
3
+ /** Documento de exemplo — homologação SEFAZ. */
4
+ const documento = {
5
+ chaveAcesso: '35260712345678000199550010000000011000000011',
6
+ ambiente: 2,
7
+ ide: {
8
+ uf: 'SP',
9
+ codigoMunicipio: '3550308',
10
+ serie: 1,
11
+ numero: 1,
12
+ naturezaOperacao: 'VENDA',
13
+ consumidorFinal: 1,
14
+ presenca: 1,
15
+ },
16
+ emitente: {
17
+ cnpj: '12345678000199',
18
+ razaoSocial: 'EMPRESA EXEMPLO LTDA',
19
+ nomeFantasia: 'EXEMPLO',
20
+ ie: '123456789012',
21
+ crt: '3',
22
+ endereco: {
23
+ logradouro: 'Rua Exemplo',
24
+ numero: '100',
25
+ bairro: 'Centro',
26
+ codigoMunicipio: '3550308',
27
+ municipio: 'São Paulo',
28
+ uf: 'SP',
29
+ cep: '01001000',
30
+ },
31
+ },
32
+ destinatario: {
33
+ cpf: '12345678909',
34
+ razaoSocial: 'NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL',
35
+ indIEDest: 9,
36
+ endereco: {
37
+ logradouro: 'Rua Cliente',
38
+ numero: '200',
39
+ bairro: 'Jardim',
40
+ codigoMunicipio: '3550308',
41
+ municipio: 'São Paulo',
42
+ uf: 'SP',
43
+ cep: '01020000',
44
+ },
45
+ },
46
+ itens: [
47
+ {
48
+ codigo: '001',
49
+ descricao: 'NOTA FISCAL EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL',
50
+ ncm: '84713012',
51
+ cfop: '5102',
52
+ unidade: 'UN',
53
+ quantidade: 1,
54
+ valorUnitario: 100.0,
55
+ valorTotal: 100.0,
56
+ cst: '00',
57
+ aliquotaIcms: 18,
58
+ valorIcms: 18,
59
+ },
60
+ ],
61
+ frete: { modalidade: 9 },
62
+ pagamentos: [{ forma: '01', valor: 100.0 }],
63
+ informacoesComplementares: 'Documento gerado pela biblioteca GHINFE',
64
+ };
65
+
66
+ const service = new NFeService({ mock: true });
67
+
68
+ console.log('=== GHINFE — Geração de XML NF-e ===\n');
69
+
70
+ const xml = service.gerarXml(documento);
71
+ console.log('XML gerado (primeiros 500 chars):\n');
72
+ console.log(xml.substring(0, 500) + '...\n');
73
+
74
+ console.log('Para assinar com certificado A1:');
75
+ console.log(' const xmlAssinado = service.gerarXmlAssinado(documento, { pfx: buffer, senha: "..." });\n');
76
+
77
+ console.log('Para emitir completo (mock SEFAZ):');
78
+ console.log(' const resultado = await service.emitir(documento, { pfx, senha });\n');
79
+
80
+ // Emissão mock sem certificado (apenas envio do XML não assinado para demo)
81
+ const retorno = await service.enviar(xml, documento.chaveAcesso);
82
+ console.log('Retorno mock SEFAZ:');
83
+ console.log(JSON.stringify(retorno, null, 2));
@@ -0,0 +1,46 @@
1
+ import { NFSeService } from '../src/index.js';
2
+
3
+ const documento = {
4
+ numero: 1,
5
+ serie: 'NF',
6
+ ambiente: 2,
7
+ codigoMunicipio: '3550308',
8
+ cnpjPrestador: '12345678000199',
9
+ inscricaoMunicipal: '12345678',
10
+ optanteSimplesNacional: 1,
11
+ servico: {
12
+ itemListaServico: '01.01',
13
+ discriminacao: 'Desenvolvimento de software conforme contrato 001/2026',
14
+ codigoMunicipio: '3550308',
15
+ valorServicos: 1500.0,
16
+ aliquotaIss: 5.0,
17
+ valorIss: 75.0,
18
+ issRetido: 2,
19
+ },
20
+ tomador: {
21
+ cnpj: '98765432000100',
22
+ razaoSocial: 'CLIENTE EXEMPLO LTDA',
23
+ email: 'fiscal@cliente.com.br',
24
+ endereco: {
25
+ logradouro: 'Rua das Acacias',
26
+ numero: '200',
27
+ bairro: 'Centro',
28
+ codigoMunicipio: '3550308',
29
+ uf: 'SP',
30
+ cep: '01005000',
31
+ },
32
+ },
33
+ informacoesComplementares: 'NFS-e gerada pela biblioteca GHINFE',
34
+ };
35
+
36
+ const service = new NFSeService({ mock: true });
37
+
38
+ console.log('=== GHINFE — NFS-e ABRASF 2.04 ===\n');
39
+
40
+ const xml = service.gerarXml(documento);
41
+ console.log('XML RPS (trecho):', xml.substring(0, 400) + '...\n');
42
+
43
+ const resultado = await service.emitir(documento);
44
+ console.log('Retorno mock:');
45
+ console.log(' NFS-e:', resultado.retorno.numeroNfse);
46
+ console.log(' Código verificação:', resultado.retorno.codigoVerificacao);
@@ -0,0 +1,14 @@
1
+ import { SefazEndpointResolver } from '../src/index.js';
2
+
3
+ console.log('=== GHINFE — Endpoints SEFAZ Multi-UF ===\n');
4
+
5
+ const ufs = ['SP', 'RJ', 'MG', 'PR', 'RS', 'SC', 'BA', 'GO'];
6
+
7
+ for (const uf of ufs) {
8
+ const { autorizador, endpoints } = SefazEndpointResolver.obterEndpoints(uf, 2);
9
+ console.log(`${uf} → ${autorizador}`);
10
+ console.log(` Autorização: ${endpoints.autorizacao?.substring(0, 70)}...`);
11
+ console.log(` Evento: ${endpoints.evento?.substring(0, 70)}...\n`);
12
+ }
13
+
14
+ console.log('Total UFs suportadas:', SefazEndpointResolver.listarUFs().length);
@@ -0,0 +1,49 @@
1
+ import { NFeService } from '../src/index.js';
2
+ import { NFE_EVENTOS } from '../src/index.js';
3
+
4
+ const chaveAcesso = '35260712345678000199550010000000011000000011';
5
+
6
+ const service = new NFeService({ mock: true, mockEventoScenario: 'registrado' });
7
+
8
+ console.log('=== GHINFE — Cancelamento e CC-e (mock) ===\n');
9
+
10
+ // --- Cancelamento ---
11
+ const dadosCancelamento = {
12
+ chaveAcesso,
13
+ cnpj: '12345678000199',
14
+ uf: 'SP',
15
+ ambiente: 2,
16
+ protocolo: '135260000000001',
17
+ justificativa: 'Cancelamento por erro de digitacao no pedido do cliente',
18
+ };
19
+
20
+ const xmlCancelamento = service.gerarXmlCancelamento(dadosCancelamento);
21
+ console.log('XML Cancelamento (trecho):', xmlCancelamento.substring(0, 300) + '...\n');
22
+
23
+ const retornoCancelamento = await service.enviarEventoMock(
24
+ xmlCancelamento,
25
+ chaveAcesso,
26
+ NFE_EVENTOS.CANCELAMENTO
27
+ );
28
+ console.log('Retorno cancelamento:', retornoCancelamento.cStat, '—', retornoCancelamento.xMotivo);
29
+ console.log('Protocolo evento:', retornoCancelamento.protocolo, '\n');
30
+
31
+ // --- Carta de Correção ---
32
+ const dadosCce = {
33
+ chaveAcesso,
34
+ cnpj: '12345678000199',
35
+ uf: 'SP',
36
+ ambiente: 2,
37
+ sequencia: 1,
38
+ correcao: 'Correcao do endereco de entrega: Rua Nova, 500, Bairro Centro',
39
+ };
40
+
41
+ const xmlCce = service.gerarXmlCartaCorrecao(dadosCce);
42
+ console.log('XML CC-e (trecho):', xmlCce.substring(0, 300) + '...\n');
43
+
44
+ const retornoCce = await service.enviarEventoMock(
45
+ xmlCce,
46
+ chaveAcesso,
47
+ NFE_EVENTOS.CARTA_CORRECAO
48
+ );
49
+ console.log('Retorno CC-e:', retornoCce.cStat, '—', retornoCce.xMotivo);
@@ -0,0 +1,25 @@
1
+ import {
2
+ gerarChaveAcesso,
3
+ validarChaveAcesso,
4
+ parseChaveAcesso,
5
+ calcularDigitoVerificador,
6
+ } from '../src/utils/chave.utils.js';
7
+
8
+ console.log('=== GHINFE — Chave de Acesso ===\n');
9
+
10
+ const chave = gerarChaveAcesso({
11
+ uf: 'SP',
12
+ cnpj: '12345678000199',
13
+ modelo: '55',
14
+ serie: 1,
15
+ numero: 42,
16
+ tipoEmissao: 1,
17
+ codigoNumerico: '12345678',
18
+ });
19
+
20
+ console.log('Chave gerada:', chave);
21
+ console.log('DV válido:', validarChaveAcesso(chave));
22
+ console.log('Parse:', parseChaveAcesso(chave));
23
+
24
+ const chave43 = chave.substring(0, 43);
25
+ console.log('DV calculado:', calcularDigitoVerificador(chave43));