Consumindo Serviços da NF-e com WCF

Todas as empresas, quando vendem uma mercadoria são obrigadas a emitir nota fiscal. Até pouco tempo atrás, as notas não eram padronizadas e cada empresa utilizava em modelo diferente. O governo decidiu então criar um mecanismo para que fosse possível a emissão de forma eletrônica.

Com isso cada estado brasileiro criou uma porção de web services que permite a emissão, autorização, cancelamento, consulta de status, etc. Como é possível perceber nas URLs dos serviços, eles utilizam o ASP.NET Web Services (ASMX) para expor estas funcionalidades.

Como sabemos, o WCF é o pilar de comunicação dentro do .NET Framework, e mantém compatibilidade com os antigos serviços desenvolvidos em ASMX. Isso quer dizer que é possível consumir estes serviços com a API do WCF. Para que isso seja possível, alguns cuidados precisam ser tomados para garantir que o acesso será permitido.

Os serviços são protegidos e para acessá-los é necessário apresentar um certificado digital válido. Os certificados podem ser adquiridos por entidades certificadores, tais como Serasa, Certsign, VeriSign, etc. E vale dizer que até mesmo o WSDL, documento que descreve as funcionalidades do serviço, também está protegido, e precisamos também apresentar um certificado para simplesmente adicionar a referência no Visual Studio.

Vale lembrar que existem alguns tipos de certificados, e no meu caso, estou utilizando um certifcado de cartão A3 (e-CNPJ) que está protegido por um PIN (senha) que é necessário informá-la sempre que o certificado está prestes a ser utilizado. Como estou com ele devidamente instalado, ao acessar a URL do serviço no navegador, já aparece uma lista com os possíveis certificados, assim como podemos notar na imagem abaixo. Uma vez que o certificado é escolhido, então a senha será exigida e, consequentemente, teremos acesso à página padrão do ASP.NET que descreve o serviço.

Da mesma forma que acontece acima, o Visual Studio também exigirá o certificado ao realizar o “Add Service Reference“, e informando corretamente, o download do WSDL será realizado e a referência para o serviço será configurada. Atente-se aqui que não estamos utilizando a opção “Add Web Reference“, pois ela recorre a API antiga (SoapHttpClientProtocol) para acesso e não utiliza o WCF.

Apesar da ferramenta já criar uma configuração padrão, ela não é válida para o acesso. Precisamos ajustar para informar ao WCF que ele precisa utilizar um certificado antes de fazer a requisição ao serviço. Estamos optando por utilizar um binding customizado para que seja possível adequar a segurança e a serialização de acordo com as exigências da SEFAZ.

Entre as customizações, temos que utilizar a versão 1.2 do SOAP. Além disso, informar que o transporte será baseado em HTTPS e que é necessário um certificado do cliente para apresentar ao serviço para ter acesso ao recurso. A configuração do certificado é feita através de um behavior e associado ao endpoint do serviço. Abaixo temos o resumo do arquivo de configuração válido para realizar o acesso. Por questões de simplicidade, estou utilizando o serviço que retorna o status (operante ou não) dos demais serviços da SEFAZ.

<?xml version=”1.0″ encoding=”utf-8″ ?>
<configuration>
  <system.serviceModel>
    <bindings>
      <customBinding>
        <binding name=”NFe”>
          <textMessageEncoding messageVersion=”Soap12″ />
          <httpsTransport requireClientCertificate=”true” />
        </binding>
      </customBinding>
    </bindings>
    <behaviors>
      <endpointBehaviors>
        <behavior name=”NFe”>
          <clientCredentials>
            <clientCertificate storeName=”My”
                               storeLocation=”CurrentUser”
                               x509FindType=”FindBySubjectName”
                               findValue=”ISRAEL AECE ME:………”/>
          </clientCredentials>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <client>
      <endpoint address=”https://nfe.fazenda.sp.gov.br/ws/nfestatusservico2.asmx&#8221;
                binding=”customBinding”
                bindingConfiguration=”NFe”
                behaviorConfiguration=”NFe”
                contract=”ServiceReference1.NfeStatusServico2Soap12″
                name=”ServiceReference1.NfeStatusServico2Soap12″ />
    </client>
  </system.serviceModel>
</configuration>

Uma vez que a configuração está concluída, podemos acessar o serviço e visualizarmos o retorno. Note que o código C# nada sabe sobre as configurações de certificado. É importante ressaltar que como este certificado tem um PIN, um prompt irá aparecer automaticamente para a digitação do mesmo. Na sequencia é possível visualizar o resultado que foi devolvido pelo serviço.

using (var client = new NfeStatusServico2Soap12Client())
{
    var corpo = new XmlDocument();
    var mensagem = “<?xml version=”1.0″ encoding=”utf-8″ ?>” +
                “<consStatServ xmlns=”http://www.portalfiscal.inf.br/nfe&#8221; versao=”3.10″>” +
                “<tpAmb>1</tpAmb>” +
                “<cUF>35</cUF>” +
                “<xServ>STATUS</xServ>” +
                “</consStatServ>”;

    corpo.LoadXml(mensagem);

    var resultado = client.nfeStatusServicoNF2(new nfeStatusServicoNF2Request()
    {
        nfeCabecMsg = new nfeCabecMsg()
        {
            cUF = “35”,
            versaoDados = “3.10”
        },
        nfeDadosMsg = corpo
    });

    Console.WriteLine(resultado.nfeStatusServicoNF2Result.OuterXml);
}

<retConsStatServ versao=”3.10″ xmlns=”http://www.portalfiscal.inf.br/nfe”><tpAmb
>1</tpAmb><verAplic>SP_NFE_PL_008f</verAplic><cStat>107</cStat><xMotivo>Serviço
em Operaçao</xMotivo><cUF>35</cUF><dhRecbto>2015-03-19T08:31:31-03:00</dhRecbto>
<tMed>1</tMed></retConsStatServ>