Skip to content

Latest commit

 

History

History
680 lines (579 loc) · 13.5 KB

File metadata and controls

680 lines (579 loc) · 13.5 KB

📚 Documentação da API

Esta documentação detalha todas as rotas da API REST do Módulo de Homologação SEFAZ.

⚠️ IMPORTANTE

Este projeto é um EXEMPLO de implementação, não um sistema pronto para produção.

  • ✅ Use para aprendizado e desenvolvimento
  • NÃO use diretamente em produção sem adaptações significativas
  • 📖 Leia o DISCLAIMER completo para detalhes sobre limitações

📑 Índice

Visão Geral

Base URL: http://localhost:3000/api

Formato: Todas as requisições e respostas usam JSON.

Padrão de Resposta:

{
  "ok": true/false,
  "message": "Mensagem descritiva (em caso de erro)",
  "data": { ... }
}

Autenticação

A autenticação é feita via certificado digital A1 (.pfx) enviado no corpo da requisição, não por headers. Cada requisição que requer certificado deve incluir:

{
  "config": {
    "tpAmb": 2,
    "cUF": "35",
    "pfx": "base64_do_certificado",
    "pfxPassword": "senha_do_certificado"
  }
}

⚠️ Segurança: Em produção, use HTTPS para proteger certificados em trânsito.

Rotas de Sistema

GET /api/health

Verifica o status da aplicação.

Parâmetros: Nenhum

Resposta:

{
  "ok": true,
  "service": "sandbox-ui-next",
  "ambiente": "selecionavel",
  "timestamp": "2026-03-03T10:30:00-03:00"
}

GET /api/config

Retorna a configuração atual do sistema.

Parâmetros: Nenhum

Resposta:

{
  "ok": true,
  "enforceHomologacao": true,
  "fiscalEngine": {
    "enabled": true,
    "tenantId": "local",
    "environment": "embedded",
    "provider": "local"
  }
}

Rotas NF-e

Todas as rotas NF-e requerem o objeto config com certificado digital.

POST /api/status

Consulta o status do serviço SEFAZ.

Payload:

{
  "config": {
    "tpAmb": 2,
    "cUF": "35",
    "pfx": "base64...",
    "pfxPassword": "senha"
  }
}

Resposta de Sucesso:

{
  "ok": true,
  "operacao": "NFE_ConsultaStatusServico",
  "retorno": {
    "cStat": "107",
    "xMotivo": "Serviço em Operação",
    "cUF": "35",
    "tpAmb": "2",
    "dhRecbto": "2026-03-03T10:30:00-03:00"
  }
}

POST /api/protocolo

Consulta o protocolo de uma NF-e autorizada.

Payload:

{
  "config": {
    "tpAmb": 2,
    "cUF": "35",
    "pfx": "base64...",
    "pfxPassword": "senha"
  },
  "chave": "35260312345678000100550010000000011234567890"
}

Parâmetros:

  • chave (string, obrigatório): Chave de acesso de 44 dígitos

Resposta de Sucesso:

{
  "ok": true,
  "operacao": "NFE_ConsultaProtocolo",
  "retorno": {
    "cStat": "100",
    "xMotivo": "Autorizado o uso da NF-e",
    "chNFe": "35260312345678000100550010000000011234567890",
    "dhRecbto": "2026-03-03T10:30:00-03:00",
    "nProt": "135260000123456",
    "xml": "<?xml version=\"1.0\"?>..."
  }
}

POST /api/autorizacao

Autoriza a emissão de uma NF-e.

Payload Básico:

