Documentação Completa

API completa para cálculo de impostos da Reforma Tributária com autenticação segura e sistema de créditos

✅ Alíquotas Atualizadas
Sempre com valores corretos
🔐 Autenticação Segura
Tokens JWT criptografados
💳 10 Créditos Grátis
No cadastro automático
ℹ️ Novidade v2.0: Sistema totalmente atualizado com alíquotas sempre corretas e sistema de créditos integrado. Faça seu cadastro e receba 10 cálculos gratuitos!
🚀 Testar rapidamente com Postman:

Baixe nossa collection pronta e comece a testar em segundos!

Download
🔑 Autenticação Bearer:

Sim! Os tokens continuam sendo do tipo Bearer. Use assim:

Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

Autenticação

✅ Autenticação Moderna e Segura: Sistema de autenticação JWT com tokens criptografados, auto-renovação e verificação de segurança em todas as requisições.

1. Registrar Novo Usuário

Cadastro automático com 10 créditos grátis!

POST /api/auth/register
curl -X POST http://localhost:3000/api/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "seu-email@gmail.com",
    "password": "SuaSenha123!",
    "name": "Seu Nome Completo",
    "company": "Sua Empresa Ltda",
    "cnpj": "12.345.678/0001-90",
    "phone": "(11) 98765-4321"
  }'

Campos obrigatórios: email, password

Resposta de Sucesso (201 - SEM TOKEN):

{
  "success": true,
  "message": "Usuário registrado com sucesso! Você recebeu 10 créditos grátis. Agora faça login para obter seu token de acesso.",
  "user": {
    "id": "uuid-do-usuario",
    "email": "seu-email@gmail.com",
    "name": "Seu Nome Completo",
    "credits": 10,
    "emailVerified": false
  },
  "timestamp": "2025-01-10T10:00:00.000Z"
}
⚠️ Importante: O registro NÃO retorna token! Após criar a conta, você precisa fazer login (próximo passo) para obter o access_token.

2. Fazer Login (Obter Token)

Após registrar ou quando precisar de um novo token, faça login:

POST /api/auth/login
curl -X POST http://localhost:3000/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "seu-email@gmail.com",
    "password": "SuaSenha123!"
  }'

Resposta:

{
  "success": true,
  "message": "Login realizado com sucesso",
  "session": {
    "access_token": "eyJhbGciOiJIUzI1NiIs...",
    "refresh_token": "v1.MXZLb3JhZ...",
    "expires_in": 3600
  },
  "user": {
    "id": "uuid-do-usuario",
    "email": "seu-email@gmail.com",
    "credits": 10,
    "is_active": true
  }
}

3. Renovar Token

Quando o access_token expirar (após 1 hora), use o refresh_token para obter um novo:

POST /api/auth/refresh
curl -X POST http://localhost:3000/api/auth/refresh \
  -H "Content-Type: application/json" \
  -d '{
    "refresh_token": "v1.MXZLb3JhZ..."
  }'

Gerenciamento de Tokens

Como Funcionam os Tokens

Access Token

  • ✅ Usado em todas as requisições
  • ⏱️ Validade: 1 hora
  • 🔄 Renovável com refresh_token
  • 📍 Onde usar: Header Authorization: Bearer TOKEN

Refresh Token

  • 🔄 Usado apenas para renovar access_token
  • ⏱️ Validade: 7 dias
  • 💾 Guardar de forma segura
  • 🚫 NÃO usar em requisições normais
ℹ️ Onde os Tokens Ficam?
Os tokens são gerenciados de forma segura pelo sistema de autenticação:
  • Sessões ativas são mantidas de forma criptografada
  • Refresh tokens permitem renovação automática
  • Seus dados ficam protegidos e privados

E se Perdi Meu Token?

💡 Solução: Fazer Login Novamente

Tokens NÃO são "recuperáveis" - eles são gerados dinamicamente pelo Supabase. Se perdeu, basta fazer login novamente para obter um novo token válido.

