Pular para o conteúdo principal

Guia de Migração: v2 → v3

Este guia ajuda você a migrar do SDK NFE.io v2.x para v3.0.

Visão Geral

O que há de Novo na v3?

Principais Melhorias:

  • TypeScript Nativo - Segurança de tipos completa e suporte a IntelliSense
  • Async/Await Moderno - Sem callbacks, API limpa baseada em promises
  • Zero Dependências - Usa Fetch API nativa do Node.js (Node 18+)
  • Melhor Tratamento de Erros - Classes de erro tipadas com informações detalhadas
  • Retry Automático - Lógica de retry com exponential backoff integrada
  • ESM & CommonJS - Funciona com ambos os sistemas de módulos
  • OpenAPI Types - Tipos gerados automaticamente das especificações da API

⚠️ Requisitos:

  • Node.js >= 18.0.0 (anteriormente v12 na v2)
  • Mudanças incompatíveis na API (veja abaixo)

Cronograma de Migração

Abordagem recomendada:

  1. ✅ Atualize para Node.js 18+ se necessário
  2. ✅ Instale v3 ao lado da v2 (mesmo nome de pacote)
  3. ✅ Migre um recurso por vez
  4. ✅ Atualize os testes
  5. ✅ Remova dependência da v2

Mudanças Incompatíveis

1. Nome do Pacote (INALTERADO)

# v2 e v3 usam o mesmo nome
npm install nfe-io

2. Sintaxe de Import/Require

// v2
var nfe = require('nfe-io')('sua-api-key');

// v3 (ESM)
import { NfeClient } from 'nfe-io';
const nfe = new NfeClient({ apiKey: 'sua-api-key' });

// v3 (CommonJS)
const { NfeClient } = require('nfe-io');
const nfe = new NfeClient({ apiKey: 'sua-api-key' });

3. Configuração

// v2
var nfe = require('nfe-io')('api-key');
nfe.setTimeout(60000);

// v3
const nfe = new NfeClient({
apiKey: 'api-key',
timeout: 60000,
environment: 'production', // ou 'development'
retryConfig: {
maxRetries: 3,
baseDelay: 1000
}
});

4. Callbacks → Async/Await

// v2 (callbacks)
nfe.serviceInvoices.create('company-id', data, function(err, invoice) {
if (err) return console.error(err);
console.log(invoice);
});

// v2 (promises)
nfe.serviceInvoices.create('company-id', data)
.then(invoice => console.log(invoice))
.catch(err => console.error(err));

// v3 (async/await - RECOMENDADO)
try {
const invoice = await nfe.serviceInvoices.create('company-id', data);
console.log(invoice);
} catch (error) {
console.error(error);
}

5. Tratamento de Erros

// v2
nfe.serviceInvoices.create('company-id', data, function(err, invoice) {
if (err) {
if (err.type === 'AuthenticationError') {
// tratar erro de autenticação
}
}
});

// v3
import { AuthenticationError, ValidationError } from 'nfe-io';

try {
const invoice = await nfe.serviceInvoices.create('company-id', data);
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('API key inválida');
} else if (error instanceof ValidationError) {
console.error('Dados inválidos:', error.details);
}
}

6. Formato de Resposta

// v2 - Retorno direto dos dados
const invoice = await nfe.serviceInvoices.retrieve('company-id', 'invoice-id');
console.log(invoice.number);

// v3 - Igual! (sem mudanças)
const invoice = await nfe.serviceInvoices.retrieve('company-id', 'invoice-id');
console.log(invoice.number);

7. Mudanças nos Nomes dos Métodos

Método v2Método v3Notas
create()create()✅ Igual
list()list()✅ Igual
retrieve()retrieve()✅ Igual
update()update()✅ Igual
delete()delete() / remove()⚠️ remove() em Companies
sendEmail()sendEmail()✅ Igual
downloadPdf()downloadPdf()✅ Igual
downloadXml()downloadXml()✅ Igual
N/AcreateAndWait()🆕 Novo! Polling automático
N/AlistAll()🆕 Paginação automática
N/AfindByTaxNumber()🆕 Busca por CNPJ/CPF

Migração Passo a Passo

Passo 1: Instalar v3

