Pular para conteúdo

Compatibilidade — SmartNFCe

O que o adaptador aceita, o que ele recusa e onde ele diverge do motor local. Onde não há linha nesta página, o comportamento é o do motor. A documentação dele continua valendo, e é essa a ideia.

Três veredictos aparecem nas tabelas:

Veredicto Significa
Compatível Mesma forma de fio, mesmo comportamento
Ressalva Funciona, com uma diferença que pode afetar o seu código
Fora Não implementado nesta versão

Cada linha compara dois lados de origens diferentes. O nosso lado roda aqui, e você pode conferi-lo contra este adaptador. O lado do motor vem de captura, e onde não houve captura esta página diz qual é o caso. Ver Formas sem captura.

Adaptador em desenvolvimento

As linhas desta página já são contrato. O adaptador ainda não foi lançado, então algo pode mudar até lá. Se mudar, muda aqui primeiro.

Autenticação

Recurso Veredicto Observação
Nenhuma autenticação Ressalva O motor roda em localhost e não autentica. Na nuvem isso não é possível: exigimos o token OAuth2 de dispositivo que o equipamento já tem
Token de dispositivo já em campo Compatível Sem escopo novo, sem provisionamento, sem janela de migração
Empresa informada no corpo Ressalva Desnecessário: o vínculo vem do token
401 HTTP em vez de erro em banda Ressalva Exceção declarada à regra do 200. A autenticação é acréscimo nosso, e não faz parte do contrato do motor
Recusa genérica, sem dizer o que falhou Ressalva Deliberado: uma negativa de autenticação nunca revela qual verificação falhou
pos_agent emitindo Fora fiscal_box e smart_nfce alcançam os verbos fiscais. Um pos_agent recebe o mesmo 401 genérico de qualquer outra falha
Token sem o tipo de dispositivo Ressalva Recusado por segurança em vez de liberado. Nenhum escopo mudou. O dispositivo só precisa renovar o token uma vez
Emissor que custodia por várias empresas Ressalva Um fiscal_box ou smart_nfce custodia documentos de várias empresas, mas emite apenas pela empresa à qual está atribuído

As duas linhas acima falam de dispositivos diferentes. Custódia flexível não concede emissão: quem decide é o tipo do dispositivo. Se o seu equipamento custodia por várias empresas e não é fiscal_box nem smart_nfce, o caso dele é a primeira linha.

Emissão

Recurso Veredicto Observação
POST /api/v1/nfce/xml/{uuid} com XML no corpo Compatível
uuid escolhido pelo cliente Compatível É a chave de idempotência. Reenviar não gera segundo documento
tpEmis decidido pelo cliente Compatível Não decidimos contingência por você. É uma divergência deliberada em relação aos outros dialetos
Corpo "gordo" na autorização Compatível Os ~29 campos de identificação e telemetria, todos string. A telemetria tem uma ressalva na linha Tempo médio SEFAZ(ms)
Tempo médio SEFAZ(ms) Ressalva Repete o valor de Tempo comando(ms). Mede o comando inteiro, que inclui numeração, assinatura e gravação. Leia como teto, não como latência da SEFAZ
Corpo mínimo na rejeição Compatível cStat, xMotivo e diagnostico. É a forma do motor
cStat como string na emissão Compatível Reproduzido. Em outras rotas ele é int
Erros de digitação nProto, dhRecibo, certificareExpiryCountdown Compatível Reproduzidos verbatim, de propósito
Sentinela -100 para contingência Compatível
Corpo malformado responde 200 em banda Compatível Nunca um 422
Campos desconhecidos no corpo Compatível Tolerados e ignorados, como no motor
Agent version e agente Ressalva Carregam a nossa identidade, não a do produto original. Um cliente que valida essa string precisa ajustar
versao_base da pré-validação Ressalva Reporta o nosso conjunto de regras, não a base do motor
Autocorreção de NCM Fora Adiada. O documento é recusado em vez de corrigido
Sinalização de CEST Fora Adiada

Consulta

Recurso Veredicto Observação
GET /api/v1/nfce/authorization/status/{uuid} Compatível
GET /api/v1/nfce/{nNFouChave} por número ou chave Compatível
Sentinela -5 para uuid desconhecido Compatível O sentinela é o mesmo nos dois casos, mas o texto não é: uuid not found e em processamento, consulte novamente significam coisas opostas para quem decide reenviar. Ver a divergência deliberada
retConsSitNFe como JSON dentro de string Compatível Nunca objeto aninhado
verAplic em GET /api/v1/nfce/status_sefaz Ressalva Hoje responde vazio. Ver o que fazer com o campo vazio

verAplic responde vazio

O valor não chega ao adaptador, e preenchê-lo é trabalho ainda não feito.

De qualquer forma, não decida nada pela versão da aplicação da SEFAZ. O conselho vale com o campo vazio e continua valendo quando ele estiver preenchido.

Cancelamento