POST /api/auth/login
{ "email": "...", "password": "..." }

→ Gera novo access_token válido por 1 hora
→ Gera novo refresh_token válido por 7 dias

Usar Token nas Requisições

Adicione o token no header Authorization:

curl -X POST http://localhost:3000/api/calcular-impostos \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{ ... }'

Sistema de Créditos

🎁 10 Créditos Grátis no Cadastro!

Todo novo usuário recebe 10 créditos gratuitos automaticamente via trigger do banco. Não precisa fazer nada - é automático!

Como Funciona

1
Cadastro - Recebe 10 créditos grátis automaticamente
2
Operações - Consomem créditos:
  • • Calcular impostos: 1 crédito
  • • Validar XML: 1 crédito
  • • Converter XML: 2 créditos
3
Verificação - Antes de processar, sistema verifica se tem créditos suficientes
4
Processamento - Após processar a operação, decrementa os créditos correspondentes
5
Sem Créditos - Retorna erro 402 Payment Required

Verificar Saldo de Créditos

GET /api/auth/credits
curl -X GET http://localhost:3000/api/auth/credits \
  -H "Authorization: Bearer SEU_TOKEN"

Resposta:

{
  "success": true,
  "data": {
    "userId": "uuid-do-usuario",
    "email": "seu-email@gmail.com",
    "credits": 7
  }
}

Créditos na Resposta do Cálculo

Toda resposta de cálculo inclui informações sobre créditos:

{
  "success": true,
  "data": { ... },
  "meta": {
    "creditsUsed": 1,
    "creditsRemaining": 9
  }
}

Início Rápido em 3 Passos

1 Registrar

curl -X POST http://localhost:3000/api/auth/register \
  -H "Content-Type: application/json" \
  -d '{"email":"teste@gmail.com","password":"senha123","name":"Teste"}'

→ Recebe 10 créditos grátis
→ Recebe access_token e refresh_token

🏷️ NCM e Alíquotas Diferenciadas

NCM é opcional! Informe para alíquotas diferenciadas conforme a Reforma Tributária 2026.

🛒 Cesta Básica

NCM: 01010101

Alíquotas: IBS 0%, CBS 0%

💊 Medicamentos

NCM: 30049099

Alíquotas: IBS 0.5%, CBS 4.5%

📚 Educação

NCM: 49011000

Alíquotas: IBS 0%, CBS 0%

🧴 Higiene

NCM: 34011100

Alíquotas: IBS 0.75%, CBS 6.75%

# Exemplo com NCM (Cesta Básica)
curl -X POST http://localhost:3000/api/calcular-impostos \
  -H "Authorization: Bearer SEU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "valorFrete": 1000,
    "dataEmissao": "2026-06-15",
    "ufOrigem": "SP",
    "ufDestino": "RJ",
    "municipioDestino": "Rio de Janeiro",
    "cst": "00",
    "cClassTrib": "00",
    "ncm": "01010101"
}'

💡 Dica: Se NCM não informado, usa alíquota padrão de transporte (IBS 0.1%, CBS 0.9%)

2 Calcular Impostos

curl -X POST http://localhost:3000/api/calcular-impostos \
  -H "Authorization: Bearer SEU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "valorFrete": 1000,
    "dataEmissao": "2026-06-15",
    "ufOrigem": "SP",
    "ufDestino": "RJ",
    "municipioDestino": "Rio de Janeiro",
    "cst": "00",
    "cClassTrib": "00",
    "regimeTributario": "presumido",
    "ncm": "01010101"
}'

→ Consome 1 crédito
→ Retorna cálculo completo com ICMS + PIS + COFINS
→ Mostra créditos restantes

3 Ver Histórico

curl -X GET http://localhost:3000/api/historico \
  -H "Authorization: Bearer SEU_TOKEN"

→ Ver todos os cálculos realizados
→ Paginação disponível (limit, offset)
→ Ordenado por data (mais recente primeiro)

🏷️ NCM e Alíquotas Diferenciadas

