Pular para conteúdo

Compatibilidade — FocusNFE

O que o adaptador aceita, o que ele recusa e onde ele diverge do provedor. Onde não há linha nesta página, o comportamento é o do provedor. 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 provedor vem da documentação publicada por ele.

Autenticação

Recurso Veredicto Observação
HTTP Basic, token como usuário, senha em branco Compatível
Token por empresa por ambiente Compatível O endereço base seleciona o ambiente
401 com corpo text/html HTTP Basic: Access denied Compatível Reproduzido, inclusive o content-type
403 permissao_negada para CNPJ de outra empresa Compatível
Rotação de token pela API Fora O Veraciti provisiona os tokens

Emissão — POST /v2/nfce?ref=

Recurso Veredicto Observação
Corpo JSON achatado, campos em português Ressalva Subconjunto documentado. Ver Campos aceitos
Emissão síncrona Compatível
201 nos dois desfechos (autorizado e erro_autorizacao) Compatível
ref obrigatória na query, alfanumérica Ressalva Limite de 200 caracteres. A mesma regra vale no caminho da consulta, do cancelamento e do e-mail: fora do alfabeto é 422 erro_validacao, campo: "ref"
Escopo da ref Compatível Única por token, ou seja, por empresa e ambiente
Recusa antes da SEFAZ Compatível 422 erro_validacao, com erros[] preenchido
Numeração automática pela API Compatível É o padrão, como no provedor
numero / serie informados pelo cliente Ressalva Só em credenciais na faixa de numeração pelo cliente. Caso contrário, 422
codigo_unico (cNF) Ressalva Sempre nosso. Informá-lo é 422
natureza_operacao com padrão VENDA AO CONSUMIDOR Compatível
numero_item em cada item Compatível Opcional. Ver numero_item é opcional
data_emissao Ressalva O fuso horário é obrigatório. Enviar sem ele é 422
forma_emissao=offline Fora A contingência aqui é automática. Ver Contingência
completa=1 Compatível Acrescenta protocolo e requisicao_nota_fiscal
itens no eco de completa=1 vs items na emissão Compatível Quirk reproduzido de propósito

Reenvio da mesma ref

Estado da ref Resposta Veredicto
Em processamento 422 pending_operation Compatível
Autorizada ou cancelada 422 already_processed Compatível
Denegada 422 already_processed Ressalva: não reemitimos sob denegação
erro_autorizacao Nova tentativa. O número depende da faixa Ressalva

O reenvio após rejeição é o caminho de correção documentado pelo provedor, e nós o implementamos. A ressalva é a numeração, e ela depende da faixa da sua credencial.

Na numeração pela API, que é o padrão, o reenvio recebe um número novo, e o número da tentativa rejeitada fica como lacuna. Na faixa de numeração pelo cliente, você pode reenviar o mesmo numero, sob as condições de Quando um número seu pode ser reutilizado.

Quem chega do FocusNFE cai na numeração pela API e passa a ver lacunas onde antes não via. E perde um mecanismo. O provedor documenta que a API dele pode inutilizar números em vez de reaproveitar o número, e publica o gatilho inutilizacao para avisar quando isso acontece. Aqui não há equivalente: o número da tentativa rejeitada fica aberto, e nós não o fechamos nem avisamos. Você o fecha por inutilização, como as demais lacunas.

O canal já existe deste lado. O gatilho inutilizacao dispara em toda inutilização efetiva da empresa (ver Webhooks). O que falta é o fato a notificar.

O provedor documenta o reenvio sob a mesma ref neste estado. Ele não documenta qual número a nova tentativa consome.

Duas emissões simultâneas na mesma ref que ainda não existe: uma vence, e a outra recebe 201 com o estado da vencedora, o mesmo corpo que uma consulta responderia. O provedor provavelmente responderia pending_operation. É uma divergência conhecida e aceita.

numero_item é opcional

A numeração dos itens vem da ordem do array items, então o adaptador não lê o campo. O campo continua aceito: nada muda para quem já manda, e quem parar de mandar também não vê diferença.

Campos aceitos

