Programação Por Equipe DevBras

Capa do artigo: Gerador de NF-e adaptado para o SAT: por que o equipamento recusa e como separar

Gerador de NF-e adaptado para o SAT: por que o equipamento recusa e como separar

O CF-e-SAT tem leiaute, fluxo e assinatura próprios. Reaproveitar o gerador da NF-e com duas tags trocadas produz cupom recusado no balcão. Veja as diferenças e um desenho com um emissor por documento.

Sábado, 11h, a loja de calçados em Campinas está com fila. O time tinha copiado a rotina que gera a NF-e, trocado a raiz para CFe, renomeado duas tags e apontado para o SAT. Cada venda volta recusada pelo equipamento, e a operadora do caixa não sabe se a venda vale. A resposta curta: o XML do CF-e-SAT não é a NF-e com a raiz trocada. Ele tem leiaute próprio, quem assina é o equipamento e boa parte dos campos que a NF-e exige o seu sistema nem deve mandar. Tenha um gerador por documento, escolhido pela configuração da loja, e teste cada um no ambiente de testes do próprio documento.

Este guia mostra as diferenças que derrubam o reaproveitamento e um desenho de código que impede a mistura. Para o contexto de quando usar SAT, veja SAT fiscal no PDV; para a diferença conceitual entre os documentos, SAT não é a nota eletrônica com outro nome.

Regras fiscais variam por estado e mudam com o tempo. Isto não substitui o contador nem a documentação oficial da Sefaz do seu estado.

Por que "quase igual" não funciona

NF-e, NFC-e e CF-e-SAT resolvem problemas parecidos, mas o fluxo de cada um é diferente, e o XML reflete o fluxo:

  • Na NF-e e na NFC-e, o seu sistema gera o XML completo, com numeração, data de emissão e chave de acesso, assina com o certificado digital da empresa e transmite para o serviço web da Sefaz. A NFC-e usa o mesmo leiaute da NF-e, com modelo 65 e um grupo para o QR Code.
  • No SAT, usado em São Paulo, o seu sistema (o aplicativo comercial) monta apenas os dados da venda e entrega ao equipamento por uma biblioteca do fabricante. O equipamento completa a numeração e a data, assina com o certificado dele e cuida da transmissão. O Ceará tem um modelo próprio de equipamento fiscal, com especificação própria; não é o SAT paulista com outro nome.

Na prática, o XML de entrada do SAT é menor e diferente. O grupo de identificação, que na NF-e tem dezenas de campos, no SAT leva o CNPJ da software house, a assinatura do aplicativo comercial (signAC) e o número do caixa. A versão vem no atributo versaoDadosEnt, não em versao. E grupos equivalentes têm nomes e estrutura diferentes.

O mesmo pagamento nos dois documentos

Uma venda de R$ 59,90 no cartão de crédito. Na NF-e e na NFC-e:

<pag>
  <detPag>
    <tPag>03</tPag>
    <vPag>59.90</vPag>
  </detPag>
</pag>

No XML de venda do SAT:

<pgto>
  <MP>
    <cMP>03</cMP>
    <vMP>59.90</vMP>
  </MP>
</pgto>

Mesma informação, outra estrutura. Multiplique isso pelo cabeçalho, pelos itens e pelos impostos, e a rotina "adaptada" vira uma colcha de if que gera um documento que não é nenhum dos dois. O guia sobre gerar o XML da nota sem concatenar vale para os dois documentos; o ponto aqui é que cada um tem o seu modelo.

Como separar os fluxos no código

  1. Modele a venda uma vez, sem nada fiscal: itens, quantidades, valores, pagamentos, cliente opcional. Ela é a entrada comum.
  2. Crie um emissor por documento, cada um com o próprio modelo de XML, a própria validação e a própria forma de envio: um para NFC-e, outro para CF-e-SAT.
  3. Escolha o emissor pela configuração da loja e do caixa, não por um if espalhado. A loja de Campinas emite SAT; a loja de outro estado emite NFC-e.
  4. Falhe na abertura do caixa se a configuração não tiver emissor válido. É melhor descobrir às 8h do que na primeira venda.
  5. Mostre na tela do caixa qual documento está ativo. Quem opera a loja precisa saber se está emitindo SAT ou NFC-e.
  6. Teste cada emissor no ambiente de testes próprio: homologação da Sefaz para a NFC-e, equipamento em modo de teste ou ferramenta de teste oficial para o SAT.

Um emissor por documento, escolhido pela loja