Como Funciona o NCM

O código NCM (Nomenclatura Comum do Mercosul) permite aplicar alíquotas diferenciadas conforme a categoria do produto transportado.

1
Informe o NCM: Adicione o campo ncm na requisição
2
Consulta Automática: Sistema busca alíquotas específicas
3
Economia: Impostos reduzidos automaticamente

📊 Alíquotas por Categoria

Cesta Básica
Carnes, leite, arroz, feijão
IBS 0% | CBS 0%
Medicamentos
Medicamentos essenciais
IBS 0% | CBS 0%
Educação
Livros, materiais escolares
IBS 0% | CBS 0%
Sem NCM
Alíquotas padrão de transporte
IBS 0.1% | CBS 0.9%

⚠️ Validação de NCM

Importante: Se você informar um NCM que não existe em nossa base de dados, o cálculo não será executado. Você receberá um erro informando que o NCM não foi encontrado. Isso garante que você esteja usando alíquotas corretas e atualizadas.

🔍 Consultar NCMs Disponíveis

GET /api/ncm/stats

Estatísticas dos NCMs cadastrados

GET /api/ncm/categorias

Lista todas as categorias disponíveis

Todos os Endpoints

Autenticação (Públicos)

POST /api/auth/register
Registrar usuário
POST /api/auth/login
Fazer login
POST /api/auth/refresh
Renovar token
POST /api/auth/logout
Fazer logout Requer Auth
GET /api/auth/profile
Ver perfil Requer Auth
GET /api/auth/credits
Ver créditos Requer Auth

Operações (Requerem Autenticação + Créditos)

POST /api/calcular-impostos
💳 1 Crédito

Calcula impostos (ICMS, PIS, COFINS ou IBS, CBS)

POST /api/converter-xml
💳 2 Créditos

Converte XML CTe para o novo formato da reforma

POST /api/validar-xml
💳 1 Crédito

Valida XML CTe antes de converter

GET /api/historico
Ver histórico de operações
GET /api/estatisticas
Ver estatísticas de uso

Informações (Públicos)

GET /api/cronograma
Cronograma da reforma (2026-2033)
GET /api/cronograma/:ano
Cronograma de um ano específico

Conversão de XML CTe

Converta automaticamente XMLs de CTe do formato antigo para o novo padrão da reforma tributária.

Converter XML (2 Créditos)

POST /api/converter-xml 💳 2 Créditos

Converte um XML de CTe completo, calculando os novos impostos IBS e CBS e atualizando os campos conforme o novo padrão.

curl -X POST http://localhost:3000/api/converter-xml \
  -H "Authorization: Bearer SEU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "xmlContent": "...",
    "dataEmissao": "2026-01-15"
  }'

Resposta:

{
  "success": true,
  "data": {
    "xmlNovo": "... (convertido) ...",
    "impostosCalculados": {
      "ibsTotal": 10.00,
      "cbs": 90.00,
      "totalImpostos": 100.00
    },
    "resumoConversao": {
      "camposAdicionados": ["IBSCBS.vBC", "IBSCBS.pIBS"],
      "camposRemovidos": ["ICMS.ICMS00"]
    }
  },
  "meta": {
    "creditsUsed": 2,
    "creditsRemaining": 8
  }
}

⚠️ Importante: A conversão de XML consome 2 créditos pois realiza tanto o cálculo dos impostos quanto a conversão completa do documento.

Validar XML (1 Crédito)

POST /api/validar-xml 💳 1 Crédito

Valida se o XML está no formato correto antes de converter. Útil para verificar a estrutura sem gastar os 2 créditos da conversão completa.

curl -X POST http://localhost:3000/api/validar-xml \
  -H "Authorization: Bearer SEU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "xmlContent": "..."
  }'

Resposta:

{
  "success": true,
  "data": {
    "isValid": true,
    "errors": []
  },
  "meta": {
    "creditsUsed": 1,
    "creditsRemaining": 9
  }
}