No documento: cnpj_emitente, data_emissao, natureza_operacao, presenca_comprador, modalidade_frete, local_destino, items, formas_pagamento, serie, numero, codigo_unico, cpf_destinatario, cnpj_destinatario, nome_destinatario, indicador_inscricao_estadual_destinatario, informacoes_adicionais_contribuinte, valor_troco.

Em cada item: identificação e valores (numero_item, codigo_produto, descricao, codigo_ncm, cest, cfop, unidade_comercial, unidade_tributavel, quantidade_comercial, quantidade_tributavel, valor_unitario_comercial, valor_unitario_tributavel, valor_bruto, valor_desconto, valor_frete, valor_seguro, valor_outras_despesas, valor_total_tributos, codigo_barras_comercial, codigo_barras_tributavel), e os grupos de tributo:

Grupo Campos
ICMS icms_origem1, icms_situacao_tributaria, icms_modalidade_base_calculo, icms_base_calculo, icms_aliquota, icms_valor
FCP fcp_percentual, fcp_valor
ST retido / consumidor final icms_base_calculo_retido_st, icms_aliquota_final, icms_valor_substituto, icms_valor_retido_st, fcp_base_calculo_retido_st, fcp_percentual_retido_st, fcp_valor_retido_st, icms_reducao_base_calculo_efetiva, icms_base_calculo_efetiva, icms_aliquota_efetiva, icms_valor_efetivo
Crédito do Simples icms_aliquota_credito_simples, icms_valor_credito_simples
PIS / COFINS pis_situacao_tributaria, pis_base_calculo, pis_aliquota_porcentual, pis_quantidade_vendida, pis_aliquota_valor, pis_valor e os equivalentes cofins_*
IBS/CBS ibs_cbs_situacao_tributaria, ibs_cbs_classificacao_tributaria, ibs_cbs_base_calculo, ibs_uf_aliquota, ibs_uf_valor, ibs_mun_aliquota, ibs_mun_valor, ibs_valor_total, cbs_aliquota, cbs_valor

Em cada forma de pagamento: forma_pagamento, valor_pagamento, tipo_integracao, bandeira_operadora, numero_autorizacao.

Como no provedor, icms_situacao_tributaria carrega o CST (2 dígitos) ou o CSOSN (3 dígitos). O comprimento decide qual dos dois o campo carrega. icms_aliquota é o pICMS sem o FCP, que tem campos próprios.

Fora do subconjunto e recusados: partilha por UF de destino (icms_*_uf_destino, fcp_*_uf_destino, icms_aliquota_interestadual), ST próprio (icms_modalidade_base_calculo_st, icms_margem_valor_adicionado_st, icms_aliquota_st, icms_valor_st), combustíveis monofásico (icms_*_mono*), diferimento, cashback (pDevTrib/vDevTrib), crédito presumido, Imposto Seletivo (is_*), ZFM, códigos de barras próprios (codigo_barras_proprio_*) e fcp_base_calculo. Os totais de documento também não são aceitos, porque nós calculamos todos eles.

Consulta — GET /v2/nfce/{ref}

Recurso Veredicto Observação
Consulta por ref Compatível
404 nao_encontrado para ref desconhecida Compatível
erros[] na consulta de um documento rejeitado Compatível
Ausência de rota de listagem de NFC-e Compatível Igual ao provedor: acesso só por ref
chave_nfe com prefixo NFe Compatível
numero, serie, status_sefaz como texto Compatível

Vocabulário de status

Situação status
Autorizado autorizado
Rejeitado pela SEFAZ erro_autorizacao
Denegado denegado
Cancelado cancelado
Em contingência offline autorizado + contingencia_offline: true
Envio sem desfecho conhecido processando_autorizacao

A linha processando_autorizacao é uma ressalva: a NFC-e do provedor é síncrona e esse valor não está no status de topo, que é autorizado, cancelado, erro_autorizacao ou denegado. No contrato do provedor ele aparece em tentativa_anterior.status. Nós o usamos no status de topo, na única situação em que um documento pode ficar sem desfecho: um envio cujo resultado ainda precisa ser provado por consulta. É deliberado. A alternativa seria afirmar autorização sem resposta da SEFAZ, o que não fazemos.

Nesse estado a resposta vem sem liquidação: sem chave_nfe, sem numero/serie, sem os caminhos de arquivo e sem status_sefaz, porque não há o que reportar ainda. Vale tanto na emissão (201) quanto na consulta, e um reenvio da mesma ref responde 422 pending_operation até a consulta resolver o desfecho.

Documento em contingência responde no formato de autorização com o par contingencia_offline / contingencia_offline_efetivada, como no provedor.

Cancelamento — DELETE /v2/nfce/{ref}

Recurso Veredicto Observação
justificativa de 15 a 255 caracteres Compatível Validada antes do envio
Janela de 30 minutos Ressalva Validamos antes de ir à SEFAZ, para que o erro seja claro
Recusa da SEFAZ em banda (erro_cancelamento, HTTP 200) Compatível
caminho_xml_cancelamento, numero_protocolo Compatível
Content-Type: application/json obrigatório Ressalva Vale também no DELETE. Sem ele, 415 formato_invalido
Falha de comunicação com a SEFAZ Ressalva 502 erro_comunicacao, sem afirmar falha. Consulte o documento em seguida
Cancelamento por substituição Fora O provedor não expõe o verbo

Inutilização

Recurso Veredicto Observação
POST /v2/nfce/inutilizacao (singular) Compatível Campos e formato do provedor
ano derivado no servidor Compatível Usamos o ano corrente
GET /v2/nfce/inutilizacoes (plural) Ressalva As entradas são por número: uma faixa inutilizada aparece como um registro por documento, não como um intervalo
Filtros cnpj, numero_inicial, numero_final Compatível
Filtros data_recebimento_* Ressalva Interpretamos a data sem fuso como UTC. Envie o deslocamento se quiser hora local
protocolo_sefaz (inutilização) vs numero_protocolo (cancelamento) Compatível Quirk reproduzido
autorizado/erro_autorizacao como status de evento Compatível Quirk reproduzido

E-mail

Recurso Veredicto Observação
POST /v2/nfce/{ref}/email, até 10 endereços Compatível Envio em segundo plano
Envio de documento ainda não autorizado Ressalva 422 erro_validacao

Webhooks (gatilhos)

Recurso Veredicto Observação
CRUD em /v2/hooks Compatível
Eventos nfce_contingencia e inutilizacao Compatível São os dois que se aplicam à NFC-e
Outros eventos do enum Fora 422 no registro
Registro por cpf Fora 422. Os tokens são por empresa
cnpj diferente do da credencial Compatível 403 permissao_negada
Autenticação por cabeçalho estático Compatível Sem HMAC, como no provedor
Escada de retentativas 1min/30min/1h/3h/24h Compatível Seis envios no total, depois descartado
Validação da URL registrada Ressalva http/https, e recusamos endereços privados com 422. Conferimos de novo a cada envio. Ver Requisitos do seu endpoint
Redirecionamentos Ressalva O adaptador não os segue. Um 3xx conta como tentativa fracassada
Garantia de entrega Ressalva Ao menos uma vez. O mesmo evento pode chegar repetido. Faça o seu recebedor idempotente
Limite de gatilhos Ressalva Até 10 ativos por empresa e ambiente, somando os eventos. O 11º responde 422 erro_validacao. O provedor conta por evento: 5 por empresa para o mesmo evento
DELETE /v2/hooks/{id} Ressalva Desativa em vez de apagar: o gatilho some da listagem e para de disparar, mas o histórico de entregas permanece. Libera uma vaga no limite
Corpo da entrega Ressalva Congelado no disparo. Uma retentativa reenvia o que o evento dizia, não o estado atual
Corpo do nfce_contingencia Ressalva É o corpo de consulta do documento, sem qrcode_url e url_consulta_nf
Origem do inutilizacao Ressalva Dispara para toda inutilização efetiva da empresa, inclusive as feitas fora deste adaptador
Reenvio manual de gatilho Fora O provedor também não tem para NFC-e

Arquivos

Recurso Veredicto Observação
caminho_xml_nota_fiscal Compatível Mesmo formato de caminho, raiz por ambiente
caminho_xml_cancelamento Compatível
Raiz /arquivos_development em homologação Compatível Reproduzida do caminho de exemplo do provedor
Caminhos relativos Compatível Concatene com o endereço base
caminho_danfe Ressalva O caminho termina em .html, mas serve o DANFCe em PDF (content-type: application/pdf). Não há renderização em HTML nesta versão
Autenticação nas rotas de arquivo Compatível Mesmo Basic das demais rotas
Busca de arquivo de outro ambiente Compatível 404
XML da inutilização Ressalva Servimos em /{raiz}/inutilizacao/{id}.xml, e o provedor em /{raiz}/{cnpj}/{aaaamm}/XMLs/{chave}-inu.xml. O formato do caminho é nosso. O id precisa ser de uma inutilização sua, no ambiente do endereço base. Qualquer outro responde 404

Erros

As regras abaixo decidem o formato de qualquer recusa. Elas cobrem casos que a tabela não lista, então vale conhecê-las antes dela.

Corpo lido como documento responde 422. Corpo lido como parâmetros responde 400. A emissão recebe um documento fiscal, e suas recusas de campo vêm em 422 erro_validacao_schema com a lista erros[]. Cancelamento, inutilização, e-mail e criação de gatilho recebem parâmetros, e suas recusas vêm em 400 requisicao_invalida, com uma única mensagem que nomeia o parâmetro e sem erros[]. É o mesmo corte que o provedor faz, e ele só vale para corpos que chegaram a ser lidos.

erros[] só aparece quando a recusa aponta para um campo que você enviou. Um corpo que não é JSON válido não tem campo ao qual atribuir a falha. A resposta é 415 formato_invalido, em qualquer rota, com codigo e mensagem e sem o array. Quando erros[] vem, campo é sempre um nome de campo desta API, nunca um caminho do layout da NF-e.

Um problema em item pode existir sem entrada em erros[]. Quando a regra nomeia um grupo do leiaute, e não um campo desta API, nós omitimos a entrada em vez de inventar um nome. O texto do problema fica em mensagem. O item aparece no fim da frase do problema, como [nItem:2], na mesma forma que o provedor usa. Se você usa erros[] para localizar o que corrigir, leia mensagem também.

Recurso Veredicto Observação
Corpo {codigo, mensagem, erros[]} Compatível
400 requisicao_invalida (ref ausente) Compatível
415 formato_invalido Compatível Corpo que não é JSON válido responde 415, como no provedor. Também respondemos 415 quando o Content-Type não é application/json. Nenhum cliente correto alcança esse segundo gatilho
Códigos 422: erro_validacao, erro_validacao_schema, pending_operation, already_processed, empresa_nao_configurada Compatível
502 erro_comunicacao Ressalva Não existe no contrato do provedor. Usamos quando não alcançamos a SEFAZ em uma operação de ciclo de vida
Limites de requisição e cota Fora Não há cota nem limitação de taxa nesta versão. Não respondemos 429 nem enviamos os cabeçalhos Rate-Limit-*

Fora desta versão

Reunidos em um lugar, com o motivo:

Recurso Motivo
ECONF (conciliação financeira) Sem equivalente no fluxo de emissão. Candidato a uma versão futura
forma_emissao=offline A contingência é automática aqui
Endpoints do produto "NFC-e local" (*_local) Produto diferente, fora do escopo
API de empresas (tokens, CSC, habilita_*) Empresa, certificado e CSC são cadastro da plataforma
NF-e 55, CT-e, MDF-e, NFS-e e seus gatilhos Fora do escopo desta versão

  1. icms_origem é obrigatório em todo item, inclusive para emitentes MEI. O dicionário de campos do provedor marca o campo como não obrigatório nesse caso. Aqui nós o exigimos do mesmo jeito. A origem da mercadoria (orig) é obrigatória no XML da NF-e e não existe valor padrão documentado para MEI, então omiti-la significaria atribuir uma origem que você não declarou. Envie sempre, porque omitir responde 422 erro_validacao