public enum DocumentoDeVenda { Nfce, CfeSat }

public sealed record ResultadoEmissao(bool Autorizado, string? Chave, string? Xml, string Mensagem);

public interface IEmissorDeCupom
{
    DocumentoDeVenda Documento { get; }
    Task<ResultadoEmissao> EmitirAsync(Venda venda, CancellationToken ct);
}

public sealed class SeletorDeEmissor
{
    private readonly IReadOnlyDictionary<DocumentoDeVenda, IEmissorDeCupom> _emissores;

    public SeletorDeEmissor(IEnumerable<IEmissorDeCupom> emissores) =>
        _emissores = emissores.ToDictionary(e => e.Documento);

    public IEmissorDeCupom Para(ConfiguracaoDoCaixa caixa) =>
        _emissores.TryGetValue(caixa.Documento, out var emissor)
            ? emissor
            : throw new InvalidOperationException(
                "Caixa " + caixa.Numero + " configurado para " + caixa.Documento + ", mas não há emissor registrado.");
}

O EmissorSat e o EmissorNfce implementam a interface cada um à sua maneira. O emissor de SAT monta o XML de venda com signAC e número do caixa, chama a função de envio da biblioteca do fabricante com o número de sessão e o código de ativação, e interpreta o retorno do equipamento. O de NFC-e monta o XML completo, assina com o certificado, gera o QR Code e transmite. Nenhum dos dois conhece o outro. Uma mudança no leiaute do SAT não tem como quebrar a NFC-e.

Na abertura do caixa, chame Para uma vez e guarde o emissor. Se lançar exceção, o caixa não abre e mostra a mensagem. A operadora vê na barra superior "Emitindo: CF-e-SAT" ou "Emitindo: NFC-e".

Contingência e mudança de documento

Contingência é outro ponto em que os documentos não se misturam. A NFC-e tem modalidades de contingência próprias, previstas na documentação. O SAT tem o comportamento do equipamento e as regras da Sefaz-SP para quando ele falha. Não improvise "se o SAT falhar, emite NFC-e" numa sexta à tarde sem saber se a sua empresa pode e como registrar isso. Defina com o contador antes, escreva o procedimento e teste.

A Sefaz-SP vem conduzindo a migração de contribuintes do SAT para a NFC-e. Se a sua loja está nessa transição, o desenho com um emissor por documento é exatamente o que permite trocar a configuração do caixa num dia marcado, sem reescrever a venda. Confira o cronograma na página oficial da Sefaz-SP. Se você atende lojas em mais de um estado, veja também SAT de um estado não se copia para outro.

Erros comuns

  • Reaproveitar o gerador da NF-e trocando a raiz. O equipamento recusa, e a recusa aparece no balcão, com cliente esperando.
  • Mandar ao SAT campos que ele mesmo preenche, como numeração e data de emissão. O XML de entrada fica fora do leiaute.
  • Decidir o documento com if espalhado pelo código. Uma tela emite SAT, outra emite NFC-e, e ninguém sabe qual vale em cada caixa.
  • Testar o SAT só com XML validado no computador do desenvolvedor. A recusa real vem do equipamento ou da ferramenta de teste oficial.
  • Esconder da operação qual documento está ativo. Quando dá problema, o suporte pergunta "é SAT ou NFC-e?" e ninguém na loja sabe responder.
  • Tratar a biblioteca fiscal como se ela escolhesse o documento. Ela emite o que você pede; a escolha é configuração da loja, validada com o contador.

Checklist

  • Existe um emissor separado para cada documento, sem código de XML compartilhado entre eles.
  • A venda é modelada uma vez, sem campo fiscal específico de um documento.
  • O documento de cada caixa vem da configuração, e o caixa não abre sem emissor válido.
  • A tela do caixa mostra qual documento está ativo.
  • O emissor de SAT foi testado no equipamento em modo de teste ou na ferramenta oficial.
  • O procedimento de contingência de cada documento está escrito e foi validado com o contador.
  • Há um plano para trocar o documento de uma loja sem mexer na venda.

Vá até o caixa de uma das suas lojas e tente responder sem abrir o código: o botão de finalizar a venda vai emitir CF-e-SAT ou NFC-e, e onde isso está configurado?

Avalie este artigo

Referência: https://social.msdn.microsoft.com/Forums/pt-BR/adaea637-348f-4432-b8a8-0dc8218deba3/gerar-xml-para-o-sat-fiscal?forum=vsvbasicpt