💡 Dica: Use validar-xml primeiro (1 crédito) para verificar se o arquivo está correto, depois use converter-xml (2 créditos) para fazer a conversão completa.

Cliente JavaScript

Use esta classe para integrar facilmente a dofiscal API em sua aplicação:

class DofiscalClient {
  constructor(apiUrl = 'http://localhost:3000') {
    this.apiUrl = apiUrl;
    this.accessToken = localStorage.getItem('dofiscal_token');
    this.refreshToken = localStorage.getItem('dofiscal_refresh');
  }

  // ========== AUTENTICAÇÃO ==========
  
  async register(email, password, name) {
    const res = await fetch(`${this.apiUrl}/api/auth/register`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ email, password, name })
    });
    const data = await res.json();
    
    // Register NÃO retorna session/token
    // Você precisa fazer login() depois para obter o token
    
    return data;
  }

  async login(email, password) {
    const res = await fetch(`${this.apiUrl}/api/auth/login`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ email, password })
    });
    const data = await res.json();
    
    if (data.success && data.session) {
      this.saveTokens(data.session);
    }
    return data;
  }

  async refreshAccessToken() {
    const res = await fetch(`${this.apiUrl}/api/auth/refresh`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ refresh_token: this.refreshToken })
    });
    const data = await res.json();
    
    if (data.success && data.session) {
      this.saveTokens(data.session);
    }
    return data;
  }

  logout() {
    this.accessToken = null;
    this.refreshToken = null;
    localStorage.removeItem('dofiscal_token');
    localStorage.removeItem('dofiscal_refresh');
  }

  saveTokens(session) {
    this.accessToken = session.access_token;
    this.refreshToken = session.refresh_token;
    localStorage.setItem('dofiscal_token', this.accessToken);
    localStorage.setItem('dofiscal_refresh', this.refreshToken);
  }

  // ========== REQUISIÇÕES ==========

  async request(endpoint, options = {}) {
    if (!this.accessToken) {
      throw new Error('Não autenticado. Faça login primeiro.');
    }

    let res = await fetch(`${this.apiUrl}${endpoint}`, {
      ...options,
      headers: {
        ...options.headers,
        'Authorization': `Bearer ${this.accessToken}`,
        'Content-Type': 'application/json'
      }
    });

    // Auto-renovar se token expirou
    if (res.status === 403 && this.refreshToken) {
      await this.refreshAccessToken();
      res = await fetch(`${this.apiUrl}${endpoint}`, {
        ...options,
        headers: {
          ...options.headers,
          'Authorization': `Bearer ${this.accessToken}`,
          'Content-Type': 'application/json'
        }
      });
    }

    return res.json();
  }

  // ========== MÉTODOS DA API ==========

  async calcularImpostos(payload) {
    return this.request('/api/calcular-impostos', {
      method: 'POST',
      body: JSON.stringify(payload)
    });
  }

  async getCredits() {
    return this.request('/api/auth/credits');
  }

  async getHistorico(limit = 50, offset = 0) {
    return this.request(`/api/historico?limit=${limit}&offset=${offset}`);
  }

  async getEstatisticas() {
    return this.request('/api/estatisticas');
  }

  async converterXml(xmlContent, dataEmissao) {
    return this.request('/api/converter-xml', {
      method: 'POST',
      body: JSON.stringify({ xmlContent, dataEmissao })
    });
  }

  async validarXml(xmlContent) {
    return this.request('/api/validar-xml', {
      method: 'POST',
      body: JSON.stringify({ xmlContent })
    });
  }

  async getCronograma() {
    // Público - não precisa auth
    const res = await fetch(`${this.apiUrl}/api/cronograma`);
    return res.json();
  }
}

// ========== EXEMPLO DE USO ==========

const dofiscal = new DofiscalClient();

// 1. Primeiro: Registrar (se for novo usuário)
await dofiscal.register('usuario@gmail.com', 'senha123', 'Seu Nome');