# Instalar novo pacote (v2 fica instalada por enquanto)
npm install [email protected]

# Verificar versão do Node.js
node --version # Deve ser >= 18.0.0

Passo 2: Atualizar Imports

- var nfe = require('nfe-io')('api-key');
+ const { NfeClient } = require('nfe-io');
+ const nfe = new NfeClient({ apiKey: 'api-key' });

Ou com ES Modules:

+ import { NfeClient } from 'nfe-io';
+ const nfe = new NfeClient({ apiKey: 'api-key' });

Passo 3: Converter Callbacks para Async/Await

- nfe.serviceInvoices.create('company-id', data, function(err, invoice) {
- if (err) return console.error(err);
- console.log(invoice);
- });

+ async function criarNotaFiscal() {
+ try {
+ const invoice = await nfe.serviceInvoices.create('company-id', data);
+ console.log(invoice);
+ } catch (error) {
+ console.error(error);
+ }
+ }
+ criarNotaFiscal();

Passo 4: Atualizar Tratamento de Erros

+ import { 
+ NfeError,
+ AuthenticationError,
+ ValidationError,
+ NotFoundError
+ } from 'nfe-io';

try {
const invoice = await nfe.serviceInvoices.create('company-id', data);
} catch (error) {
- if (error.type === 'AuthenticationError') {
+ if (error instanceof AuthenticationError) {
console.error('Autenticação falhou');
}
- if (error.type === 'ValidationError') {
+ if (error instanceof ValidationError) {
console.error('Dados inválidos:', error.details);
}
}

Passo 5: Atualizar TypeScript (se aplicável)

// Adicionar tipos ao seu código
import { NfeClient, ServiceInvoice, Company } from 'nfe-io';

const nfe = new NfeClient({ apiKey: 'api-key' });

async function getInvoice(
companyId: string,
invoiceId: string
): Promise<ServiceInvoice> {
return await nfe.serviceInvoices.retrieve(companyId, invoiceId);
}

Passo 6: Remover v2

# Após todo código migrado e testado
# Não há necessidade de desinstalar se estiver na mesma major version
# Apenas atualize suas importações e uso do código

Mudanças na API

Notas Fiscais de Serviço (Service Invoices)

// v2
nfe.serviceInvoices.create('company-id', invoiceData, callback);
nfe.serviceInvoices.list('company-id', callback);
nfe.serviceInvoices.retrieve('company-id', 'invoice-id', callback);
nfe.serviceInvoices.cancel('company-id', 'invoice-id', callback);
nfe.serviceInvoices.sendEmail('company-id', 'invoice-id', callback);
nfe.serviceInvoices.downloadPdf('company-id', 'invoice-id', callback);
nfe.serviceInvoices.downloadXml('company-id', 'invoice-id', callback);

// v3
await nfe.serviceInvoices.create('company-id', invoiceData);
await nfe.serviceInvoices.list('company-id', { pageCount: 50, pageIndex: 0 });
await nfe.serviceInvoices.retrieve('company-id', 'invoice-id');
await nfe.serviceInvoices.cancel('company-id', 'invoice-id');
await nfe.serviceInvoices.sendEmail('company-id', 'invoice-id');
await nfe.serviceInvoices.downloadPdf('company-id', 'invoice-id');
await nfe.serviceInvoices.downloadXml('company-id', 'invoice-id');

// 🆕 Novo na v3: Polling automático para processamento assíncrono
await nfe.serviceInvoices.createAndWait('company-id', invoiceData, {
maxAttempts: 30,
intervalMs: 2000
});

Empresas (Companies)

// v2
nfe.companies.create(companyData, callback);
nfe.companies.list(callback);
nfe.companies.retrieve('company-id', callback);
nfe.companies.update('company-id', updates, callback);
nfe.companies.uploadCertificate('company-id', fileData, password, callback);

// v3 - CRUD Básico (mesmo padrão, agora async)
await nfe.companies.create(companyData);
await nfe.companies.list({ pageCount: 20, pageIndex: 0 });
await nfe.companies.retrieve('company-id');
await nfe.companies.update('company-id', updates);
await nfe.companies.remove('company-id'); // Renomeado de 'delete'

// v3 - Gerenciamento de Certificados (aprimorado)
await nfe.companies.uploadCertificate('company-id', {
file: fileBuffer,
password: 'senha-certificado',
filename: 'certificate.pfx' // Opcional
});

// 🆕 Novo na v3: Utilitários de certificado
const validation = await nfe.companies.validateCertificate(certBuffer, 'senha');
const status = await nfe.companies.getCertificateStatus('company-id');
const warning = await nfe.companies.checkCertificateExpiration('company-id', 30);

// 🆕 Novo na v3: Helpers de paginação
const allCompanies = await nfe.companies.listAll(); // Paginação automática
for await (const company of nfe.companies.listIterator()) {
// Streaming eficiente de memória
}

// 🆕 Novo na v3: Métodos de busca
const company = await nfe.companies.findByTaxNumber(12345678000190); // CNPJ
const matches = await nfe.companies.findByName('Acme'); // Por nome
const withCerts = await nfe.companies.getCompaniesWithCertificates();
const expiring = await nfe.companies.getCompaniesWithExpiringCertificates(30);

Principais Mudanças:

  • delete()remove() (evita palavra reservada JavaScript)
  • uploadCertificate() agora recebe objeto com { file, password, filename? }
  • 🆕 Validação de certificado antes do upload
  • 🆕 Monitoramento de expiração de certificados
  • 🆕 Busca por CNPJ/CPF ou nome
  • 🆕 Paginação automática com listAll() e listIterator()
// v2
nfe.legalPeople.create('company-id', personData, callback);
nfe.legalPeople.list('company-id', callback);
nfe.legalPeople.retrieve('company-id', 'person-id', callback);
nfe.legalPeople.update('company-id', 'person-id', updates, callback);
nfe.legalPeople.delete('company-id', 'person-id', callback);

// v3 (mesmo padrão, apenas async)
await nfe.legalPeople.create('company-id', personData);
await nfe.legalPeople.list('company-id');
await nfe.legalPeople.retrieve('company-id', 'person-id');
await nfe.legalPeople.update('company-id', 'person-id', updates);
await nfe.legalPeople.delete('company-id', 'person-id');

// Mesmo para pessoas físicas
await nfe.naturalPeople.create('company-id', personData);
await nfe.naturalPeople.list('company-id');
await nfe.naturalPeople.retrieve('company-id', 'person-id');
await nfe.naturalPeople.update('company-id', 'person-id', updates);
await nfe.naturalPeople.delete('company-id', 'person-id');

Mudanças:

  • ✅ Validação automática de CNPJ (pessoas jurídicas)
  • ✅ Validação automática de CPF (pessoas físicas)
  • ✅ Mesma interface async/await para ambos os recursos

Webhooks

// v2
nfe.webhooks.create(webhookData, callback);
nfe.webhooks.list(callback);
nfe.webhooks.retrieve('webhook-id', callback);
nfe.webhooks.update('webhook-id', updates, callback);
nfe.webhooks.delete('webhook-id', callback);

// v3
await nfe.webhooks.create('company-id', webhookData);
await nfe.webhooks.list('company-id');
await nfe.webhooks.retrieve('company-id', 'webhook-id');
await nfe.webhooks.update('company-id', 'webhook-id', updates);
await nfe.webhooks.delete('company-id', 'webhook-id');

Exemplos de Código

Antes & Depois: Fluxo Completo de Emissão de Nota Fiscal

Código v2:

var nfe = require('nfe-io')('api-key');

function emitirNotaFiscal(companyId, invoiceData, callback) {
nfe.serviceInvoices.create(companyId, invoiceData, function(err, invoice) {
if (err) return callback(err);

if (invoice.code === 202) {
// Poll manual
var checkInterval = setInterval(function() {
nfe.serviceInvoices.retrieve(companyId, invoice.id, function(err, result) {
if (err) {
clearInterval(checkInterval);
return callback(err);
}

if (result.status === 'issued') {
clearInterval(checkInterval);

// Enviar email
nfe.serviceInvoices.sendEmail(companyId, result.id, function(err) {
if (err) return callback(err);
callback(null, result);
});
}
});
}, 2000);
} else {
// Enviar email
nfe.serviceInvoices.sendEmail(companyId, invoice.id, function(err) {
if (err) return callback(err);
callback(null, invoice);
});
}
});
}

emitirNotaFiscal('company-id', invoiceData, function(err, invoice) {
if (err) return console.error(err);
console.log('Nota fiscal emitida:', invoice.number);
});

Código v3:

import { NfeClient } from 'nfe-io';

const nfe = new NfeClient({ apiKey: 'api-key' });

async function emitirNotaFiscal(companyId, invoiceData) {
// Automaticamente faz polling e envia email
const invoice = await nfe.serviceInvoices.createAndWait(
companyId,
invoiceData,
{ maxAttempts: 30, intervalMs: 2000 }
);

await nfe.serviceInvoices.sendEmail(companyId, invoice.id);

return invoice;
}

// Uso
try {
const invoice = await emitirNotaFiscal('company-id', invoiceData);
console.log('Nota fiscal emitida:', invoice.number);
} catch (error) {
console.error('Falha ao emitir nota fiscal:', error);
}

Antes & Depois: Tratamento de Erros

Código v2:

nfe.serviceInvoices.create('company-id', data, function(err, invoice) {
if (err) {
if (err.type === 'AuthenticationError') {
console.error('API key inválida');
} else if (err.type === 'BadRequestError') {
console.error('Dados inválidos:', err.message);
} else {
console.error('Erro desconhecido:', err);
}
return;
}

console.log('Sucesso:', invoice);
});

Código v3:

import { 
AuthenticationError,
ValidationError,
RateLimitError
} from 'nfe-io';

try {
const invoice = await nfe.serviceInvoices.create('company-id', data);
console.log('Sucesso:', invoice);
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('API key inválida');
} else if (error instanceof ValidationError) {
console.error('Dados inválidos:', error.details);
} else if (error instanceof RateLimitError) {
console.error('Limite de taxa atingido, tentar após:', error.retryAfter);
} else {
console.error('Erro desconhecido:', error);
}
}

Antes & Depois: Operações em Lote

Código v2:

var async = require('async');

async.mapLimit(invoices, 5, function(invoiceData, callback) {
nfe.serviceInvoices.create('company-id', invoiceData, callback);
}, function(err, results) {
if (err) return console.error(err);
console.log('Criados:', results.length);
});

Código v3:

// Não precisa de dependências externas!
async function criarEmLote(companyId, invoices) {
const results = await Promise.allSettled(
invoices.map(data =>
nfe.serviceInvoices.create(companyId, data)
)
);

const succeeded = results.filter(r => r.status === 'fulfilled');
const failed = results.filter(r => r.status === 'rejected');

console.log(`${succeeded.length} com sucesso`);
console.log(`${failed.length} falharam`);

return { succeeded, failed };
}

Migração de Gerenciamento de Certificados

O gerenciamento de certificados no v3 foi significativamente aprimorado:

Abordagem v2:

// v2: Upload e esperar que funcione
const fs = require('fs');
const certBuffer = fs.readFileSync('./certificate.pfx');

nfe.companies.uploadCertificate('company-id', certBuffer, 'senha', (err, result) => {
if (err) {
console.error('Upload falhou:', err);
return;
}
console.log('Certificado carregado');
});

Abordagem v3 (com validação):

// v3: Validar antes do upload
import { readFile } from 'fs/promises';
import { CertificateValidator } from 'nfe-io';

const certBuffer = await readFile('./certificate.pfx');

// 1. Verificar formato do arquivo
if (!CertificateValidator.isSupportedFormat('certificate.pfx')) {
throw new Error('Apenas arquivos .pfx e .p12 são suportados');
}

// 2. Validar certificado
const validation = await nfe.companies.validateCertificate(certBuffer, 'senha');
if (!validation.valid) {
throw new Error(`Certificado inválido: ${validation.error}`);
}

console.log('Certificado expira em:', validation.metadata?.validTo);

// 3. Upload (também valida automaticamente)
const result = await nfe.companies.uploadCertificate('company-id', {
file: certBuffer,
password: 'senha',
filename: 'certificate.pfx'
});

console.log(result.message);

Monitoramento v3:

// Configurar monitoramento de certificados expirando
async function verificarCertificados() {
const expirando = await nfe.companies.getCompaniesWithExpiringCertificates(30);

for (const company of expirando) {
const alerta = await nfe.companies.checkCertificateExpiration(company.id, 30);

if (alerta) {
console.warn(`⚠️ ${company.name}`);
console.warn(` Certificado expira em ${alerta.daysRemaining} dias`);
console.warn(` Data de expiração: ${alerta.expiresOn.toLocaleDateString()}`);

// Enviar alerta ao administrador
await enviarAlertaAdmin({
empresa: company.name,
diasRestantes: alerta.daysRemaining
});
}
}
}

// Executar diariamente
setInterval(verificarCertificados, 24 * 60 * 60 * 1000);

Perguntas Frequentes (FAQ)

P: Posso usar v2 e v3 juntos durante a migração?

R: Sim! Eles usam nomes de pacote diferentes (nfe-io v2 vs nfe-io v3), mas você pode identificá-los pela versão.

// v2 (versão 2.x.x)
const nfeV2 = require('nfe-io')('api-key');

// v3 (versão 3.x.x)
const { NfeClient } = require('nfe-io');
const nfeV3 = new NfeClient({ apiKey: 'api-key' });

P: Preciso alterar minha API key?

R: Não! Sua API key existente funciona tanto com v2 quanto com v3.

P: E se eu ainda estiver no Node.js 16?

R: Você deve atualizar para Node.js 18+ para usar v3. Considere:

  • Atualizar Node.js (recomendado)
  • Permanecer no v2 até poder atualizar
  • Usar Node Version Manager (nvm) para testar v3

P: Há mudanças no formato de dados?

R: Não! Os formatos de request/response da API são os mesmos. Apenas a interface do SDK mudou.

P: O que acontece com meu código v2 após a migração?

R: Mantenha-o até que você tenha migrado e testado completamente. Depois, atualize para a versão 3.x.x.

P: Há diferença de desempenho?

R: Sim! v3 é mais rápido:

  • Sem dependências externas = inicialização mais rápida
  • Fetch API nativo = melhor desempenho
  • Retry integrado = maior confiabilidade

P: Posso usar v3 com JavaScript (não TypeScript)?

R: Com certeza! Os tipos TypeScript são opcionais. v3 funciona perfeitamente com JavaScript puro.

P: E quanto à compatibilidade com versões anteriores?

R: v3 não é compatível com v2. Por isso usamos controle de versão semântico. Siga este guia para migrar.

Precisa de Ajuda?


Boa migração! 🚀

NFE.io

A NFE.io é uma empresa de tecnologia que fornece soluções para automatizar e simplificar a emissão e gestão de notas fiscais eletrônicas. Com suas ferramentas, as empresas podem economizar tempo e reduzir erros, aumentando a eficiência e precisão do processo de emissão de notas fiscais.

Um dos principais cases de sucesso da NFE.io é a implementação da solução na empresa de transporte Rodonaves. Com a automatização da emissão e gestão de notas fiscais eletrônicas, a Rodonaves conseguiu reduzir em até 80% o tempo gasto nesse processo, o que se traduziu em uma significativa melhoria na eficiência operacional. Além disso, a empresa também conseguiu eliminar erros e atrasos na emissão de notas fiscais, o que melhorou a relação com seus clientes e aumentou a confiança dos órgãos fiscais.

Outro exemplo é a implementação da NFE.io na empresa de comércio eletrônico, a Loja Integrada. Com a automatização da emissão de notas fiscais, a Loja Integrada conseguiu aumentar a velocidade de emissão de notas em até 10 vezes, o que permitiu que a empresa atendesse a uma maior quantidade de clientes e, consequentemente, aumentar as suas vendas.

Além desses exemplos, a NFE.io também tem outros cases de sucesso com empresas de setores como indústria, construção, varejo e serviços, mostrando a versatilidade e eficácia da sua solução.

Em resumo, a NFE.io é uma empresa de tecnologia que oferece soluções para automatizar e simplificar a emissão e gestão de notas fiscais eletrônicas, ajudando as empresas a economizar tempo e reduzir erros, melhorando a eficiência e precisão do processo. Com cases de sucesso em diferentes setores, a NFE.io tem se destacado como uma empresa líder em automação fiscal.