Skip to main content
Empresa de Lucro Real ou Presumido (crt: 3 no cadastro) emite NF-e e NFC-e com o ICMS calculado pelo motor fiscal: você manda o item com NCM, CFOP, origem e valores, liga "resolverTributacao": true, e o documento sai com o grupo de ICMS completo (CST 00, base, alíquota e valor, e o FCP onde ele existe). Não existe campo de alíquota no payload, de propósito: a alíquota vem de uma base fiscal auditada, não do que o integrador digitou.
  • Opt-in explícito: só com "resolverTributacao": true. Sem a flag, o emissor CRT=3 recebe 422.
  • Fonte auditada: a lista viva de UFs curadas está em Cobertura fiscal, mais a tabela federal de interestadual.
  • Recusa em vez de chute: cenário fora da base retorna 422 com o motivo, nada é emitido.

Como emitir

Os três campos que mudam o imposto e por isso importam: Na NFC-e não há o que informar: o modelo 65 é sempre venda presencial a consumidor final na UF do emitente, e a API declara isso ao motor por você.

O que sai no documento

Para um item de R$ 1.000,00 com emissor em Goiás vendendo dentro do estado:
  • CST 00 (tributada integralmente) é o CST que o motor calcula nesta fase. Os CST de ST e de benefício fiscal têm caminhos manuais próprios, descritos adiante.
  • modBC 3 = base de cálculo pelo valor da operação (LC 87/1996, art. 13, I). É o que o motor calcula: sem redução de base, sem pauta, sem MVA.
  • Se o item traz desconto, a base é o valor da operação líquido (vBC = vProd − vDesc): descontos incondicionais não integram a base (LC 87/1996, art. 13, § 1º, II, “a”; a lei manda integrar só os concedidos sob condição). O mesmo vale para a base do IBS/CBS (LC 214/2025, art. 12, § 2º, III). Use desconto apenas para desconto incondicional: é o único que o documento carrega.
  • pFCP/vFCP entram no grupo só onde existe adicional de Fundo de Combate à Pobreza: hoje o RJ (2%, geral) e o SE (a consumidor final, por produto). Onde não há adicional, o par não aparece: ausência é diferente de “0%”.
  • O ICMS não muda o total da nota: ele já está embutido no preço da mercadoria (vNF = produtos − desconto + frete + seguro + outras + II + IPI). Seu pagamentos continua fechando com o mesmo valor de antes.

O que o motor recusa, e por quê