// 2. Depois: Fazer login para pegar o token
await dofiscal.login('usuario@gmail.com', 'senha123');

// 2. Calcular impostos
const resultado = await dofiscal.calcularImpostos({
  valorFrete: 1000,
  dataEmissao: '2025-06-15',
  ufOrigem: 'SP',
  ufDestino: 'RJ',
  municipioDestino: 'Rio de Janeiro',
  cst: '00',
  cClassTrib: '00',
  regimeTributario: 'presumido'
});

                    console.log('Total impostos:', resultado.data.totalImpostos);
console.log('Créditos restantes:', resultado.meta.creditsRemaining);

// 3. Ver créditos
const creditos = await dofiscal.getCredits();
console.log('Saldo:', creditos.data.credits);

// 4. Ver histórico
const historico = await dofiscal.getHistorico(10);
console.log('Total cálculos:', historico.data.length);

// 5. Converter XML CTe (consome 2 créditos)
const conversao = await dofiscal.converterXml(
  '...',
  '2026-01-15'
);
console.log('XML convertido:', conversao.data.xmlNovo);

// 6. Validar XML CTe (consome 1 crédito)
const validacao = await dofiscal.validarXml('...');
console.log('XML válido:', validacao.data.isValid);

💡 Dica: Copie esta classe pronta para usar e integre facilmente em sua aplicação React, Vue, Angular ou JavaScript puro!

Exemplos Práticos

Exemplo 1: Cálculo Sistema Atual (2025)

{
  "valorFrete": 1000,
  "dataEmissao": "2025-06-15",
  "ufOrigem": "SP",
  "ufDestino": "RJ",
  "municipioDestino": "Rio de Janeiro",
  "cst": "00",
  "cClassTrib": "00",
  "regimeTributario": "presumido"
}

Resultado:

{
  "success": true,
  "data": {
    "sistema": "atual",
    "valorFrete": 1000,
    "impostos": {
      "icms": {
        "valor": 136.36,
        "aliquota": 0.12,
        "baseCalculo": 1136.36
      },
      "pis": {
        "valor": 6.5,
        "aliquota": 0.0065
      },
      "cofins": {
        "valor": 30,
        "aliquota": 0.03
      }
    },
    "totalImpostos": 172.86,
    "observacoes": [
      "Sistema Atual - Antes da Reforma Tributária",
      "ICMS: R$ 136.36 (12.00%)",
      "PIS: R$ 6.50 (0.6500%)",
      "COFINS: R$ 30.00 (3.00%)",
      "Regime Tributário: PRESUMIDO"
    ]
  },
  "meta": {
    "creditsUsed": 1,
    "creditsRemaining": 9
  }
}

Exemplo 2: Cálculo Sistema Reforma (2026)

{
  "valorFrete": 1000,
  "dataEmissao": "2026-06-15",
  "ufOrigem": "SP",
  "ufDestino": "RJ",
  "municipioDestino": "Rio de Janeiro",
  "cst": "00",
  "cClassTrib": "00",
  "regimeTributario": "presumido"
}

Resultado:

{
  "success": true,
  "data": {
    "sistema": "reforma",
    "valorFrete": 1000,
    "impostos": {
      "icms": { "valor": 136.36 },
      "pis": { "valor": 6.5 },
      "cofins": { "valor": 30 },
      "ibs": {
        "valor": 1.0,
        "aliquota": 0.001,
        "repartição": {
          "estadual": 0.9,
          "municipal": 0.1
        }
      },
      "cbs": {
        "valor": 9.0,
        "aliquota": 0.009
      }
    },
    "totalImpostos": 182.86,
    "observacoes": [
      "Sistema da Reforma Tributária (EC 132/2023)",
      "⚠️  ATENÇÃO: Durante a transição, AMBOS os sistemas coexistem!",
      "💰 SISTEMA ANTIGO: ICMS + PIS + COFINS",
      "🆕 SISTEMA NOVO: IBS + CBS"
    ]
  },
  "meta": {
    "creditsUsed": 1,
    "creditsRemaining": 8
  }
}

