Business - Automação Comercial

Automação Comercial com VB, VB.NET e C# (ECF e TEF) - PARTE III de IV - Transação Eletrônica de Fundos

Segundo o convênio ICMS (anexo à regulamentação principal da lei de 1994 que legisla o uso do ECF) agora é obrigatório que o TEF (Transferência Eletrônica de Fundos) seja realizado pelo ECF.

por Claudenir Andrade



Segundo o convênio ICMS (anexo à regulamentação principal da lei de 1994 que legisla o uso do ECF) agora é obrigatório que o TEF (Transferência Eletrônica de Fundos) seja realizado pelo ECF. - Como assim? - Bem, hoje quando nos dirigimos a qualquer estabelecimento comercial que aceite como forma de pagamento cartão de crédito (Visa, Amex, Credicard, etc.) ou cartão de débito (Bancos, Debito Automático, RedShop, Cheque Eletrônico, etc.) o pagamento de nossa compra com o cartão é considerado um TEF, ou Transação Eletrônica de Fundos, e quem realiza esta operação são aquelas "impressorinhas" que ficam espalhadas pelo balcão de atendimento, que muitas vezes para atender todas as bandeiras de cartão o comerciante é obrigado a amontoar no balcão cinco ou seis impressoras com seus teclados ou Pin Pads. Muito bem, o uso destas impressoras, para todo estabelecimento obrigado a utilizar um ECF, está proibida!!! A impressão do comprovante de pagamento em cartão deve ser emitida no ECF, isso mesmo, no ECF!!! - Aqui vale um comentário: - Não confunda o cupom fiscal com o comprovante de compra em cartão. O cupom fiscal registra a compra fiscalmente, contabilizando o ICMS ou ISS devido pelo estabelecimento comercial. O comprovante de compra em cartão registra que sua compra foi autorizada pela administradora e que o valor que consta neste "recibo" é o valor que será cobrado em sua fatura de cartão ou o débito que será realizado em sua conta-corrente. Então já que o uso das "maquininhas" está proibido e necessitamos efetuar a operação através do ECF como preparar o meu programa para que o mesmo possa realizar o TEF?

TEF - Primeiros Passos

Existem hoje duas maneiras de se realizar o TEF. De forma discada ou dedicada. A tabela1 indica a diferença entre elas. O TEF através da linha discada é mais "lento" que a linha dedicada, observe que colocamos "lento" entre aspas porque quando você decidir que tipo de TEF colocar ou indicar para seu cliente deverá levar em consideração o tempo médio de emissão de cupom fiscal e o número de vendas que são realizadas em cartão. Exemplo: Um supermercado obviamente optaria por colocar uma ou mais linhas dedicadas, pois "discar" e efetuar uma conexão normal por modem (como é o processo discado) é inviável para um supermercado de médio porte onde a velocidade é um fator crítico e as compras com cartão são constantes, ou seja, o tempo médio de emissão chega a 10 cupons a cada 15 minutos. Já em um mini-mercado ou material de construção a emissão de 10 cupons (10 clientes) leva até 50 minutos, pois a rotatividade é baixa e o número de clientes que paga em cartão também é baixa, talvez pela localização e o perfil dos consumidores da região. Agora quando falamos em um estabelecimento com 3 PDVs deve ser analisado o custo-beneficio da colocação de um TEF discado ou dedicado. Se a combinação Tempo Médio de Emissão e Velocidade para este perfil de cliente é um fator crítico, sem dúvida o dedicado será a melhor solução. Vamos falar sobre o TEF discado onde cada PDV terá um Modem no computador para que possa efetuar a transação TEF da compra realizada em cartão.

Além de decidir qual TEF colocar, também é necessário para TEF discado baixar um GP, Gerenciador Padrão, programa fornecido pelas bandeiras em parcerias com empresas homologadoras e certificadoras como a Software Express e a SevenPDV. - Certificadoras? Isso mesmo!!! Calma, isso não significa que a Software Express, empresa autorizada pelas bandeiras a certificarem o uso do GP , estarão aprovando ou não sua aplicação de automação comercial. O objetivo deles é certificar que seu aplicativo está "Falando" de maneira correta como o GP e realizando as operações de acordo com o que é indicado no Roteiro de Homologação e exigido pelas bandeiras (este roteiro e o GP podem ser obtidos através o e-mail suporte@softwareexpress.com.br)