Um 422 aqui é sempre local: nada chega à SEFAZ e nenhum número fiscal é consumido. O corpo traz code e o motivo por item. Exceção de canal (#745): para emissor de venda porta-a-porta (Conv. ICMS 45/99), ative canalPortaAPorta no cadastro (POST /v1/companies ou PATCH /v1/companies/{id}). A flag vale por emissor e, por isso, alcança os dois modelos em que o motor roda (55 NF-e e 65 NFC-e): numa venda de balcão interna (NFC-e) com item do segmento 28, ligar a flag pode transformar um caso que calculava em 422 TRIBUTACAO_NAO_RESOLVIDA por ST. Com a flag desligada, segue a regra global pós-#742 (esses capítulos não concluem ST por NCM). Na tripla DIFAL estrita (UF diferente + indFinal=1 + indIEDest=9), a tripla vence e o detector cede mesmo com a flag ligada (#751). Risco residual: indFinal é declaratório; se o ERP marcar indFinal=1 para revendedor não inscrito, a engineAPI confia nessa declaração (mesma premissa já adotada no fluxo da tripla DIFAL).

DIFAL: como emitir venda interestadual a consumidor final

Quando você vende para outro estado e o destinatário é consumidor final não contribuinte (o caso típico do e-commerce), a EC 87/2015 manda partilhar o imposto com o estado de destino, e o documento tem que carregar o grupo ICMSUFDest (base, alíquota interna do destino, valor devido ao destino e ao remetente). A engineAPI calcula o ICMS da operação própria, mas não apura a partilha: você apura os valores conforme a legislação da UF de destino e os informa em items[].icms.ufDestino. Sem esse grupo, a API recusa antes de emitir um documento incompleto. O que fazer hoje:
  • se o destinatário é contribuinte, declare destinatario.indicadorIE: 1, a operação deixa de ser hipótese de DIFAL e o diferencial é apurado pelo próprio destinatário, fora deste documento;
  • se é venda a consumidor de outro estado, informe o grupo items[].icms.ufDestino com a partilha calculada conforme a legislação da UF de destino. A API valida e transcreve o grupo, mas não calcula a base nem as alíquotas; siga o guia de DIFAL;
  • o grupo é aceito para emissor crt: 2 ou crt: 3. Emissor do Simples pleno (crt: 1) ou MEI (crt: 4) recebe 422 DIFAL_NAO_APLICAVEL e deve removê-lo;
  • indicadorIE ausente é tratado como não contribuinte para esta validação: quando a operação for interestadual para consumidor final, informe também o grupo de DIFAL em vez de omiti-lo.
Exemplo de resposta abreviada quando o grupo de DIFAL não é informado: O motivo abaixo é abreviado; a resposta real inclui os campos da partilha e a instrução completa para o reenvio.

Quando usar ICMS manual no Regime Normal

O grupo de ICMS do leiaute 4.00 exige a modalidade da base de cálculo (modBC), e para a maioria dos CST este contrato não expõe esse campo. Aceitar o cst e escolher a modalidade por conta própria seria decidir tributação no lugar de quem emite, em documento assinado e permanente. Há três caminhos manuais, todos com os valores apurados por quem emite:
  • substituição tributária, com os CST 60, 10, 30 e 70 na NF-e (modelo 55), para emissor crt: 2 ou crt: 3;
  • benefício fiscal, com os CST 20, 40, 41, 50, 51 e 90, nos grupos e modelos que o leiaute comporta; e
  • DIFAL, pelo grupo items[].icms.ufDestino na venda interestadual a consumidor final não contribuinte, nas condições da seção anterior.
Fora desses caminhos, informar somente icms.cst continua recusado: o contrato não expõe a modalidade de base necessária para a maioria dos CST.

Substituição tributária: os quatro CST que emitem hoje

A engineAPI não calcula ST. A margem de valor agregado e a alíquota interna de ST variam por UF, por NCM e por convênio, e estimar qualquer uma delas seria inventar imposto em documento assinado. O que ela faz é transmitir o que você informa, validando o que o leiaute comporta antes de consumir número fiscal.
Estado da prova, por código. O cst "60" (revenda já retida) e o cst "10" (tributada com ST) têm emissão real autorizada em homologação. Os cst "30" e "70" têm a estrutura validada contra o leiaute oficial e ainda aguardam a emissão real. O estado célula a célula fica em Cobertura fiscal.
Opcionais nos três últimos: pMVAST (margem de valor agregado), pRedBCST (redução da base da ST) e os trios de Fundo de Combate à Pobreza: vBCFCP/pFCP/vFCP sobre o ICMS próprio e vBCFCPST/pFCPST/vFCPST sobre a ST. Cada trio vai inteiro ou não vai.
A ST cobrada nesta operação COMPÕE o total da nota. No leiaute, vNF = produtos − desconto + frete + seguro + outras despesas + IPI + ICMS-ST + FCP-ST. No exemplo acima, os R7,20deSTentramnototal:opagamentoeˊdeR 7,20 de ST entram no total: o pagamento é de R 107,20, não R$ 100,00. Se os pagamentos não fecharem com esse total, a emissão recusa com 422 PAGAMENTO_DIVERGENTE antes de numerar. O ICMS próprio não entra (já está no preço da mercadoria).
O que a engineAPI confere antes de emitir, e o que não confere:
  • confere vICMS = vBC × pICMS (tolerância de R$ 0,01), a única conta com regra de validação escrita no leiaute: divergente é 422 ICMS_ST_INVALIDO, e a SEFAZ rejeitaria depois de consumir o número;
  • confere a estrutura: bloco pela metade é 422 ICMS_ST_INCOMPLETO, campo que não existe naquele CST (por exemplo pRedBC no "10") é 422 ICMS_ST_INVALIDO, modalidade fora da tabela idem;
  • não confere vICMSST contra vBCST × pICMSST: não existe regra escrita para essa conta, e checar o que a norma não afirma recusaria emissão legítima;
  • não recalcula a base da ST a partir de pMVAST: a base é a que você informou.
Fora do escopo desta entrega, com recusa nomeada: desoneração do ICMS e da ST (vICMSDeson, motDesICMS, vICMSSTDeson), partilha entre UF (ICMSPart), repasse interestadual de ST em combustível (grupo ICMSST), inscrição estadual de substituto do emitente (IEST) e os CSOSN de ST do Simples (201/202/203). Todos devolvem 400 ou 422 nomeando o motivo, nunca saem em silêncio. Na NFC-e (modelo 65) esses três CST não existem: o leiaute fecha o domínio do código de situação tributária desse documento. A emissão recusa com 422 antes de numerar, e os campos do grupo devolvem 400.

Substituição tributária: recusa por NCM

Antes de calcular qualquer coisa, o motor verifica se o NCM do item está arrolado no CEST (Convênio ICMS 142/2018). Se estiver, a resposta é 422, mesmo que você não tenha informado nada de ST. A resposta abaixo é abreviada:
Por que recusar em vez de emitir com ICMS próprio: em regime de ST quem recolhe é o substituto, e declarar ICMS integral no lugar da substituição é errar com o sinal invertido, o oposto do que o documento deveria dizer. Isso recusa mais do que a ST efetivamente devida, e é deliberado: a tabela de CEST não distingue par UF×UF (a exigência depende de protocolo entre os estados), então o critério é “este produto é passível de ST”, não “há ST nesta operação”. Produtos de segmentos com ST ampla (bebidas, autopeças, cosméticos, medicamentos, combustíveis) caem aqui. Isso vale para o cálculo automático: o motor não resolve ST, e não vai resolver nesta fase. O caminho manual de ST usa os quatro CST da seção acima, em que você informa os números e a engineAPI transmite. Benefícios fiscais e DIFAL têm seus próprios caminhos manuais; não substituem o grupo de ST. A recusa por CEST só acontece quando o item pede resolução automática; item com icms.cst de ST não passa pelo motor.

Cobertura de hoje: cálculo automático e caminhos manuais

A base tem prazo de validade declarado: alíquota estadual muda por lei, e uma base vencida aplicada em silêncio seria pior que a recusa. A revalidação é parte do processo de release.

Perguntas rápidas

Preciso mandar alíquota? Não, e não existe campo para isso. A alíquota vem da base auditada. E se eu não ligar a flag? O emissor CRT=3 recebe 422 ICMS_REGIME_NORMAL_NAO_RESOLVIDO. Antes desta versão o documento saía com CSOSN (código exclusivo do Simples) e a SEFAZ rejeitava; o 422 local é o mesmo problema, descoberto antes de queimar número fiscal. Simples Nacional muda em alguma coisa? Não. Emissor crt: 1 continua exatamente como antes, com CSOSN. O 422 consome número? Nunca. Todas as recusas deste guia rodam antes da numeração fiscal, nos dois caminhos (síncrono e lote).