@useinvio/nfse-sdk 0.3.0 → 1.0.1

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 CHANGED
@@ -4,9 +4,21 @@
4
4
  [![npm access](https://img.shields.io/badge/npm-public-brightgreen.svg)](https://www.npmjs.com/package/@useinvio/nfse-sdk)
5
5
  [![Node.js](https://img.shields.io/badge/node-%3E%3D20-339933.svg)](https://nodejs.org/)
6
6
 
7
+ [Website](https://sdk.useinvio.com/)
8
+
9
+ <img width="959" height="296" alt="image" src="https://github.com/user-attachments/assets/d6c45737-e7ca-4ea7-a06f-d93b7c16e4f0" />
10
+
11
+ ---
12
+
7
13
  SDK TypeScript para integração com a **NFS-e Nacional** (SEFIN).
8
14
 
9
- Cuida de todo o protocolo de comunicação: certificado A1, assinatura XML (XMLDSIG), compactação GZip/Base64, mTLS, envio e consulta. A aplicação que consome o SDK continua responsável pelas regras de negócio — código de serviço, CST, retenções, numeração da DPS.
15
+ Transforme JSON em DPS/NFS-e, assine com XMLDSIG, compacte em GZip/Base64 e transmita por mTLS sem escrever XML fiscal na mão.
16
+
17
+ O SDK cuida da camada protocolar: certificado A1, montagem de DPS, validações estruturais, assinatura XML, compactação, envio, consulta e normalização de rejeições da SEFIN. A aplicação [...]
18
+
19
+ **Para quem é:** ERPs, SaaS financeiros, plataformas de cobrança, contabilidades digitais e times Node.js/TypeScript que precisam integrar com a NFS-e Nacional.
20
+
21
+ **O que ele não é:** um motor fiscal, consultor tributário ou substituto da validação contábil do seu produto.
10
22
 
11
23
  ---
12
24
 
@@ -14,6 +26,7 @@ Cuida de todo o protocolo de comunicação: certificado A1, assinatura XML (XMLD
14
26
 
15
27
  - [Instalação](#instalação)
16
28
  - [Quick start](#quick-start)
29
+ - [Por que usar](#por-que-usar)
17
30
  - [Escolhendo o ponto de entrada](#escolhendo-o-ponto-de-entrada)
18
31
  - [Cliente orientado a recursos](#cliente-orientado-a-recursos)
19
32
  - [Certificado A1](#certificado-a1)
@@ -28,6 +41,8 @@ Cuida de todo o protocolo de comunicação: certificado A1, assinatura XML (XMLD
28
41
  - [Referência da API](#referência-da-api)
29
42
  - [Desenvolvimento](#desenvolvimento)
30
43
  - [Publicação no npm](#publicação-no-npm)
44
+ - [Divulgação e exemplos](#divulgação-e-exemplos)
45
+ - [Assistente GPT](#assistente-gpt)
31
46
 
32
47
  ---
33
48
 
@@ -102,6 +117,17 @@ try {
102
117
 
103
118
  ---
104
119
 
120
+ ## Por que usar
121
+
122
+ - Entrada JSON tipada para construir DPS no layout nacional.
123
+ - Assinatura XMLDSIG, GZip/Base64 e mTLS encapsulados em uma API Node.js.
124
+ - Erros oficiais da SEFIN preservados em formato estruturado.
125
+ - Builder separado para inspecionar ou salvar o XML antes de transmitir.
126
+ - Cliente `NfseClient` para configurar certificado, ambiente e defaults uma vez.
127
+ - Validação explícita de campos fiscais obrigatórios, sem defaults silenciosos.
128
+
129
+ ---
130
+
105
131
  ## Escolhendo o ponto de entrada
106
132
 
107
133
  | Situação | O que usar |
@@ -247,7 +273,7 @@ await emitirNfse(dpsXml, pfx, { dpsId: 'DPS0001', ambiente: 'restrita' });
247
273
  Use quando a aplicação mantém os perfis de prestador e serviço e quer que a SDK monte o XML.
248
274
 
249
275
  Para a referência completa de campos aceitos no JSON, consulte [JSON_MAPPING.md](./JSON_MAPPING.md).
250
- O builder valida formatos e combinações mínimas antes de gerar XML, mas não escolhe códigos fiscais por você. Campos como `tributacaoMunicipal` e `totTrib` precisam ser informados explicitamente; a SDK não assume tributação nem carga tributária por default.
276
+ O builder valida formatos e combinações mínimas antes de gerar XML, mas não escolhe códigos fiscais por você. Campos como `tributacaoMunicipal` e `totTrib` precisam ser informados explicita[...]
251
277
 
252
278
  ```ts
253
279
  import { emitirNfse, loadPfx, type DpsJsonRequest } from '@useinvio/nfse-sdk';
@@ -480,7 +506,7 @@ npm run build # compila para dist/
480
506
  npm test # build + tipos + testes unitários
481
507
  ```
482
508
 
483
- `npm test` também valida uma DPS gerada contra os XSD oficiais em `schemas/nfse/v1.01/Schemas/1.01`. Para compatibilidade com `xmllint`, o teste corrige em uma cópia temporária a âncora regex de `TSSerieDPS` presente no XSD oficial; os arquivos baixados do gov.br ficam preservados sem alteração.
509
+ `npm test` também valida uma DPS gerada contra os XSD oficiais em `schemas/nfse/v1.01/Schemas/1.01`. Para compatibilidade com `xmllint`, o teste corrige em uma cópia temporária a âncora regex[...]
484
510
 
485
511
  ### Uso local em outro projeto
486
512
 
@@ -510,9 +536,26 @@ O pacote usa `publishConfig.access = public`, necessário para publicar um pacot
510
536
 
511
537
  ---
512
538
 
539
+ ## Divulgação e exemplos
540
+
541
+ - Exemplos copiáveis ficam em [`examples/`](./examples).
542
+ - Material de lançamento, mensagens para redes e prompt de landing page ficam em [`docs/launch.md`](./docs/launch.md).
543
+
544
+ ---
545
+
546
+ ## Assistente GPT
547
+
548
+ Para criar um GPT que ajude outros devs a implementar e documentar esta SDK, use:
549
+
550
+ - [`docs/gpt-assistant.md`](./docs/gpt-assistant.md): configuracao completa do GPT, instrucoes copiaveis, starters e testes de preview.
551
+ - [`docs/gpt-knowledge.md`](./docs/gpt-knowledge.md): resumo compacto para subir como arquivo de Knowledge.
552
+
553
+ ---
554
+
513
555
  ## Princípios de design
514
556
 
515
557
  - Sem dependência de banco de dados, config de aplicação ou estado de tenant.
516
558
  - Funções pequenas, testáveis e reutilizáveis.
517
559
  - Erros oficiais da SEFIN são preservados na íntegra, não engolidos.
518
560
  - O SDK transporta declarações fiscais; não valida se estão contabilmente corretas.
561
+
@@ -0,0 +1,12 @@
1
+ # Examples
2
+
3
+ Copyable entry points for common NFS-e Nacional flows.
4
+
5
+ ## Files
6
+
7
+ - [`generate-dps-xml.ts`](./generate-dps-xml.ts): build an unsigned DPS XML from JSON.
8
+ - [`emit-homologation.ts`](./emit-homologation.ts): emit in the restricted/sandbox SEFIN environment.
9
+ - [`client-resource.ts`](./client-resource.ts): use `NfseClient` with certificate and defaults configured once.
10
+ - [`handle-errors.ts`](./handle-errors.ts): normalize SEFIN rejection details for your application.
11
+
12
+ The examples assume Node.js 20+ and a valid A1/PFX certificate. They are intentionally explicit about fiscal fields; the SDK does not infer municipal taxation, withholding, CST or total tax burden.
@@ -0,0 +1,50 @@
1
+ import { NfseClient } from '@useinvio/nfse-sdk';
2
+
3
+ const client = new NfseClient({
4
+ environment: 'sandbox',
5
+ certificate: {
6
+ content: process.env.NFSE_CERTIFICATE_BASE64!,
7
+ password: process.env.NFSE_CERTIFICATE_PASSWORD!,
8
+ },
9
+ defaults: {
10
+ prestador: {
11
+ cnpj: '12345678000195',
12
+ tpInsc: '2',
13
+ cLocEmi: '4106902',
14
+ serie: '1601',
15
+ opSimpNac: '1',
16
+ regEspTrib: '0',
17
+ },
18
+ servico: {
19
+ cTribNac: '010201',
20
+ xDescServ: 'Desenvolvimento de software',
21
+ cLocPrestacao: '4106902',
22
+ cNBS: '115022000',
23
+ },
24
+ },
25
+ });
26
+
27
+ const invoice = await client.invoices.create({
28
+ emissao: {
29
+ nDPS: '2',
30
+ valores: { vServ: '1000.00' },
31
+ tomador: {
32
+ CPF: '00000000000',
33
+ xNome: 'Cliente Exemplo',
34
+ },
35
+ tributacaoMunicipal: {
36
+ tribISSQN: '3',
37
+ tpRetISSQN: '1',
38
+ },
39
+ tributacaoFederal: {
40
+ piscofins: { CST: '07' },
41
+ },
42
+ totTrib: {
43
+ pTotTribFed: '0.00',
44
+ pTotTribEst: '0.00',
45
+ pTotTribMun: '5.00',
46
+ },
47
+ },
48
+ });
49
+
50
+ console.log(invoice.chaveAcesso);
@@ -0,0 +1,54 @@
1
+ import { EmitirNotaError, emitirNfse, loadPfx, type DpsJsonRequest } from '@useinvio/nfse-sdk';
2
+
3
+ const pfx = loadPfx('./certificado.pfx', process.env.PFX_PASSWORD!);
4
+
5
+ const nota: DpsJsonRequest = {
6
+ ambiente: 'restrita',
7
+ prestador: {
8
+ cnpj: '12345678000195',
9
+ tpInsc: '2',
10
+ cLocEmi: '4106902',
11
+ serie: '1601',
12
+ opSimpNac: '1',
13
+ regEspTrib: '0',
14
+ },
15
+ servico: {
16
+ cTribNac: '010201',
17
+ xDescServ: 'Desenvolvimento de software',
18
+ cLocPrestacao: '4106902',
19
+ cNBS: '115022000',
20
+ },
21
+ emissao: {
22
+ nDPS: '1',
23
+ dhEmi: '2026-06-15T10:30:00-03:00',
24
+ dCompet: '2026-06-01',
25
+ valores: { vServ: '1500.00' },
26
+ tributacaoMunicipal: {
27
+ tribISSQN: '3',
28
+ cPaisResult: 'BR',
29
+ tpRetISSQN: '1',
30
+ },
31
+ tributacaoFederal: {
32
+ piscofins: { CST: '07' },
33
+ },
34
+ totTrib: {
35
+ pTotTribFed: '0.00',
36
+ pTotTribEst: '0.00',
37
+ pTotTribMun: '5.00',
38
+ },
39
+ },
40
+ };
41
+
42
+ try {
43
+ const resultado = await emitirNfse(nota, pfx);
44
+ console.log(resultado.chaveAcesso);
45
+ console.log(resultado.nfseXml);
46
+ } catch (error) {
47
+ if (!(error instanceof EmitirNotaError)) throw error;
48
+
49
+ console.error(`Emissao rejeitada pela SEFIN: HTTP ${error.status}`);
50
+ for (const rejeicao of error.erros) {
51
+ console.error(`${rejeicao.Codigo}: ${rejeicao.Descricao}`);
52
+ if (rejeicao.Complemento) console.error(rejeicao.Complemento);
53
+ }
54
+ }
@@ -0,0 +1,43 @@
1
+ import { buildDpsFromJson, type DpsJsonRequest } from '@useinvio/nfse-sdk';
2
+
3
+ const nota: DpsJsonRequest = {
4
+ ambiente: 'restrita',
5
+ prestador: {
6
+ cnpj: '12345678000195',
7
+ tpInsc: '2',
8
+ cLocEmi: '4106902',
9
+ serie: '1601',
10
+ opSimpNac: '1',
11
+ regEspTrib: '0',
12
+ },
13
+ servico: {
14
+ cTribNac: '010201',
15
+ xDescServ: 'Desenvolvimento de software',
16
+ cLocPrestacao: '4106902',
17
+ cNBS: '115022000',
18
+ },
19
+ emissao: {
20
+ nDPS: '1',
21
+ dhEmi: '2026-06-15T10:30:00-03:00',
22
+ dCompet: '2026-06-01',
23
+ valores: { vServ: '1500.00' },
24
+ tributacaoMunicipal: {
25
+ tribISSQN: '3',
26
+ cPaisResult: 'BR',
27
+ tpRetISSQN: '1',
28
+ },
29
+ tributacaoFederal: {
30
+ piscofins: { CST: '07' },
31
+ },
32
+ totTrib: {
33
+ pTotTribFed: '0.00',
34
+ pTotTribEst: '0.00',
35
+ pTotTribMun: '5.00',
36
+ },
37
+ },
38
+ };
39
+
40
+ const { id, xml } = buildDpsFromJson(nota);
41
+
42
+ console.log(id);
43
+ console.log(xml);
@@ -0,0 +1,24 @@
1
+ import { EmitirNotaError, emitirNfse, loadPfx, type DpsJsonRequest } from '@useinvio/nfse-sdk';
2
+
3
+ async function emitWithStructuredErrors(nota: DpsJsonRequest) {
4
+ const pfx = loadPfx('./certificado.pfx', process.env.PFX_PASSWORD!);
5
+
6
+ try {
7
+ return await emitirNfse(nota, pfx);
8
+ } catch (error) {
9
+ if (!(error instanceof EmitirNotaError)) throw error;
10
+
11
+ return {
12
+ rejected: true,
13
+ status: error.status,
14
+ dpsId: error.dpsId,
15
+ errors: error.erros.map((rejeicao) => ({
16
+ code: rejeicao.Codigo,
17
+ message: rejeicao.Descricao,
18
+ detail: rejeicao.Complemento,
19
+ })),
20
+ };
21
+ }
22
+ }
23
+
24
+ void emitWithStructuredErrors({} as DpsJsonRequest);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@useinvio/nfse-sdk",
3
- "version": "0.3.0",
4
- "description": "SDK TypeScript para integração técnica com a NFS-e Nacional.",
3
+ "version": "1.0.1",
4
+ "description": "TypeScript SDK for Brazil's national NFS-e: JSON to DPS/XML, XMLDSIG, GZip/Base64, mTLS and SEFIN errors.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
@@ -16,6 +16,9 @@
16
16
  "dist/*.d.ts",
17
17
  "dist/*.js",
18
18
  "dist/*.js.map",
19
+ "docs/*.md",
20
+ "examples/*.ts",
21
+ "examples/README.md",
19
22
  "README.md",
20
23
  "JSON_MAPPING.md",
21
24
  "LICENSE"
@@ -29,9 +32,18 @@
29
32
  "keywords": [
30
33
  "nfse",
31
34
  "nfs-e",
35
+ "nfs-e-nacional",
32
36
  "nota-fiscal",
37
+ "nota-fiscal-servico",
38
+ "dps",
33
39
  "sefin",
34
- "sped"
40
+ "sped",
41
+ "xml-dsig",
42
+ "xmldsig",
43
+ "mtls",
44
+ "typescript",
45
+ "brazil",
46
+ "erp"
35
47
  ],
36
48
  "repository": {
37
49
  "type": "git",