Fluxograma de Funcionamento

O Gerenciador Padrão é um aplicativo Win32 que em sua execução ficará na zona de TaskService (ao lado do relógio do windows onde ficam todas as aplicações "residentes" que podem sofrer intervenção direta do usuário) e fica buscando arquivos em um diretório específico. Existe um GP para cada modalidade de transação. Na modalidade cartão de crédito existe o TEF_DIAL.exe e para a modalidade cartão de débito e cheque eletrônico existe o TEF_DISC.exe. Ambos buscam arquivos em diretórios respectivos, C:\TEF_DISC ou C:\TEF_DIAL, que devem ser criados dentro de um padrão. Toda a transação é realizada através de arquivos texto. Esses arquivos contém o texto que deve ser impresso no ECF. Exatamente o que é impresso nas "maquininhas" antigas é devolvido agora em arquivo para que sua aplicação manipule e imprima isso no ECF.

Nosso primeiro Exemplo será em verificar se o GP (Gerenciador Padrão) está presente ou não.

Em VB

Private Sub VerificaGP_Click()
{
 S_BufferGeral = "000-000 = ATV" + Chr(13) + Chr(10) + _
 "001-000 = " + "0000000001" + Chr(13) + Chr(10) + _
 "999-999 = 0"

 Open "C:\TEMPTEF.001" For Binary As #1
    Put #1, , S_BufferReq
 Close #1
 FileCopy "C:\TEMPTEF.001", "C:\TEF_DIAL\REQ\INTPOS.001" 
 Kill "C:\TEMPTEF.001"

 DARUMA_RET = Daruma_TEF_EsperarArquivo("C:\TEF_DIAL\RESP\INTPOS.STS", "10", "0")
 If(DARUMA_RET==1) then
  Msgbox "O Gerenciador Padrão Está Ativo"
 Else
  Msgbox "O Gerenciador Padrão Não está Ativo"
 End If
}

Em C#