{
  "config": {
    "tpAmb": 2,
    "cUF": "35",
    "pfx": "base64...",
    "pfxPassword": "senha"
  },
  "emissao": {
    "notaTipo": "saida",
    "serie": "1",
    "numero": "1",
    "dhEmi": "2026-03-03T10:30:00-03:00",
    "natOp": "Venda de mercadoria",
    
    "emit_CNPJ": "12345678000100",
    "emit_xNome": "EMPRESA EMISSORA LTDA",
    "emit_xFant": "EMPRESA EMISSORA",
    "emit_IE": "123456789",
    "emit_CRT": "3",
    "emit_xLgr": "RUA EXEMPLO",
    "emit_nro": "123",
    "emit_xBairro": "CENTRO",
    "emit_cMun": "3550308",
    "emit_xMun": "SAO PAULO",
    "emit_UF": "SP",
    "emit_CEP": "01000000",
    
    "dest_CNPJ": "98765432000100",
    "dest_xNome": "CLIENTE EXEMPLO LTDA",
    "dest_indIEDest": "1",
    "dest_IE": "987654321",
    "dest_xLgr": "AV PAULISTA",
    "dest_nro": "1000",
    "dest_xBairro": "BELA VISTA",
    "dest_cMun": "3550308",
    "dest_xMun": "SAO PAULO",
    "dest_UF": "SP",
    "dest_CEP": "01310100",
    
    "prod_cProd": "001",
    "prod_xProd": "PRODUTO EXEMPLO",
    "prod_NCM": "12345678",
    "prod_CFOP": "5102",
    "prod_uCom": "UN",
    "prod_qCom": "1.00",
    "prod_vUnCom": "100.00",
    
    "imposto_orig": "0",
    "imposto_CST": "00",
    "imposto_pICMS": "18.00",
    "imposto_vBC": "100.00",
    "imposto_vICMS": "18.00"
  }
}

Resposta de Sucesso:

{
  "ok": true,
  "operacao": "NFE_Autorizacao",
  "retorno": {
    "cStat": "100",
    "xMotivo": "Autorizado o uso da NF-e",
    "chNFe": "35260312345678000100550010000000011234567890",
    "nProt": "135260000123456",
    "dhRecbto": "2026-03-03T10:30:00-03:00",
    "xml": "<?xml version=\"1.0\"?>...",
    "danfePDF": "base64..."
  }
}

POST /api/cancelamento

Cancela uma NF-e autorizada.

Payload:

{
  "config": {
    "tpAmb": 2,
    "cUF": "35",
    "pfx": "base64...",
    "pfxPassword": "senha"
  },
  "cancelamento": {
    "chave": "35260312345678000100550010000000011234567890",
    "protocolo": "135260000123456",
    "justificativa": "Cancelamento solicitado pelo cliente devido a erro no pedido"
  }
}

Parâmetros:

  • chave (string, obrigatório): Chave de 44 dígitos
  • protocolo (string, obrigatório): Número do protocolo de autorização
  • justificativa (string, obrigatório): Entre 15 e 255 caracteres

Resposta de Sucesso:

{
  "ok": true,
  "operacao": "NFE_Cancelamento",
  "retorno": {
    "cStat": "135",
    "xMotivo": "Evento registrado e vinculado a NF-e",
    "chNFe": "35260312345678000100550010000000011234567890",
    "nProt": "135260000123457",
    "dhRecbto": "2026-03-03T11:00:00-03:00"
  }
}

POST /api/carta-correcao

Emite uma Carta de Correção Eletrônica (CC-e).

Payload:

{
  "config": {
    "tpAmb": 2,
    "cUF": "35",
    "pfx": "base64...",
    "pfxPassword": "senha"
  },
  "cartaCorrecao": {
    "chave": "35260312345678000100550010000000011234567890",
    "sequencia": 1,
    "correcao": "Correcao do endereco do destinatario: numero correto e 1001"
  }
}

Parâmetros:

  • chave (string, obrigatório): Chave de 44 dígitos
  • sequencia (number, obrigatório): Sequência da CC-e (1 para primeira)
  • correcao (string, obrigatório): Entre 15 e 1000 caracteres

Resposta de Sucesso:

{
  "ok": true,
  "operacao": "NFE_CartaDeCorrecao",
  "retorno": {
    "cStat": "135",
    "xMotivo": "Evento registrado e vinculado a NF-e",
    "chNFe": "35260312345678000100550010000000011234567890",
    "nProt": "135260000123458"
  }
}

POST /api/inutilizacao

Inutiliza uma faixa de numeração de NF-e.

Payload:

{
  "config": {
    "tpAmb": 2,
    "cUF": "35",
    "pfx": "base64...",
    "pfxPassword": "senha"
  },
  "inutilizacao": {
    "ano": "26",
    "serie": "1",
    "numeroInicial": "10",
    "numeroFinal": "15",
    "justificativa": "Numeracao pulada por erro no sistema de gestao interno"
  }
}

Parâmetros:

  • ano (string, obrigatório): 2 dígitos (ex: "26" para 2026)
  • serie (string, obrigatório): Série da NF-e
  • numeroInicial (string, obrigatório): Primeiro número da faixa
  • numeroFinal (string, obrigatório): Último número da faixa
  • justificativa (string, obrigatório): Entre 15 e 255 caracteres

Resposta de Sucesso:

{
  "ok": true,
  "operacao": "NFE_Inutilizacao",
  "retorno": {
    "cStat": "102",
    "xMotivo": "Inutilizacao de numero homologado",
    "ano": "26",
    "serie": "1",
    "nNFIni": "10",
    "nNFFin": "15"
  }
}

Rotas de Catálogos

GET /api/ncm

Busca códigos NCM (Nomenclatura Comum do Mercosul).

Parâmetros de Query:

  • q (string, obrigatório): Query de busca (mínimo 2 caracteres)
  • limit (number, opcional): Limite de resultados (1-50, padrão: 10)

Exemplo:

GET /api/ncm?q=cafe&limit=5

Resposta:

{
  "ok": true,
  "query": "cafe",
  "total": 15,
  "dataAtualizacao": "2025-01-01",
  "ato": "Resolução CAMEX 272/2021",
  "results": [
    {
      "ncm": "09011100",
      "descricao": "Café não torrado, não descafeinado",
      "score": 100
    },
    {
      "ncm": "09011200",
      "descricao": "Café não torrado, descafeinado",
      "score": 95
    }
  ]
}

GET /api/operacoes-tributarias

Lista todas as operações tributárias (CFOPs) disponíveis.

Parâmetros: Nenhum

Resposta:

{
  "ok": true,
  "total": 450,
  "operations": [
    {
      "cfop": "5102",
      "descricao": "Venda de mercadoria adquirida ou recebida de terceiros",
      "tipo": "saida",
      "scope": "interno",
      "suggestion": {
        "cst": "00",
        "pICMS": "18.00"
      }
    }
  ]
}

POST /api/operacoes-tributarias

Sugere operações tributárias baseadas no contexto.

Payload:

{
  "ufOrigem": "SP",
  "ufDestino": "RJ",
  "indIEDest": "1",
  "cfop": null,
  "crt": "3"
}

Resposta:

{
  "ok": true,
  "contexto": {
    "interestadual": true,
    "ufOrigem": "SP",
    "ufDestino": "RJ",
    "contribuinte": true
  },
  "sugestoes": [
    {
      "cfop": "6102",
      "descricao": "Venda de mercadoria adquirida ou recebida de terceiros",
      "score": 100,
      "motivos": ["Operação interestadual", "Destinatário contribuinte"],
      "suggestion": {
        "cst": "00",
        "pICMS": "12.00"
      }
    }
  ]
}

GET /api/fiscal/operation-codes

Lista códigos de operação fiscal disponíveis.

Parâmetros de Query:

  • q (string, opcional): Filtro de busca
  • limit (number, opcional): Limite de resultados (1-50, padrão: 10)

Exemplo:

GET /api/fiscal/operation-codes?q=venda&limit=10

Resposta:

{
  "ok": true,
  "total": 25,
  "codes": [
    {
      "code": "121",
      "description": "Venda Interna - Contribuinte (CFOP 5102)",
      "cfop": "5102"
    }
  ]
}

Motor Fiscal

POST /api/fiscal/calculate

Calcula impostos automaticamente usando o motor fiscal local.

Payload:

{
  "emissao": {
    "emit_CRT": "3",
    "emit_UF": "SP",
    "dest_UF": "RJ",
    "dest_indIEDest": "1",
    "prod_vUnCom": "100.00",
    "prod_qCom": "10.00"
  },
  "config": {
    "tpAmb": 2
  }
}

Parâmetros Avançados:

{
  "taxRegime": "NORMAL",
  "operationType": "Outgoing",
  "ufOrigin": "SP",
  "ufDestination": "RJ",
  "recipientContributor": "Contributor",
  "unitPrice": "100.00",
  "quantity": "10.00",
  "ncm": "12345678",
  "operationCode": "221"
}

Resposta:

{
  "ok": true,
  "operacao": "FISCAL_CalculoImpostos",
  "provider": "local",
  "tenantId": "local",
  "environment": "embedded",
  "request": {
    "taxRegime": "NORMAL",
    "operationType": "Outgoing",
    "ufOrigin": "SP",
    "ufDestination": "RJ"
  },
  "result": {
    "productAmount": "1000.00",
    "taxBase": "1000.00",
    "icmsRate": "12.00",
    "icmsAmount": "120.00",
    "cfop": "6102",
    "cst": "00",
    "assumptions": [
      "Alíquota ICMS interestadual SP->RJ: 12%",
      "CFOP sugerido: 6102 (venda interestadual)"
    ]
  },
  "summary": {
    "cfop": "6102",
    "cst": "00",
    "pICMS": "12.00",
    "vBC": "1000.00",
    "vICMS": "120.00"
  }
}

Códigos de Erro

Códigos HTTP

Código Descrição
200 Sucesso
400 Erro de validação ou requisição inválida
500 Erro interno do servidor

Códigos SEFAZ Comuns

cStat Significado
100 Autorizado o uso da NF-e
102 Inutilização de número homologado
107 Serviço em Operação
135 Evento registrado e vinculado à NF-e
217 NF-e já está cancelada na base de dados da SEFAZ
301 Uso Denegado: Irregularidade fiscal do emitente
302 Uso Denegado: Irregularidade fiscal do destinatário
539 Duplicidade de NF-e

Exemplos de Uso

JavaScript/TypeScript

// Consultar status SEFAZ
const response = await fetch('http://localhost:3000/api/status', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    config: {
      tpAmb: 2,
      cUF: '35',
      pfx: certificadoBase64,
      pfxPassword: 'senha123'
    }
  })
});

const result = await response.json();
if (result.ok) {
  console.log('SEFAZ Status:', result.retorno.xMotivo);
}

cURL

# Consultar protocolo
curl -X POST http://localhost:3000/api/protocolo \
  -H "Content-Type: application/json" \
  -d '{
    "config": {
      "tpAmb": 2,
      "cUF": "35",
      "pfx": "base64...",
      "pfxPassword": "senha"
    },
    "chave": "35260312345678000100550010000000011234567890"
  }'

Python

import requests
import base64

# Ler certificado
with open('certificado.pfx', 'rb') as f:
    pfx_base64 = base64.b64encode(f.read()).decode()

# Autorizar NF-e
response = requests.post(
    'http://localhost:3000/api/autorizacao',
    json={
        'config': {
            'tpAmb': 2,
            'cUF': '35',
            'pfx': pfx_base64,
            'pfxPassword': 'senha123'
        },
        'emissao': {
            # ... dados da emissão
        }
    }
)

result = response.json()
if result['ok']:
    print(f"NF-e autorizada: {result['retorno']['chNFe']}")

Para mais informações, consulte: