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 | Só 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 |
-
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 responde422 erro_validacao. ↩