Recurso Veredicto Observação
POST /api/v1/nfce/cancelar por número ou chave Compatível
POST /api/v1/nfce/{chNFe}/cancel Compatível justificativa obrigatória aqui, de 15 a 255 caracteres
Justificativa genérica quando omitida Compatível Reproduzido: Cancelamento a pedido do emitente da nota
Campo protocolo no corpo Ressalva Aceito para compatibilidade de fio, mas nunca necessário, porque nós já temos o protocolo dos nossos documentos
Cancelamento por substituição Compatível
tpAutor no cancelamento por substituição Compatível Aceita número e texto. As duas formas aparecem na documentação de origem, e o valor não altera o evento
infEvento como JSON dentro de string Compatível

Inutilização

Recurso Veredicto Observação
POST /api/v1/nfce/discard de uma faixa Compatível
GET /api/v1/nfce/inutilizacoes Compatível
cStat como string na resposta Compatível
cnpj, uf e tpAmb opcionais Ressalva O motor exige os três. Aqui são opcionais, e quem responde por eles é o seu token. Ver quem garante esses valores
Domínio de tpAmb Compatível Quando enviado, só aceita 1 (produção) ou 2 (homologação). É o domínio que o motor publica. Qualquer outro valor é recusado na entrada, em vez de seguir para a SEFAZ
ano obrigatório Compatível O motor também o exige
Formato de ano Compatível Dois dígitos: 26, não 2026. É o tipo Tano do leiaute da NF-e, não uma restrição nossa. O ACBrAPI aceita as duas formas. Aqui 2026 é 422

Quem garante cnpj, uf e tpAmb

O motor exige os três no corpo do pedido. Aqui eles são opcionais, e essa relaxação é nossa.

Quem passa a responder por eles é o seu token. A empresa autenticada define o CNPJ, a UF e o ambiente que vão para a SEFAZ. O corpo não é a origem desses valores em nenhum dos casos, e omitir os campos não deixa nada em aberto.

Opcional não quer dizer não conferido. Enviados, os três continuam sendo checados contra a empresa autenticada, e um valor divergente é recusado.

DANFE

Recurso Veredicto Observação
POST /api/v1/nfce/danfepdf por número ou chave Compatível
DANFE em base64 no corpo de emissão Compatível Inclusive na contingência, para o PDV conseguir imprimir
Paridade de bytes com o DANFE do motor Fora O PDF é gerado pelo nosso renderizador. O conteúdo fiscal é o mesmo e o documento é válido, mas os bytes não. Quem compara PDFs precisa parar
Configuração local de DANFE Fora Faz sentido só numa máquina local

Contingência

Recurso Veredicto Observação
GET /api/v1/nfce/contingencia/pendentes Compatível
GET /api/v1/nfce/contingencia/resultado/{nNF} Compatível Vocabulário em minúsculas. Ver os dois vocabulários
GET /api/v1/nfce/processamentocontigencia Compatível O erro de digitação está no caminho, e é reproduzido
Vocabulário capitalizado no relatório Compatível Nunca convertido no vocabulário minúsculo
Sentinela -404 para documento não relevante Compatível
Ligar e desligar contingência manualmente Compatível Interruptor de verdade: com ela ligada a emissão responde -100/tpEmis 9. O campo da resposta é status, sem acento
Durabilidade do interruptor Ressalva Não expira e só sai pelo disable correspondente. Não é um ajuste permanente: ver como saber em que modo você está
Desligar reprocessa a fila Fora Desligar só volta a emissão ao normal. Quem resolve a fila é o relatório de processamento
Contagens por ambiente Ressalva pendingContingencyInvoices e o relatório contam apenas o ambiente do endereço chamado. Não há visão consolidada

O interruptor não é um ajuste permanente

No motor local o estado da contingência fica em disco e sobrevive a um reinício. Aqui a garantia é outra. O interruptor não expira e só sai pelo disable correspondente, mas o estado não tem a mesma durabilidade. Se ele for perdido, a emissão volta a tpEmis 1 sem aviso.

A falha acontece na direção segura. O interruptor nunca fica ligado porém inerte. Perder o estado desliga a contingência de fato, e a emissão volta ao normal.

Nenhuma rota responde "a contingência está ligada?". Quem diz em que modo você está é o tpEmis de cada emissão. Leia o tpEmis da resposta em vez de confiar no último enable que você enviou.

Webhooks

Recurso Veredicto Observação
Configuração única por empresa e ambiente Compatível Garantida no banco. Não há como registrar duas vezes e receber em duplicidade
Gravação parcial Compatível Só o que você envia muda. A primeira chamada precisa trazer a url
secret somente escrita, lendo de volta *** Compatível Enviar *** de volta significa não mudar. O laço ler/editar/gravar é seguro
Configuração inexistente lê secret vazio Ressalva Diferente do *** de uma configuração existente. Serve para saber se já há segredo definido
Assinatura HMAC-SHA256 sobre os bytes entregues Compatível Cabeçalho X-Webhook-Signature: sha256=<hex>. Opcional: sem segredo, sem assinatura
retryMax e timeoutMs na configuração Ressalva Aceitos, gravados e ecoados de volta, mas não obedecidos. A entrega segue a nossa escada fixa (1min/30min/1h/3h/24h). Um retryMax de 10 não produz dez tentativas
Catálogo de eventos Compatível Sete eventos, todos ativos. Ver Os sete eventos
Tipo de nNF e cStat no corpo do webhook Ressalva int no webhook (dados) e string no corpo da emissão. Os mesmos nomes de campo, tipos diferentes conforme a superfície. As duas formas são as do motor
Uma emissão, duas entregas Ressalva Um documento com avisos de pré-validação entrega nota_autorizada/nota_rejeitada e prevalidacao, em POSTs separados. O handler precisa ser idempotente por evento, não por documento
contingencia_desativada sem pendentes Compatível Assimétrico em relação a contingencia_ativada, de propósito
timestamp do envelope Ressalva Hora local da UF da empresa, sem indicação de fuso. Não interprete como UTC

Formas sem captura

As formas desta tabela não vêm de nenhuma captura do motor. Nós as inferimos a partir do vocabulário dele. São exatamente os pontos em que o nosso contrato pode divergir do original sem que ninguém tenha como saber ainda. Se o seu PDV depende de alguma delas, confirme conosco antes.

Forma O que se sabe de fato
A resposta de POST /api/v1/nfce/cancelar A mais frágil das seis. Não há evidência direta nenhuma. Ver de onde veio esta forma
xMotivo do cStat 204 (Duplicidade de NF-e) O texto não aparece em lugar nenhum da documentação de origem. O corpo do 204 nunca foi observado
O corpo "gordo" da contingência Não há captura. A única forma de origem é um exemplo curto, com cStat e nNF como int. Só o texto do xMotivo é literal
As chaves de correcao_prevalidacao.aplicado[] Hoje a lista vem sempre vazia, então não afeta ninguém ainda. As chaves foram emprestadas de outro bloco e podem mudar quando ela começar a ser preenchida
A recusa de cancelamento e a recusa da pré-validação Cantos que a documentação de origem não cobre
Textos de recusa em português (Serviço indisponível, Cancelada por substituição e outros) Sem texto de origem

A resposta de cancelar é uma escolha nossa

O exemplo que existe na documentação de origem está atribuído a /{chNFe}/cancel, e não a POST /api/v1/nfce/cancelar. Separar as duas rotas é a leitura que respeita a captura, mas é uma escolha nossa.

Uma divergência que é deliberada

Esta não é um palpite. É uma diferença que escolhemos manter, e ela existe para proteger você:

Divergência Por quê
Um uuid em voo responde em processamento, consulte novamente, e não uuid not found Um PDV que lesse "não encontrado" reemitiria sob um uuid novo. Seriam dois documentos autorizados para uma venda só. Ver o que diverge e o que não

O sentinela continua fiel, só o texto diverge

Um PDV que lê "não encontrado" conclui que a emissão não aconteceu. Ele reemite sob um uuid novo, enquanto a primeira emissão ainda pode autorizar.

O sentinela -5 continua fiel, e só o texto diverge. Nunca trate as duas mensagens como o mesmo caso.

Rotas do motor que o adaptador não serve

Estas rotas existem no motor e esta versão não as implementa. A resposta não é a do motor.

Rota Veredicto Observação
GET e POST /api/v1/email/config Fora O motor envia o DANFE ao consumidor por SMTP configurado nele. O envio automático ainda não tem decisão nossa. Responde 404
GET /api/v1/nfce/laudo Fora Laudo de conformidade do cadastro. Não responde 404. Ver o que ele responde
GET e POST /api/v1/config/regras Fora Ajuste local da severidade da pré-validação. Aqui valem as nossas regras, e não há superfície para alterá-las. Responde 404
POST /api/v1/nfe/danfe_preview Fora Pré-visualização de NF-e modelo 55, que esta versão não emite. Responde 404
POST /api/v1/nfe/{chave44}/electronicCorrectionLetter Fora Carta de Correção Eletrônica, exclusiva do modelo 55. Responde 404
POST /api/v1/nfe/{chave44}/manifestacao Fora Manifestação do Destinatário, exclusiva do modelo 55. Responde 404

O laudo aponta para o Veraciti

A documentação do motor diz que o consolidado multi-PDV do laudo "é servido pela nuvem (Veraciti)". Ela nomeia o Veraciti como quem implementa essa rota, e esta versão não a serve.

GET /api/v1/nfce/laudo também não responde 404. O caminho tem um segmento só depois de /api/v1/nfce/, então ele cai na consulta por número ou chave e recebe esta resposta:

{ "ok": false, "error": "informe o número da nota ou a chave de 44 dígitos" }

O erro fala de chave de acesso porque veio da consulta, não do laudo. Se você depende do laudo, fale conosco antes de migrar.

Fora desta versão

Os verbos que só fazem sentido numa máquina física local não têm equivalente na nuvem:

Recurso Por que não
Impressão ESC/POS Não há impressora do outro lado
Configuração de DANFE local Idem
Cadastro local A empresa e o certificado vivem na plataforma
Restauração de fábrica Não há hardware para restaurar
Atualização automática do agente O adaptador é atualizado por nós
Leitura de log local Sem sistema de arquivos local para ler