Compatibilidade — ACBrAPI¶
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.
A comparação é com a especificação 3.1.7 do provedor. Quando ele publica uma versão nova, os campos que ela acrescenta chegam como campo desconhecido. O adaptador os recusa pelo nome até esta página ganhar a linha correspondente.
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 especificação publicada por ele.
Autenticação¶
| Recurso | Veredicto | Observação |
|---|---|---|
client_credentials → Bearer, escopos |
Compatível | Mesmo caminho de token, no host da API |
expires_in de 30 dias |
Compatível | |
Escopo nfce obrigatório nas rotas de NFC-e |
Compatível | Sem ele, 403 insufficient_scope |
| Limite de 4 requisições/hora no endpoint de token | Ressalva | Não aplicamos. Uma folga, não uma quebra |
| Revogação de credencial | Ressalva | Vale na hora, sem esperar o token expirar |
client_secret_basic (credencial no cabeçalho Basic) |
Compatível | Aceito junto com os campos no corpo |
| Escopos do provedor que este adaptador não atende | Ressalva | O adaptador aceita esses escopos e não os concede. O campo scope da resposta lista o que o token recebeu |
| Corpos de erro de autenticação | Ressalva | O provedor não os documenta. Usamos o vocabulário padrão do Keycloak (invalid_client, unsupported_grant_type) |
Emissão — POST /nfce¶
| Recurso | Veredicto | Observação |
|---|---|---|
Árvore infNFe em JSON |
Ressalva | Subconjunto documentado. Ver Grupos aceitos |
ambiente no corpo, com aceitação assimétrica por host |
Compatível | |
referencia opcional |
Ressalva | Sem ela, cada POST é documento novo. O eco responde null quando você não enviou nenhuma |
Formato da referencia |
Ressalva | Máximo de 50 caracteres, e o prefixo ~auto: é reservado. Ver Formato aceito |
Reenvio da mesma referencia |
Ressalva | Responde o estado atual, sempre. Não há reemissão sob a mesma referência. Ver Referência e reenvio |
ide.nNF / ide.serie informados pelo cliente |
Ressalva | Por padrão o número é nosso e nNF é ignorado. A faixa de numeração pelo cliente é configuração da credencial, e nela nNF vira obrigatório (422 se ausente) |
ide.cNF, ide.cDV |
Ressalva | Aceitos e ignorados (são sempre nossos) |
ide.tpEmis |
Ressalva | Aceito e ignorado. Quem decide contingência somos nós |
ide.tpAmb |
Compatível | Se informado, precisa combinar com ambiente |
ide.mod |
Compatível | Só 65. Outro valor é 422 |
ide.natOp |
Ressalva | Se você omitir, gravamos VENDA AO CONSUMIDOR |
ide.tpImp |
Ressalva | Se você omitir, gravamos 4 (DANFE NFC-e) |
ide.indPres |
Ressalva | Se você omitir, gravamos 1 (operação presencial). Envie 4 para entrega a domicílio |
Bloco emit completo |
Ressalva | Validamos emit.CNPJ contra a empresa da credencial e ignoramos o resto. Os dados do emitente vêm do cadastro |
infNFeSupl (QR Code) |
Ressalva | Aceito e ignorado. O QR é gerado na assinatura |
total |
Ressalva | Aceito e ignorado. Os totais são calculados |
infRespTec |
Ressalva | Aceito e ignorado. Preenchido por nós |
| Resposta terminal na própria requisição | Ressalva | O provedor pode responder pendente. Nós respondemos o desfecho. Seu laço de consulta continua correto, e só termina na primeira volta |
POST /nfce/lotes |
Fora | |
POST /nfce/previa/pdf e /xml |
Fora |
Grupos aceitos¶
infNFe aceita: versao, Id, ide, emit, dest, det, total, transp, pag,
infAdic, infRespTec. Qualquer outro grupo é recusado pelo nome, inclusive cobr,
avulsa, retirada, entrega, autXML, exporta, compra, cana, infSolicNFF e
agropecuario.
Em imposto, os grupos aceitos são:
| Tributo | Grupos aceitos |
|---|---|
| ICMS | ICMS00, ICMS20, ICMS40, ICMS60, ICMS90, ICMSSN101, ICMSSN102, ICMSSN500, ICMSSN900 |
| PIS | PISAliq, PISNT, PISOutr, PISQtde |
| COFINS | COFINSAliq, COFINSNT, COFINSOutr, COFINSQtde |
| IBS/CBS | IBSCBS com CST, cClassTrib e gIBSCBS |
Os grupos de ICMS-ST próprio e de partilha (ICMS10, ICMS30, ICMS51, ICMS53,
ICMS61, ICMS70, ICMSPart, ICMSST, ICMSSN201, ICMSSN202) são recusados pelo nome:
não são operações de NFC-e no subconjunto desta versão.
O grupo ICMS é obrigatório em todo item, e o IBSCBS também
(por quê). Quando você informa gIBSCBS,
as três pernas (gIBSUF, gIBSMun, gCBS) precisam vir juntas.
Consulta e listagem¶
| Recurso | Veredicto | Observação |
|---|---|---|
GET /nfce/{id} |
Compatível | id é o identificador que devolvemos na emissão |
GET /nfce com cpf_cnpj + ambiente obrigatórios |
Compatível | |
Filtros referencia, chave, serie |
Compatível | |
$top, $skip, $inlinecount → @count |
Ressalva | Fora da faixa de 1 a 100, $top é 422, em vez de ser corrigido em silêncio. Valor não numérico também é 422, no mesmo corpo {mensagem} das demais recusas |
| Ordenação | Ressalva | Mais recentes primeiro |
| Vocabulário de status do documento | Ressalva | Ver Vocabulário de status |
valor_total |
Ressalva | Calculado como Σ vPag − vTroco |
tipo_emissao |
Compatível | Lido da chave. 9 indica contingência |
| Leitura entre ambientes | Ressalva | O host de homologação lê apenas documentos de homologação |
POST /nfce/{id}/sincronizar |
Fora | |
GET /nfce/sefaz/status |
Fora |
Vocabulário de status¶
| Situação | status |
autorizacao.codigo_status |
|---|---|---|
| Autorizado | autorizado |
cStat da autorização |
| Rejeitado pela SEFAZ | rejeitado |
cStat da rejeição |
| Recusado por nós antes do envio | erro |
null |
| Denegado | denegado |
cStat |
| Cancelado | cancelado |
cStat |
| Em contingência, aguardando entrega | pendente |
— |
| Envio sem desfecho conhecido | pendente |
— |
erro é sempre recusa nossa, nunca da SEFAZ. Como não existe resposta da SEFAZ para
reportar, codigo_status vem null e o bloco autorizacao é reaproveitado para carregar o
diagnóstico: motivo_status traz o problema e mensagem traz a orientação. Nas demais
situações, mensagem vem null.
Contingência não tem estado próprio neste vocabulário. Os valores de status são
pendente, autorizado, rejeitado, denegado, encerrado, cancelado e erro, e
nenhum deles nomeia contingência. Não acrescentamos um: o documento fica pendente até a
entrega terminar. Se você precisa distinguir, tipo_emissao 9 na resposta identifica um
documento de contingência.
Cancelamento¶
| Recurso | Veredicto | Observação |
|---|---|---|
POST /nfce/{id}/cancelamento |
Compatível | |
justificativa opcional, preenchida quando em branco |
Compatível | Nosso padrão é Cancelamento a pedido do emitente |
| Tamanho da justificativa | Ressalva | Exigimos 15 a 255 caracteres (regra da SEFAZ) antes de ir ao fio |
| Janela de cancelamento | Ressalva | Validamos os 30 minutos da NFC-e antes do envio |
GET /nfce/{id}/cancelamento |
Compatível | |
DfeCancelamento.id |
Ressalva | É o identificador do evento, não o do documento. Vale o mesmo critério da inutilização |
justificativa na leitura de volta |
Ressalva | O POST ecoa o que você enviou. A leitura de volta responde null |
autor.cpf_cnpj |
Compatível | CNPJ da empresa emitente |
tipo_evento |
Ressalva | Respondemos "110111", o código SEFAZ do cancelamento. O provedor não documenta o valor que usa |
| Falha de comunicação no cancelamento | Ressalva | Responde 502 sem registrar nada, em vez de afirmar falha. Consulte o documento em seguida. Ver Ciclo de vida |
| Cancelamento por substituição | Fora | O provedor não expõe o verbo |
GET /nfce/eventos, GET /nfce/eventos/{id} |
Fora | Eventos são lidos pelas rotas específicas |
/cancelamento/xml e /cancelamento/pdf |
Fora |
Inutilização¶
| Recurso | Veredicto | Observação |
|---|---|---|
POST /nfce/inutilizacoes |
Compatível | Campos 1:1. O cnpj resolve a empresa |
ano |
Ressalva | Aceitamos 2026 ou 26, e o eco responde os 2 dígitos que a SEFAZ usa. Ver por que recusamos em vez de normalizar |
serie de 0 a 999, numero_inicial e numero_final de 1 a 999999999 |
Compatível | Aplicados na entrada: fora da faixa é 422 antes de qualquer chamada à SEFAZ. Ver de onde vêm esses limites |
numero_final menor que numero_inicial |
Ressalva | 422 |
GET /nfce/inutilizacoes/{id} |
Compatível | id é o do evento devolvido no POST |
justificativa na leitura de volta |
Ressalva | Mesma regra do cancelamento: null |
| Recusa da SEFAZ | Compatível | Em banda, com status: "rejeitado" |
/inutilizacoes/{id}/xml e /pdf |
Fora |
ano é recusado, não normalizado¶
O provedor não limita ano além de "inteiro", então o que fazemos aqui é uma restrição
nossa. Vale conhecer essa restrição, porque ela recusa entradas que antes passavam.
Aceitamos duas formas: o ano com 2 dígitos (26) ou com 4 (2026). Convertemos o de 4
dígitos para os 2 que a SEFAZ usa. Qualquer outro valor responde 422, com
ano: informe o ano com 2 ou 4 dígitos.
O motivo é que a conversão sozinha aceita coisas que não deveria: reduzir um número aos 2
últimos dígitos transforma -5 em 95 e 12026 em 26. Nos dois casos um valor inválido
viraria um ano plausível, e a faixa inutilizada (que não volta atrás) seria de um ano que
você não pediu. Recusar é a única leitura segura.
De onde vêm os limites de serie e de numeração¶
serie de 0 a 999 e a numeração de 1 a 999999999 são os limites do próprio leiaute da NF-e
(TSerie e TNF), que o provedor também publica. Não são escolha nossa nem dele.
Arquivos¶
| Recurso | Veredicto | Observação |
|---|---|---|
GET /nfce/{id}/xml (nfeProc) |
Ressalva | Só para documentos autorizados. O provedor serve também para denegados. Nós não guardamos o invólucro processado nesse caso, então use /xml/nota |
GET /nfce/{id}/xml/nota |
Compatível | |
GET /nfce/{id}/xml/protocolo |
Compatível | Disponível após a autorização |
| Cobrança por download repetido | Ressalva | Não cobramos. A regra de "primeiro download grátis" não se aplica |
GET /nfce/{id}/pdf (DANFCE) |
Fora | |
GET /nfce/{id}/escpos |
Fora | |
POST /nfce/{id}/email |
Fora |
Erros¶
O provedor não documenta nenhuma resposta de erro. Nós mantemos isso onde há resposta em
banda. Validação e rejeição viram status: "erro" ou
"rejeitado" no próprio documento.
Para os cantos que o contrato deixa em aberto, respondemos um código HTTP honesto e um corpo mínimo em português:
| Código | Quando |
|---|---|
404 |
Documento, evento ou arquivo inexistente dentro da visibilidade da sua credencial |
409 |
Operação incompatível com o estado atual do documento. Cancelar o que não está autorizado cai aqui |
422 |
JSON malformado, campo desconhecido, campo obrigatório ausente, parâmetro de query ou de caminho inválido |
502 |
Falha de comunicação com a SEFAZ em uma operação de ciclo de vida |
503 |
Emissão indisponível nesta instalação |
Esse corpo de um campo só é o único formato de erro fora de banda do dialeto. Vale
inclusive para o que normalmente escaparia da nossa validação (um $top com letras, um
{id} que não é um identificador válido), que responde {"mensagem": "Requisição inválida:
…"}. Você pode tratar toda resposta de erro pelo mesmo caminho de código.
| Recurso | Veredicto | Observação |
|---|---|---|
cStat como inteiro em codigo_status |
Compatível | |
402 (créditos), 429 (limite de requisições) |
Fora | Não há cota nem limitação de taxa nesta versão. Não enviamos os cabeçalhos x-quota-*, Retry-After e X-Retry-In |
Fora desta versão¶
Reunidos em um lugar, com o motivo:
| Recurso | Motivo |
|---|---|
Lotes (/nfce/lotes) |
O fluxo de emissão é por documento. Emitir em laço tem o mesmo efeito |
Prévia (/nfce/previa/*) |
Sem equivalente no fluxo de emissão |
| DANFCE em PDF, ESC/POS, e-mail | Disponíveis na plataforma, ainda não expostos por este dialeto |
POST /nfce/{id}/sincronizar |
A resolução de estado é nossa e automática (Contingência) |
GET /nfce/sefaz/status |
Baixa prioridade |
API de empresas (/empresas) |
Empresa, certificado e CSC são cadastro da plataforma |
| Endpoints de depuração | |
| Webhooks | O provedor não tem. O acompanhamento é por consulta |
| NF-e 55, CT-e, MDF-e, NFS-e | Fora do escopo desta versão |