Códigos de Erro

401 TOKEN_REQUIRED

Token de acesso não fornecido. Adicione Authorization: Bearer TOKEN no header.

402 INSUFFICIENT_CREDITS

Créditos insuficientes para realizar o cálculo. Resposta inclui créditos disponíveis e necessários.

403 TOKEN_INVALID

Token inválido ou expirado. Faça login novamente ou use refresh_token.

404 ALIQUOTA_NOT_FOUND

Alíquota não encontrada no banco para os parâmetros informados. Verifique se o banco foi populado.

500 INTERNAL_ERROR

Erro interno do servidor. Verifique os logs ou entre em contato com o suporte.

Perguntas Frequentes (FAQ)

❓ Como recuperar meu token se perdi?

Você não pode "recuperar" o token antigo. Tokens JWT são gerados dinamicamente e não são armazenados. Se perdeu, basta fazer login novamente para obter um novo token válido:

POST /api/auth/login

❓ O que acontece quando meu access_token expira?

O access_token expira após 1 hora. Você tem 2 opções:

  • Opção 1: Usar refresh_token em POST /api/auth/refresh
  • Opção 2: Fazer login novamente

❓ Posso ver os tokens salvos?

Os tokens são gerenciados de forma segura e criptografada pelo sistema de autenticação. Eles ficam armazenados de forma privada e você não precisa se preocupar com isso - o sistema gerencia tudo automaticamente para garantir sua segurança!

❓ Como funciona o sistema de créditos?

  • Cadastro = 10 créditos grátis
  • Calcular impostos = 1 crédito
  • Validar XML = 1 crédito
  • Converter XML = 2 créditos
  • Sem créditos = erro 402
  • Consultar saldo = GET /api/auth/credits
  • Todas respostas incluem meta.creditsRemaining

❓ As alíquotas estão sempre atualizadas?

Sim! Todas as alíquotas (ICMS, PIS, COFINS, IBS, CBS) são mantidas atualizadas automaticamente pelo sistema, garantindo cálculos sempre precisos conforme a legislação vigente.

❓ O que acontece se acabarem meus créditos?

Você receberá um erro 402 Payment Required ao tentar calcular:

{
  "success": false,
  "error": "Créditos insuficientes",
  "code": "INSUFFICIENT_CREDITS",
  "details": {
    "required": 1,
    "available": 0,
    "shortfall": 1
  }
}

Solução: No futuro haverá sistema de pagamento para comprar mais créditos. Por enquanto, crie um novo usuário de teste.

❓ Posso usar a API sem autenticação?

Alguns endpoints são públicos (não requerem autenticação):

  • GET /api/cronograma - Cronograma da reforma
  • GET /api/cronograma/:ano - Cronograma por ano
  • GET /api-docs - Documentação Swagger

Mas para calcular impostos ou converter XMLs, você PRECISA estar autenticado e ter créditos.

Collection do Postman

📦 Download da Collection Completa

Collection com todos os endpoints, exemplos prontos e scripts de teste automáticos!

Postman Download Collection Postman

Como Usar

1
Baixar Collection

Clique no botão acima para baixar o arquivo JSON

2
Importar no Postman

Abra o Postman → Import → Upload Files → Selecione o arquivo baixado

3
Executar "Registrar Usuário"

O script automático salva o token na variável {{token}}

4
Testar outros endpoints

Todos os endpoints já estão configurados para usar o token automaticamente!

✅ Recursos da Collection:

  • ✅ Todos os endpoints documentados
  • ✅ Variáveis automáticas ({{token}}, {{baseUrl}})
  • ✅ Scripts de teste que salvam tokens automaticamente
  • ✅ Exemplos práticos de uso
  • ✅ Organizada por categorias
  • ✅ Autenticação Bearer configurada

💡 Dica: Após importar, vá em "Variables" da collection e configure o baseUrl se sua API estiver rodando em outra porta ou domínio.