Como Funciona o Monitoramento SEFAZ
Este documento explica detalhadamente como o sistema Monitor SEFAZ verifica a saúde dos provedores SEFAZ em todos os estados brasileiros.
📋 Visão Geral
O Monitor SEFAZ utiliza o serviço oficial de StatusServico fornecido pela SEFAZ para verificar a disponibilidade e tempo de resposta dos serviços fiscais eletrônicos (NFe, NFCe, CTe, DCe).
🔄 Ciclo de Monitoramento
Frequência
O sistema executa ciclos de monitoramento a cada 30 segundos, processando todas as UFs e serviços configurados.
Fluxo do Ciclo
┌─────────────────────────────────────────┐
│ MonitorWorker (Background Service) │
│ Ciclo a cada 30 segundos │
└─────────────────┬───────────────────────┘
│
┌─────────▼─────────┐
│ Warmup Certificado│
│ (Inicialização) │
└─────────┬─────────┘
│
┌─────────▼─────────────────────────┐
│ Filtrar UFs Habilitadas │
│ (NFe, NFCe, CTe, DCe) │
└─────────┬─────────────────────────┘
│
┌─────────▼─────────────────────────┐
│ Separar DCe das Outras Consultas │
└─────────┬─────────────────────────┘
│
┌───────────┴───────────┐
│ │
┌─────▼─────┐ ┌──────▼──────┐
│ Processar│ │ Processar │
│ DCe │ │ NFe/NFCe/ │
│ (Único) │ │ CTe │
│ │ │ (Paralelo) │
└───────────┘ └─────────────┘
🔍 Processo de Verificação de Saúde
1. Requisição SOAP ao StatusServico
Para cada UF e serviço, o sistema envia uma requisição SOAP (Web Service) ao endpoint oficial da SEFAZ.
Estrutura da Requisição SOAP
Endpoint: URL específica por UF e tipo de serviço (ex: https://nfe.sefaz.es.gov.br/ws/NFeStatusServico4/NFeStatusServico4.asmx)
Método: POST
Content-Type: - application/soap+xml; charset=utf-8 (SOAP 1.2 - Padrão) - text/xml; charset=utf-8 (SOAP 1.1 - Fallback)
Headers:
Content-Type: application/soap+xml; charset=utf-8; action="http://www.portalfiscal.inf.br/nfe/wsdl/NFeStatusServico4/nfeStatusServicoNF"
SOAPAction: "http://www.portalfiscal.inf.br/nfe/wsdl/NFeStatusServico4/nfeStatusServicoNF"
Envelope SOAP (Exemplo NFe):
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<nfeDadosMsg xmlns="http://www.portalfiscal.inf.br/nfe/wsdl/NFeStatusServico4">
<consStatServ versao="4.00" xmlns="http://www.portalfiscal.inf.br/nfe">
<tpAmb>1</tpAmb> <!-- 1=Produção, 2=Homologação -->
<cUF>32</cUF> <!-- Código da UF (32=ES) -->
<xServ>STATUS</xServ> <!-- Serviço: STATUS -->
</consStatServ>
</nfeDadosMsg>
</soap12:Body>
</soap12:Envelope>
Parâmetros da Requisição
- tpAmb: Ambiente (1=Produção, 2=Homologação)
- cUF: Código numérico da UF (ex: 32=ES, 35=SP, 31=MG)
- xServ: Sempre "STATUS" para consulta de status
- versao: Versão do layout (4.00 para NFe, NFCe, CTe)
Certificado Digital
Todas as requisições utilizam certificado digital A1 ou A3 para autenticação SSL/TLS:
var certificado = await certificateService.GetCertificateAsync();
// Certificado é usado para autenticação SSL na requisição HTTPS
2. Resposta SOAP da SEFAZ
A SEFAZ responde com um envelope SOAP contendo o status do serviço:
Exemplo de Resposta (Serviço Operacional):
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Body>
<nfeResultMsg xmlns="http://www.portalfiscal.inf.br/nfe/wsdl/NFeStatusServico4">
<retConsStatServ versao="4.00" xmlns="http://www.portalfiscal.inf.br/nfe">
<tpAmb>1</tpAmb>
<verAplic>SP_NFE_PL_009h</verAplic>
<cStat>107</cStat>
<xMotivo>Serviço em Operação</xMotivo>
<cUF>35</cUF>
<dhRecbto>2025-12-26T10:00:00-03:00</dhRecbto>
<tMed>1000</tMed>
</retConsStatServ>
</nfeResultMsg>
</soap:Body>
</soap:Envelope>
Campos Importantes da Resposta
| Campo | Descrição | Exemplo |
|---|---|---|
| cStat | Código de Status | 107 = Serviço em Operação |
| xMotivo | Motivo/Descrição | Serviço em Operação |
| tMed | Tempo Médio de Resposta (ms) | 1000 = 1 segundo |
| dhRecbto | Data/Hora de Recebimento | 2025-12-26T10:00:00-03:00 |
| verAplic | Versão da Aplicação | SP_NFE_PL_009h |
3. Códigos de Status (cStat)
O campo cStat indica o status operacional do serviço:
| Código | Significado | Status do Monitor |
|---|---|---|
| 107 | Serviço em Operação | ✅ Operacional |
| 108 | Serviço Paralisado Momentaneamente | ⚠️ Degradado |
| 109 | Serviço Paralisado sem Previsão | ❌ Indisponível |
| 110 | Serviço Paralisado em Curto Prazo | ❌ Indisponível |
| 111 | Serviço Paralisado em Médio Prazo | ❌ Indisponível |
| 112 | Serviço Paralisado em Longo Prazo | ❌ Indisponível |
| 113 | Serviço em Contingência | ⚠️ Contingência |
| 114 | SVC Desabilitado | ❌ Indisponível |
| 999 | Erro/Timeout/Exceção | ❌ Indisponível |
4. Medição de Latência
O sistema mede o tempo de resposta completo:
var stopwatch = Stopwatch.StartNew();
var resultado = await soapService.ConsultarStatusAsync(url, certificado, ambiente, codigoUf, ct);
stopwatch.Stop();
var latencyMs = stopwatch.ElapsedMilliseconds; // Tempo total em milissegundos
Classificação de Latência:
- Normal: ≤ 2 segundos
- Lento: 2 a 5 segundos
- Muito Lento: 5 a 30 segundos
- Timeout: ≥ 30 segundos ou sem resposta
5. Sistema de Contingência (SVC)
Quando o servidor principal retorna erro ou aviso de contingência, o sistema automaticamente tenta o Servidor de Contingência (SVC):
// Condições para tentar SVC:
bool deveTentarSvc =
(falhaConexao || avisoContingencia) // cStat = "999" ou "113"
&& !IsSvcDisabled(resultado) // SVC não está desabilitado (cStat != "114")
&& _options.TentarContingencia // Configuração permite
&& helper.UsaServidorContingencia(uf); // UF suporta SVC
if (deveTentarSvc) {
// Tenta servidor de contingência
var resultadoSvc = await soapService.ConsultarStatusAsync(urlSvc, ...);
}
Fluxo de Contingência:
1. Consulta Servidor Principal
↓
2. Verifica cStat:
- "999" (erro/timeout) → Tenta SVC
- "113" (contingência) → Tenta SVC
- "107" (operacional) → Retorna resultado
↓
3. Se necessário, consulta Servidor de Contingência (SVC)
↓
4. Retorna melhor resultado disponível
🔧 Implementação Técnica
Arquitetura do Monitoramento
MonitorWorker (Background Service)
↓
CheckStatusWithRetryAsync (para cada UF)
↓
1. Verificar Cache (evita consultas desnecessárias)
↓
2. Consultar Status SEFAZ
├── SefazStatusService.ConsultarStatusAsync()
│ ├── Determina tipo de serviço (NFe, NFCe, CTe, DCe)
│ ├── Obtém URL do endpoint
│ └── Executa consulta com contingência
│ ├── ExecutarConsultaComContingenciaAsync()
│ │ ├── Consulta servidor principal
│ │ └── Tenta SVC se necessário
│ └── Retorna SefazStatusResult
↓
3. Medir Latência (Stopwatch)
↓
4. Mapear Resultado (SefazResultMapper)
↓
5. Persistir no Redis (MonitorSefazUseCase)
└── RedisStatusService.InsertResultAsync()
Código Principal
MonitorWorker.cs:
private async Task CheckStatusWithRetryAsync(UfConfig config, CancellationToken token)
{
// 1. Verificar cache (evita chamadas desnecessárias)
if (await redis.HasRecentUpdateAsync(config.UF, serviceName))
return;
// 2. Executar consulta à SEFAZ
var stopwatch = Stopwatch.StartNew();
var sefazResult = await sefazStatusService.ConsultarStatusAsync(
config.UF,
ServiceTypeMapper.ToSefazServiceType(config.ServiceType),
token);
stopwatch.Stop();
// 3. Mapear e persistir resultado
var result = SefazResultMapper.ToMonitorResult(
sefazResult,
config.UF,
serviceName,
stopwatch.ElapsedMilliseconds);
await monitorUseCase.ExecuteAsync(result);
}
NfeStatusServicoSoapService.cs:
public async Task<SefazStatusResult> ConsultarStatusAsync(...)
{
// 1. Criar envelope SOAP
var envelope = CriarSoapEnvelope(ambiente, codigoUf, isSoap12);
// 2. Enviar requisição HTTP POST
using var request = new HttpRequestMessage(HttpMethod.Post, url);
request.Content = new StringContent(envelope, Encoding.UTF8, "application/soap+xml");
// 3. Executar requisição com certificado
using var response = await httpClient.SendAsync(request, ct);
var responseXml = await response.Content.ReadAsStringAsync(ct);
// 4. Parsear resposta XML
return ParsearRespostaSoap(responseXml);
}
⚡ Otimizações
1. Cache Inteligente
O sistema verifica se já existe uma atualização recente (30 segundos) antes de consultar a SEFAZ:
if (await redis.HasRecentUpdateAsync(config.UF, serviceName))
return; // Pula consulta desnecessária
2. Paralelismo Controlado
Máximo de 5 consultas simultâneas para evitar sobrecarga:
await Parallel.ForEachAsync(otherConfigs, new ParallelOptions
{
MaxDegreeOfParallelism = 5, // Limite de concorrência
CancellationToken = stoppingToken
}, async (config, token) =>
{
await CheckStatusWithRetryAsync(config, token);
});
3. Otimização DCe
DCe usa o mesmo servidor (Paraná) para todos os estados, então fazemos apenas 1 consulta e replicamos o resultado:
// Consulta única para todos os estados
var sefazResult = await sefazStatusService.ConsultarStatusAsync(
firstConfig.UF, // Qualquer UF serve
ServiceType.DCe,
token);
// Replica resultado para todos os estados
await Task.WhenAll(dceConfigs.Select(config =>
monitorUseCase.ExecuteAsync(mappedResult)));
4. Fallback SOAP 1.1/1.2
Se a requisição SOAP 1.2 falhar, o sistema automaticamente tenta SOAP 1.1:
// Tenta SOAP 1.2 primeiro (padrão NF-e 4.0)
var resultado = await ExecutarRequestAsync(url, ambiente, codigoUf, httpClient, true, ct);
// Se falhar por incompatibilidade, tenta SOAP 1.1
if (resultado.CStat == "999" && resultado.XMotivo?.Contains("VersionMismatch"))
resultado = await ExecutarRequestAsync(url, ambiente, codigoUf, httpClient, false, ct);
📊 Dados Coletados
Para cada verificação, o sistema armazena:
MonitorResult {
UF: "SP", // Unidade Federativa
Service: "NFeStatusServico", // Tipo de serviço
Status: "Operacional", // Status legível
CStat: "107", // Código de status SEFAZ
XMotivo: "Serviço em Operação", // Motivo
LatencyMs: 1234, // Latência em milissegundos
Success: true, // Sucesso na consulta
Timestamp: DateTime.UtcNow, // Quando foi consultado
ContingencyInfo: {...} // Info de contingência (se aplicável)
}
🚨 Tratamento de Erros
Erros de Conexão
- Timeout: Requisição excede 30 segundos → cStat = "999"
- DNS: Endpoint não encontrado → cStat = "999"
- SSL/TLS: Erro de certificado → cStat = "999"
Erros de Resposta
- SOAP Fault: Resposta contém erro SOAP → cStat = "999"
- XML Inválido: Resposta não é XML válido → cStat = "999"
- Elemento Ausente: Campo obrigatório não encontrado → cStat = "999"
Erros de Certificado
- Certificado Não Configurado: → cStat = "999", XMotivo = "Certificado digital não configurado"
- Certificado Expirado: → Erro SSL/TLS → cStat = "999"
🔐 Segurança
Autenticação
- Certificado Digital A1/A3: Autenticação SSL/TLS obrigatória
- HTTPS: Todas as requisições são feitas via HTTPS
- Validação de Certificado: Validação automática do certificado SSL da SEFAZ
Validação
- Validação de UF: Verifica se a UF é válida antes de consultar
- Validação de Resposta: Parse e validação do XML de resposta
- Sanitização: Tratamento seguro de dados recebidos
📈 Métricas e Analytics
O sistema coleta métricas para análise:
- Latência (P50, P95, P99): Percentis de tempo de resposta
- Taxa de Sucesso: Percentual de consultas bem-sucedidas
- Histórico: Dados das últimas 24 horas armazenados no Redis
- Tendências: Análise de padrões de disponibilidade
🔄 Frequência de Atualização
- Ciclo Base: A cada 30 segundos
- Cache: 30 segundos (proteção contra consultas simultâneas)
- Retenção: Histórico de 24 horas mantido no Redis
- Latest TTL: Cache do status mais recente por 2 horas
Última Atualização: 26 de Dezembro de 2025
Documentação Relacionada: - Arquitetura.md - Tecnologico.md