private void VerificaGP_Click(object sender, System.EventArgs e)
{
string String_Tef;

string_Tef = "00-000 = ATV\r\n"; 
String_Tef +="001-000 = 0000000001\r\n"; 
String_Tef +=  "999-999 = 0";

FileStream Arquivo = new FileStream("C:\\TEFTEMP.TXT",FileMode.Create);
StreamWriter Escrever = new StreamWriter(Arquivo);
Escrever.Write(string_Tef);
Escrever.Close();
File.Copy("C:\\TEFTEMP.TXT", "C:\\TEF_DIAL\\RESP\\INTPOS.001",true);

DARUMA_RET = Daruma_TEF_EsperarArquivo("C:\\TEF_DIAL\\RESP\\INTPOS.STS", "10", "0");
If(DARUMA_RET==1
 MessageBox.show("O Gerenciador Padrão está Ativo");
Else
 MessageBox.show("O Gerenciador Padrão Não está Ativo");
}

Note que em ambos os casos o processo é o mesmo, criar o arquivo com o comando desejado (neste caso ATV), copiar o arquivo como comando para o diretório REQ e esperar a resposta do Gerenciador padrão que será a criação do arquivo de resposta no diretório RESP, neste caso você pode fazer uso da função DARUMA_TEF_EsperarArquivo onde o parâmetro desta função é o nome do arquivo que deseja esperar - incluindo o diretório - o tempo que deseja esperar em segundos e se deseja TRAVAR o teclado ou não.

A dll irá retornar 0(zero) se estourou o tempo e o arquivo não foi encontrado ou 1(um) se o arquivo foi encontrado.

Mas, agora que sabemos como é o funcionamento, vamos a uma operação de cartão de credito com o ECF, um cupom fiscal com pagamento em Cartão.

Em VB

Private Sub Cupom_Click()
 Daruma_RET = Daruma_FI_VendeItem("1234", "Leite", "FF", "F", "10", 2, "1,00", "%", "0")
  " COMENTADO Daruma_RET = Daruma_FI_FechaCupomResumido("Dinheiro", "Obrigado Volte Sempre!!")
  Daruma_RET = Daruma_FI_IniciaFechamentoCupom("A", "%", "0,00")
  
S_NumeroCupom = space(10) : S_ValorFormaPago = space(20)
Daruma_RET= Daruma_FI_NumeroCupom(S_NumeroCupom): 
Daruma_RET = Daruma_FI_SubTotal(S_ValorFormaPago)
S_BufferGeral = "000-000 = CRT" + Chr(13) + Chr(10) + _
"001-000 = " + "0000000001" + Chr(13) + Chr(10) + _
"002-000 = " + S_NumeroCupom + Chr(13) + Chr(10) + _
"003-000 = " + S_ValorFormaPago + Chr(13) + Chr(10) + _
"999-999 = 0"

 Open "C:\TEMPTEF.001" For Binary As #1
    Put #1, , S_BufferReq
 Close #1
 FileCopy "C:\TEMPTEF.001", "C:\TEF_DIAL\REQ\INTPOS.001"
 Kill "C:\TEMPTEF.001"

 DARUMA_RET = Daruma_TEF_EsperarArquivo("C:\TEF_DIAL\RESP\INTPOS.001", "10", "0")
 If(DARUMA_RET==1) then
   Daruma_RET = Daruma_FI_EfetuaFormaPagametno("Dinheiro", "10,00")
   Daruma_RET = _
     Daruma_FI_IndentificaConsumidor("Claudenir Campos Andrade", _
     "Blábláblá", "123456 Texto")
   Daruma_RET = Daruma_TerminaFechamentoCupom("Obrigado Volte Sempre!!")
   "Imprime o TEF no Comprovante Não Fiscal Vinculado
   DARUMA_RET = Daruma_TEF_ImprimirResposta("C:\TEF_DIAL\RESP\INTPOS.001", "Cartão", "1") 
   "se for <>1 é porque a impressora foi desligada no meio da Impressão
   If(DARUMA_RET<>1) then 
      DARUMA_RET = Daruma_TEF_ImprimirResposta("C:\TEF_DIAL\RESP\INTPOS.001", "", "1") 
   end if
   Daruma_RET = Daruma_TEF_FechaRelatorio()
Else
  Msgbox "Problemas com TEF, Favor escolher outra forma  Pagamento"
  ....
End If

End Sub

EM C#

private void Cupom_Click(object sender, System.EventArgs e)
{
 DARUMA32.RET = DARUMA32.Daruma_FI_VendeItem("12345","Leite","0001","I","10",2,"10,00","%","000");
 // COMENTADO DARUMA32.Daruma_FI_FechaCupomResumido("Cheque","Espero que Funcione");
 DARUMA32.RET = DARUMA32.Daruma_FI_IniciaFechamentoCupom("A", "%", "0,00");
 DARUMA32.RET = DARUMA32.Daruma_FI_NumeroCupom(S_NumeroCupom);
 DARUMA32.RET = DARUMA32.Daruma_FI_SubTotal(S_ValorFormaPagp);
 
String_Tef= "000-000 = CRT\r\n";
String_Tef+="001-000 = 0000000001\r\n";
String_Tef+="002-000 = "+S_NumeroCupom+"\r\n";
String_Tef+="003-000 = "+S_ValorFormaPago+"\r\n";
String_Tef+="999-999 = 0";

 FileStream Arquivo = new FileStream("C:\\TEFTEMP.TXT",FileMode.Create);
StreamWriter Escrever = new StreamWriter(Arquivo);
Escrever.Write(string_Tef);
Escrever.Close();
 File.Copy("C:\\TEFTEMP.TXT", "C:\\TEF_DIAL\\RESP\\INTPOS.001",true);
 DARUMA32_RET = Daruma_TEF_EsperarArquivo("C:\\TEF_DIAL\\RESP\\INTPOS.STS", "10", "0");
 If(DARUMA32_RET==1)
 {
  DARUMA32.RET = DARUMA32.Daruma_FI_EfetuaFormaPagametno("Cartão", "10,00");
  DARUMA32.RET = 
    DARUMA32.Daruma_FI_IndentificaConsumidor("Claudenir Andrade", 
    "Blábláblá", "123456 Texto");
  DARUMA32.RET = DARUMA32.Daruma_TerminaFechamentoCupom("Obrigado Volte Sempre!! ");

   "Imprime o TEF no Comprovante Não Fiscal Vinculado
   DARUMA32.RET = 
    DARUMA32.Daruma_TEF_ImprimirResposta("C:\\TEF_DIAL\\RESP\I\NTPOS.001", "Cartão", "1") 
  
  "se for <>1 é porque a impressora foi desligada no meio da Impressão 
  If(DARUMA32_RET<>1) then 
      DARUMA32.RET = 
	DARUMA32.Daruma_TEF_ImprimirResposta("C:\\TEF_DIAL\\RESP\\INTPOS.001", "", "1") 

   DARUMA32.RET = DARUMA32.Daruma_TEF_FechaRelatorio()
 }
 Else
   MessageBox.Show ("Probelmas ao Imprimir o TEF");
   ...
}

O Objetivo de ambos os códigos acima é demonstrar as facilidades oferecidas pela DARUMA32.DLL com o TEF.

Observem a existência da função Daruma_TEF_EsperarArquivo onde você passa o caminha completo do arquivo com o nome e o tempo em MiliSegundos que deseja esperar, isso desonera o software e o desenvolvedor de criar um timer só pra esperar este arquivo.

Outra funcionalidade que a DARUMA32.DLL possui para o TEF é a questão da Impressão da resposta para o TEF, porque enquanto a Resposta do TEF está sendo impressa o que acontece na Homologação é o desligamento do ECF, ou seja, o software deve tratar se o ECF esta desligado ou não e verificar se o desligamento aconteceu no momento da impressão do TEF.

Com a Função DARUMA_TEF_ImprimirResposta isso não é necessário, porque esta função irá devolver 0(zero) ou 1(um) caso a impressão tenha sido completa ou não, ou seja, se esta função devolver algum valor Diferente de 1(UM) então é porque a resposta não foi totalmente impressa e existirá a necessidade de imprimir o TEF novamente em um Relatório Gerencial, mas também não se preocupe com isso porque basta chamar a função DARUMA_TEF_ImprimirResposta, sem indicar a forma de pagamento - passando o valor vazio neste parâmetro - que a própria função irá fechar o comprovante Não Fiscal Vinculado e abrir um Relatório Gerencial e imprimir a resposta novamente no Gerencial. Não se preocupe também em fechar o Comprovante Não Fiscal Vinculado ou o Gerencial, chame a Função DARUMA_TEF_FechaRelatorio que a própria função se encarrega de saber quem é que está aberto - se é um Gerencial ou um Vinculado - e a própria função envia o comando correspondente.

Pagamento de Prestações com TEF

Muito se comenta sobre como efetuar o pagamento de uma prestação em cartão de credito. Vamos imaginar que foi efetuado uma compra no valor de R$100 reais, em 4 x 25,00.

No ato da compra da mercadoria deve-se emitir o cupom fiscal, no momento da compra, porém no pagamento da primeira prestação é lógico que não se emitira um cupom fiscal novamente até porque se isso acontecer o estabelecimento comercial estará debitando ICMS duplamente.

Por isso, aqui vai uma dica, independente de for pagamento em cartão ou pagamento em dinheiro, as prestações referentes a uma compra já realizada, as prestações referentes a um cupom já emitido devem ser recebidas na impressora fiscal como Valores NÃO FISCAIS, utilizando-se do Comprovante Não Fiscal Não Vinculado (antigo Recebimento Não Sujeito ao ICMS).

O Comprovante Não Fiscal Não Vinculado é um Cupom que permite receber valores que não tenham relacionamento com o cupom fiscal diretamente, como no caso de recebimento de contas de Água, Luz, Telefone e prestações de cupons fiscais já emitidos como é nosso exemplo. Vamos ao Código de como isso é feito, imaginando que o cupom já foi emitido e que o cliente estará pagando a primeira prestação, por exemplo, de R$25,00 Reais.

Em VB

....
  Daruma_RET = Daruma_RecebimentoNaoFiscal("03", "25,00",  "Dinheiro")

Em C#

   ...
  DARUMA32.RET = DARUMA32.Daruma_RecebimentoNaoFiscal("03", "25,00",  "Dinheiro");

Simplesmente com a chamada desta função você terá impresso em seu ECF um pequeno cupom não fiscal vinculado que conterá o valor de R$25,00 reais, pago em Dinheiro do Índice 03(três). Este índice deve ser previamente cadastrado no ECF, ou seja, antes de iniciar o dia, ou na primeira vez que o ECF esta sendo Lacrado você deve cadastrar os chamados "Totalizadores Não Fiscais", onde cada um terá um Índice e um Nome, em nosso exemplo utilizei-me do Índice 03 que em meu ECF está cadastrado como "Prestação". Você poderá cadastrar até 19 Totalizadores Não Fiscais.

Neste nosso exemplo acima o que fizemos foi receber uma prestação em dinheiro no valor de R$25,00. Imaginando que esta operação fosse paga em Cartão, teremos que proceder todos os passos relativos a operação com cartão, criar arquivo..esperar resposta...imprimir a resposta em um NaoFiscalVinculado, etc.

Em VB

....
 
S_NumeroCupom = space(10) : S_ValorFormaPago = space(20)
Daruma_RET= Daruma_FI_NumeroCupom(S_NumeroCupom): 
Daruma_RET = Daruma_FI_SubTotal(S_ValorFormaPago)
S_BufferGeral = "000-000 = CRT" + Chr(13) + Chr(10) + _
"001-000 = " + "0000000001" + Chr(13) + Chr(10) + _
"002-000 = " + S_NumeroCupom + Chr(13) + Chr(10) + _
"003-000 = " + S_ValorFormaPago + Chr(13) + Chr(10) + _
"999-999 = 0"

 Open "C:\TEMPTEF.001" For Binary As #1
    Put #1, , S_BufferReq
 Close #1
 FileCopy "C:\TEMPTEF.001", "C:\TEF_DIAL\REQ\INTPOS.001"
 Kill "C:\TEMPTEF.001"

 DARUMA_RET = Daruma_TEF_EsperarArquivo("C:\TEF_DIAL\RESP\INTPOS.001", "10", "0")
 If(DARUMA_RET==1) then
   Daruma_RET = Daruma_RecebimentoNaoFiscal("03", "25,00",  "Cartão")
   "Imprime o TEF no Comprovante Não Fiscal Vinculado
   DARUMA_RET = Daruma_TEF_ImprimirResposta("C:\TEF_DIAL\RESP\INTPOS.001", "Cartão", "1") 
	 "se for <>1 é porque a impressora foi desligada no meio da Impressão
   If(DARUMA_RET<>1) then 
      DARUMA_RET = Daruma_TEF_ImprimirResposta("C:\TEF_DIAL\RESP\INTPOS.001", "", "1") 
   end if
   Daruma_RET = Daruma_TEF_FechaRelatorio()
Else
  Msgbox "Problemas com TEF, Favor escolher outra forma  Pagamento"

Em C#

   ...
 DARUMA32.RET = DARUMA32.Daruma_FI_NumeroCupom(S_NumeroCupom);
 DARUMA32.RET = DARUMA32.Daruma_FI_SubTotal(S_ValorFormaPagp);
 
String_Tef= "000-000 = CRT\r\n";
String_Tef+="001-000 = 0000000001\r\n";
String_Tef+="002-000 = "+S_NumeroCupom+"\r\n";
String_Tef+="003-000 = "+S_ValorFormaPago+"\r\n";
String_Tef+="999-999 = 0";

 FileStream Arquivo = new FileStream("C:\\TEFTEMP.TXT",FileMode.Create);
StreamWriter Escrever = new StreamWriter(Arquivo);
Escrever.Write(string_Tef);
Escrever.Close();
 File.Copy("C:\\TEFTEMP.TXT", "C:\\TEF_DIAL\\RESP\\INTPOS.001",true);

 DARUMA32_RET = Daruma_TEF_EsperarArquivo("C:\\TEF_DIAL\\RESP\\INTPOS.STS", "10", "0");
 If(DARUMA32_RET==1)
   { DARUMA32.RET = DARUMA32.Daruma_RecebimentoNaoFiscal("03", "25,00",  "Cartão");
     DARUMA32.RET = 
       DARUMA32.Daruma_TEF_ImprimirResposta( _
       "C:\\TEF_DIAL\\RESP\I\NTPOS.001", "Cartão", "1") 
     "se for <>1 é porque a impressora foi desligada no meio da Impressão
     If(DARUMA32_RET<>1) then 
      DARUMA32.RET = 
	DARUMA32.Daruma_TEF_ImprimirResposta( _
        "C:\\TEF_DIAL\\RESP\\INTPOS.001", "", "1") 

   DARUMA32.RET = DARUMA32.Daruma_TEF_FechaRelatorio()
 }
Else
  MessageBox.Show("Problemas com TEF, escolha outra forma  pagamento para o Não Fiscal");
....

Notou a diferença entre este código e o código de emissão de tef com o cupom fiscal? Nenhuma diferença verdade? Porque o mesmo processo de TEF, esperar resposta...imprimir no vinculado...fechar o relatório, etc.. tudo isso é idêntico seja para o pagamento de um cupom fiscal seja para o pagamento de uma prestação em comprovante não fiscal não vinculado (antigo recebimento não sujeito ao ICMS).

A Única diferença é que no caso do cupom fiscal o TEF é feito com o cupom fiscal aberto, exatamente antes de enviar a forma de Pagamento para o ECF, por quê? Porque se a resposta da Operadora não acontecer você ainda estará com a chance de trocar a forma de pagamento e efetuar o encerramento do cupom fiscal.

No caso do Recebimento de uma prestação TEF, primeiro você realiza toda a operação de TEF, e somente após isso é que você irá efetuar o recebimento do valor, uma vez que a resposta da Operadora estiver acontecido,isso porque o recebimento de valores não fiscais - como nosso exemplo de 25,00 Reais - acontece de uma única vez, não existe abertura, recebimento e comando de fechamento é um único comando que faz tudo isso.

Claro que existe outros procedimentos para o TEF que não descrevemos aqui, como por exemplo, ao receber a resposta do TEF verificar se o mesmo contém o campo indicando que o cartão está Autorizado, e somente neste caso o TEF poderá ser impresso.

O Código fonte completo em VB e C# com todas as rotinas você poderá baixar no site www.daruma.com.br (exemploVBTEF.ZIP e exemploC#Tef.ZIP) ou solicitar ao suporte para desenvolvedores DARUMA - suporte@daruma.com.br ou s.borges@daruma.com.br.

Claudenir Andrade

Claudenir Andrade - Formado pela Academia de Sistemas Informáticos de Madrid, trabalha com automação comercial há nove anos, foi responsável pela Homologação e aprovação de ECFs brasileiros em países como Equador e Venezuela, gerencia a equipe de desenvolvimento da Daruma Automação. Autor do primeiro livro de automação comercial no Brasil - "Automação Comercial com VB.Net e C#", é também MVP da Microsoft e está criando e definindo o Modelo XML para Automação Comercial, escreve artigos também para o site MSDN e pode ser contatado pelo e-mail - claudenir@daruma.com.br