30 dias com o WebService da GINFES

Em julho de 2012 fui convidado para desenvolver um aplicativo consumidor de um WebService para produção de Notas Fiscais de Serviço Eletrônicas (NFS-e). A questão é que, mesmo conhecendo o Delphi e seus recursos, eu ainda não tinha experiência com desenvolvimento de aplicativos para acesso de WebServices e com documentos fiscais eletrônicos. A saída foi obter o máximo de informações na internet e com outros profissionais para que o desenvolvimento não ficasse engessado.

WebService da GINFES

WebService é o nome dado a uma tecnologia que permite a integração de diferentes aplicações pela internet por meio de arquivos XML. A grande vantagem de se utilizar um WebService é a agilidade na comunicação, bem como uma padronização dos serviços disponibilizados. O objetivo é automatizar o processamento de um pacote de dados e receber a resposta de forma rápida.

Um bom exemplo de um WebService é a consulta de logradouros através do site dos Correios. Acho que você já deve ter conhecido algum sistema onde o usuário digita o CEP do cliente e todos os dados do endereço são automaticamente preenchidos. Pois então, no momento que o usuário digita o CEP, o sistema faz uma comunicação com o site dos Correios através de um WebService, informando apenas o CEP dentro de um arquivo XML.

A empresa que mantém a funcionalidade do WebService da Prefeitura de Ribeirão Preto é a GINFES, que também atua em outros municípios.

WebService no Delphi

Para consumir um WebService pelo Delphi, o primeiro passo é obter o endereço WSDL, fornecido pela própria empresa que mantém o WebService ativo. O Delphi, desde a versão 7, dispõe de uma ferramenta nativa para importação de endereços WSDL, chamado WSDL Importer:

Ferramenta WSDL Importer do Delphi

Essa ferramenta trata de interpretar o endereço WSDL (ou arquivo WSDL, caso seja baixado para o computador), e criar uma unit com o cabeçalho das funções disponibilizadas pelo WebService, prontas para serem chamadas. O WebService da GINFES, por exemplo, fornece quatro funções: envio de RPS, consulta de lote, consulta de NFS-e e cancelamento de NFS-e. Que bom, já veio tudo pronto! Então, só preciso chamar a função e passar os parâmetros necessários! Espere aí… eu disse “parâmetros”?

Sim. As funções do WebService exigem que um arquivo XML seja obrigatoriamente passado como parâmetro, obedecendo uma estrutura pré-definida pelos desenvolvedores do WebService. Como já sabemos, um arquivo XML consiste em uma hierarquia de tags (que lembram HTML) para armazenar valores.

A GINFES disponibiliza alguns arquivos conhecidos como XML Schema (com extensão XSD) para definição de regras de validação, ou seja, o desenvolvedor deve seguir essas regras para que o WebService receba e processe o arquivo XML corretamente. Após aplicar essas regras, é possível validar a estrutura final do arquivo XML pelo site do W3C.

Exemplo de arquivo XSDExemplo de um arquivo XSD

Bom, agora nós temos o endereço do WebService e a forma como o arquivo XML deve ser criado, então já podemos utilizar as funções, certo? Ainda não.

Certificado Digital

Como se trata de uma operação fiscal, é necessário que o usuário tenha em mãos um Certificado Digital – dispositivo ou arquivo que contém informações sobre entidade emissora (como se fosse o CPF de uma Pessoa Física) – no qual se divide em dois padrões:

  • A1: arquivo de computador
  • A3: dispositivo portátil (cartão ou token USB)

Certificado Digital A3Certificado Digital do tipo A3

Apesar da segurança em transferir o arquivo utilizando um Certificado Digital, o WebService ainda exige que o arquivo XML seja digitalmente assinado. Uma Assinatura Digital, em breves palavras, trata-se de uma garantia de que a empresa (emissora do arquivo) é autêntica e que o arquivo gerado é válido. Para ficar mais fácil de entender, pense em um contrato qualquer que exija a assinatura do contratante. Sem a assinatura o contrato não tem validade, correto? Da mesma forma, se o arquivo XML não for assinado, também não terá validade e não poderá ser processado.

DLL da FlexDocs

Eis que esse foi um dos meus grandes desafios: descobrir como assinar um arquivo pelo Delphi. Passei horas ligando para outros profissionais e tentando descobrir algo na internet, até que finalmente encontrei um site que fazia referência a uma empresa especializada em documentos eletrônicos: A FlexDocs. Após vários contatos, a empresa me disponibilizou uma DLL com uma série de funções, entre elas a geração da Assinatura Digital.

Para utilizar essa DLL no Delphi, primeiramente é preciso importá-la através do menu Component > Import Component. Ao abrir a janela de importação, deve-se selecionar opção Import a Type Library e clicar em Next. A próxima tela exibe todas as bibliotecas já registradas no Delphi. Para registrar uma nova biblioteca, clique em Add e carregue a DLL. Seguindo estes passos finalmente consegui criar uma unit com as funções da DLL para gerar a assinatura digital no arquivo.

Troubleshooting

O próximo passo era começar a realizar os testes.

Como tudo na informática não funciona da primeira vez, no meu caso não foi diferente, haha. Recebi diversas mensagens acusando erros na estrutura do arquivo (o famoso código E160) e outros erros relacionados à validação dos campos, como valores de impostos, descontos e caracteres especiais na descrição do item. O tamanho do campo também é uma restrição do WebService, e foi um dos problemas que me arrancou os cabelos até descobrir que o endereço do tomador estava com dois caracteres excedidos no tamanho.

Ao realizar os testes, me deparei com mais um imprevisto: o arquivo XML era enviado ao WebService e permanecia em uma fila de espera por aproximadamente 20 segundos até que fosse processado. A solução foi programar o aplicativo para aguardar este tempo e realizar uma consulta do lote enviado. Dessa forma, o aplicativo poderia obter o número da NFS-e gerada automaticamente, ótimo! O problema é que em horários de pico este tempo é variável, dependendo da quantidade de arquivos na fila a serem processados. Quando isso ocorria, eu recebia o código E4 indicando que o RPS (arquivo) não foi processado. Portanto, tive que pensar em outra solução.

Logo, ao invés de aguardar apenas 20 segundos, decidi mover a linha de consulta do lote para dentro de um laço de repetição. Se o aplicativo recebesse o código E4, a consulta era feita novamente, caso contrário o arquivo foi processado com sucesso. Apesar de parecer simples, devo assumir que deu um trabalhão, haha.

Resultado

Infelizmente me desliguei da empresa, mas o aplicativo ainda continua sendo utilizado. Desenvolver este aplicativo foi uma grande experiência, embora eu acredite que muitos também já passaram por isso, haha. Aproveitando este artigo, gostaria de agradecer ao Elton Welsch do suporte da GINFES por atender minhas inúmeras ligações, a empresa FlexDocs pela atenção e pela disponibilização da DLL, e também a Maria Rita, Product Owner que me guiou no desenvolvimento deste aplicativo.

Bom, e no fim das contas, o resultado foi este:

Informativo SMARAPD sobre a utilização de WebService no sistema SMARaa

 

Ainda está encontrando dificuldades sobre este assunto? Confiira o FAQ do WebService da GINFES aqui no blog.

Abraços e até a próxima!


 

André Celestino