Função em AdvPL para baixar XML de nota direto do SEFAZ

Olá pessoal…

Hoje vou mostrar uma função que baixa o XML de uma NFe direto do Sefaz utilizando um WebService.

Essa função, faz a conexão com o WebService e efetua o download do XML para dentro de uma pasta.

Ela foi desenvolvida por Súlivan Simões (o e-Mail dele consta na documentação da função abaixo). É necessário também criar alguns parâmetros na SX6, que estão documentados na função abaixo. Gostaria de agradecer ao Súlivan por disponibilizar o fonte, e autorizar o compartilhamento dele aqui no Terminal de Informação.

Caso ocorram erros de certificado CA, veja na documentação, os links disponíveis para tirar a dúvida.

Abaixo o código fonte desenvolvido:

#Include "Protheus.ch"
#Include "ApWebSrv.ch"
#Include "TopConn.ch"

/*/{Protheus.doc} zBxXML
Faz download do arquivo XML do site da sefaz usando a Chave da nota
@author Súlivan Simões Silva - Email: sulivansimoes@gmail.com
@since  08/03/2019
@version 1.0
@param cChaveNFe, caracter, chave da NFe à ser baixada da Sefaz 
@example zBxXML
@type function
@see Abaixo os links usados como referência para montagem da função
		Link 01 - http://tdn.totvs.com/display/tec/Classe+TWsdlManager
		Link 02 - http://tdn.totvs.com/display/tec/SOAP+1.1+e+SOAP+1.2
		Link 03 - http://tdn.totvs.com/display/tec/XmlParser		        
		Link 04 - http://www.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=iGDFY8YBs28=
	Dúvidas quanto a Parse:
		Link 01 - https://centraldeatendimento.totvs.com/hc/pt-br/articles/360022658731-MP-ADVPL-Peer-certificate-cannot-be-authenticated-with-given-CA-certificates
		Link 02 - http://tdn.totvs.com/display/tec/Acesso+a+Web+Services+que+exigem+certificados+de+CA
@obs Documentação feita e adaptações por Daniel Atilio
	Os parâmetros que devem ser criados na base são:
		MV_X_BXUF  - Código do Estado conforme IBGE ( https://www.oobj.com.br/bc/article/quais-os-c%C3%B3digos-de-cada-uf-no-brasil-465.html )
		MV_X_BXAMB - Indica o tipo de Ambiente, 1 = Produção, 2 = Homologação
		MV_X_BXCA  - Diretório do certificado "ca", por exemplo: \certs\000001_ca.pem
		MV_X_BXCER - Diretório do certificado "cert", por exemplo: \certs\000001_cert.pem
		MV_X_BXKEY - Diretório do certificado "key", por exemplo: \certs\000001_key.pem
		MV_X_BXPSW - Senha do Certificado
		MV_X_BXPRO - Tipo do Protocolo, 0=Descobre sozinho; 1=TLSv1; 2=SSLv2; 3=SSLv3
		MV_X_BXDIR - Diretório que será gerado os arquivos XML
@example Basta chamar a função passando a chave da nfe
	u_zBxXML("CHAVE_AAAAAAAAAAAAAAAAAAAAAAA")
	u_zBxXML("CHAVE_BBBBBBBBBBBBBBBBBBBBBBB")
	u_zBxXML("CHAVE_CCCCCCCCCCCCCCCCCCCCCCC")
/*/

User Function zBxXML(cChaveNFe)
	Local aArea	    := GetArea()
	Local lRet      := .T.
	Local cURL	    := "https://www1.nfe.fazenda.gov.br/NFeDistribuicaoDFe/NFeDistribuicaoDFe.asmx?WSDL"
	Local cMsg      := ""
	Local oWsdl     := Nil
	Local cMsgRet   := ""
	Local cError    := ""
	Local cWarning  := ""
	Local cXmlGZip  := ""
	Local cArqXML   := ""
	Local cUfAutor  := SuperGetMV("MV_X_BXUF",  .F., "35")
	Local cTpAmb    := SuperGetMV("MV_X_BXAMB", .F., "1")
	Local cCNPJEmp  := Alltrim(SM0->M0_CGC)
	Local lContinua := .T.
	Private oXmlDocZip

	//Instância a classe, setando as parâmetrizações necessárias
	oWsdl := TWsdlManager():New()
	oWsdl:cSSLCACertFile := SuperGetMV("MV_X_BXCA",  .F., "\certs\000001_ca.pem")
	oWsdl:cSSLCertFile   := SuperGetMV("MV_X_BXCER", .F., "\certs\000001_cert.pem")
	oWsdl:cSSLKeyFile    := SuperGetMV("MV_X_BXKEY", .F., "\certs\000001_key.pem")
	oWsdl:cSSLKeyPwd     := SuperGetMV("MV_X_BXPSW", .F., "senha")
	oWsdl:nSSLVersion    := SuperGetMV("MV_X_BXPRO", .F., "0")
	oWsdl:nTimeout       := 120

	//Tenta fazer o Parse da URL
	lRet := oWsdl:ParseURL(cURL)
	If ! lRet 
		ConOut("[u_zBxXML] - Erro ParseURL: " + oWsdl:cError)
		lContinua := .F.
	EndIf
	
	//Se for continuar o processamento
	If lContinua
	
		//Tenta definir a operação
		lRet := oWsdl:SetOperation("nfeDistDFeInteresse")
		If ! lRet 
			ConOut("[u_zBxXML] - Erro SetOperation: " + oWsdl:cError)
			lContinua := .F.
		EndIf
	EndIf
	
	//Se for continuar
	If lContinua
		//Monta a mensagem que será enviada
		cMsg := '<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">'                        + CRLF
		cMsg += '	<soapenv:Header/>'                                                                              + CRLF
		cMsg += '    <soapenv:Body>'                                                                                + CRLF
		cMsg += '        <nfeDistDFeInteresse xmlns="http://www.portalfiscal.inf.br/nfe/wsdl/NFeDistribuicaoDFe">'  + CRLF
		cMsg += '	            <nfeDadosMsg>'                                                                      + CRLF
		cMsg += '					<distDFeInt xmlns="http://www.portalfiscal.inf.br/nfe" versao="1.01">'          + CRLF
		cMsg += '						<tpAmb>'+cTpAmb+'</tpAmb>'                                                  + CRLF
		cMsg += ' 					<cUFAutor>'+cUfAutor+'</cUFAutor>'                                              + CRLF
		cMsg += '						<CNPJ>'+cCNPJEmp+'</CNPJ>'                                                  + CRLF
		cMsg += '  					<consChNFe>'                                                                    + CRLF
		cMsg += '   						<chNFe>'+alltrim(cChaveNFe)+'</chNFe>'                                  + CRLF
		cMsg += '  					</consChNFe>'                                                                   + CRLF
		cMsg += '					</distDFeInt>'                                                                  + CRLF
		cMsg += '	            </nfeDadosMsg>'                                                                     + CRLF
		cMsg += '	        </nfeDistDFeInteresse>'                                                                 + CRLF
		cMsg += '	    </soapenv:Body>'                                                                            + CRLF
		cMsg += '	</soapenv:Envelope>'                                                                            + CRLF
		
		//Envia uma mensagem SOAP personalizada ao servidor
		lRet := oWsdl:SendSoapMsg(cMsg)
		If ! lRet 
			ConOut("[u_zBxXML] - Erro SendSoapMsg: " + oWsdl:cError)
			ConOut("[u_zBxXML] - Erro SendSoapMsg FaultCode: " + oWsdl:cFaultCode)
			lContinua := .F.
		EndIf
	EndIf

	//Se for continuar
	If lContinua
		//Pega a resposta do SOAP
		cMsgRet := oWsdl:GetSoapResponse()
						   
		//Transforma a resposta em um objeto
		oXmlDocZip := XmlParser(cMsgRet, "_", @cError, @cWarning)
		
		//Se existir Warning, mostra no console.log
		If ! Empty(cWarning)
			ConOut("[u_zBxXML] - Alerta cWarning: " + cWarning)
		EndIf
		
		//Se houve erro, não permitirá prosseguir
		If ! Empty(cError)
			ConOut("[u_zBxXML] - Erro cError: " + cError)
			lContinua := .F.
		EndIf
	EndIf

	//Se for continuar
	If lContinua
		//Se a tag DocZip existir (for diferente de Undefinied)
		If (Type("oXmlDocZip:_SOAP_ENVELOPE:_SOAP_BODY:_NFEDISTDFEINTERESSERESPONSE:_NFEDISTDFEINTERESSERESULT:_RETDISTDFEINT:_LOTEDISTDFEINT:_DOCZIP") != "U")

			//Pega tag que contém XML em zip
			cXmlGZip := oXmlDocZip:_SOAP_ENVELOPE:_SOAP_BODY:_NFEDISTDFEINTERESSERESPONSE:_NFEDISTDFEINTERESSERESULT:_RETDISTDFEINT:_LOTEDISTDFEINT:_DOCZIP:TEXT
			
			//Gera arquivo XML
			cArqXML := fGeraXML(cXmlGZip, cChaveNFe)
		else
			conout("[u_zBxXML] - Ocorreu algum problema no momento de baixar o arquivo da sefaz!")
		endif
	EndIf

	RestArea(aArea)
Return cArqXML

/*-------------------------------------------------------------------------------*
 | Func:  fGeraXML                                                               |
 | Desc:  Função para gerar o arquivo XML em uma pasta                           |
 *-------------------------------------------------------------------------------*/

Static Function fGeraXML(cConteudo, cChave)
	Local aArea   	 := getArea()
	Local lRet    	 := .T. 
	Local cArquivo	 := cChave + ".xml"
	Local cDiretorio := Alltrim(SuperGetMV("MV_X_BXDIR", .F., "C:\TOTVS\XML\"))
	Local nTamanho	 := 0
	Local cUnXML  	 := "" 
	Local cDecode64  := ""
	Local cArqFull   := ""
	Local lHouveErro := .F.
	
	//Se o último caracter do diretório não for \, será barra \
	If SubStr(cDiretorio, Len(cDiretorio), 1) != "\"
		cDiretorio += "\"
	EndIf
	
	//Define o caminho final do arquivo
	cArqFull := cDiretorio + cArquivo
	
	//Pega o tamanho e descriptografa o conteúdo
	nTamanho  := Len(cConteudo)
	cDecode64 := Decode64(cConteudo)
	lRet      := GzStrDecomp(cDecode64, nTamanho, @cUnXML)
     
    //Se deu certo
	If lRet
		
		//Se o diretório não existir, cria
		If ! ExistDir(cDiretorio)
			MakeDir(cDiretorio)
		EndIf
		
		//Cria o arquivo com o conteúdo
		lRet := MemoWrite(cDiretorio+cArquivo, cUnXML)
		
		//Se houve falha, mostra mensagem no console.log
		If ! lRet
			ConOut("[u_zBxXML][fGeraXML] - Não foi possivel criar o arquivo: " + cArqFull)
			lHouveErro := .T.
		EndIf
	
	//Se não deu certo, mostra mensagem no console.log
	Else
		ConOut("[u_zBxXML][fGeraXML] - Houve algum erro na descompactação do arquivo!")
		lHouveErro := .T.
	EndIf

	//Se houve erro, zera o nome do arquivo para retornar em branco
	If lHouveErro
		cArqFull := ""
	EndIf

	RestArea(aArea)
Return cArqFull

Atualização 07/08/2019

Foi criado o parâmetro MV_X_SSLIN, para tratativas do Parse. Além disso, também foi alterado a forma de buscar dados da SM0, por causa do Lobo Guará. Segue abaixo o fonte revisado:

#Include "Protheus.ch"
#Include "ApWebSrv.ch"
#Include "TopConn.ch"
 
/*/{Protheus.doc} zBxXML
Faz download do arquivo XML do site da sefaz usando a Chave da nota
@author Súlivan Simões Silva - Email: sulivansimoes@gmail.com
@since  08/03/2019
@version 1.1
@param cChaveNFe, caracter, chave da NFe à ser baixada da Sefaz 
@example zBxXML
@type function
@see Abaixo os links usados como referência para montagem da função
        Link 01 - http://tdn.totvs.com/display/tec/Classe+TWsdlManager
        Link 02 - http://tdn.totvs.com/display/tec/SOAP+1.1+e+SOAP+1.2
        Link 03 - http://tdn.totvs.com/display/tec/XmlParser                
        Link 04 - http://www.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=iGDFY8YBs28=
    Dúvidas quanto a Parse:
        Link 01 - https://centraldeatendimento.totvs.com/hc/pt-br/articles/360022658731-MP-ADVPL-Peer-certificate-cannot-be-authenticated-with-given-CA-certificates
        Link 02 - http://tdn.totvs.com/display/tec/Acesso+a+Web+Services+que+exigem+certificados+de+CA
		Link 03 - http://tdn.totvs.com/pages/viewpage.action?pageId=223932805
		Link 04 - http://tdn.totvs.com/display/tec/TWsdlManager%3AlSSLInsecure
@obs Documentação feita e adaptações por Daniel Atilio
    Os parâmetros que devem ser criados na base são:
        MV_X_BXUF  - Código do Estado conforme IBGE ( https://www.oobj.com.br/bc/article/quais-os-c%C3%B3digos-de-cada-uf-no-brasil-465.html )
        MV_X_BXAMB - Indica o tipo de Ambiente, 1 = Produção, 2 = Homologação
        MV_X_BXCA  - Diretório do certificado "ca", por exemplo: \certs\000001_ca.pem
        MV_X_BXCER - Diretório do certificado "cert", por exemplo: \certs\000001_cert.pem
        MV_X_BXKEY - Diretório do certificado "key", por exemplo: \certs\000001_key.pem
        MV_X_BXPSW - Senha do Certificado
        MV_X_BXPRO - Tipo do Protocolo, 0=Descobre sozinho; 1=TLSv1; 2=SSLv2; 3=SSLv3
        MV_X_BXDIR - Diretório que será gerado os arquivos XML
		MV_X_SSLIN - Define se fará a conexão SSL com o servidor de forma anônima, ou seja, sem verificação de certificados ou chaves. Default é .T.
@example Basta chamar a função passando a chave da nfe
    u_zBxXML("CHAVE_AAAAAAAAAAAAAAAAAAAAAAA")
    u_zBxXML("CHAVE_BBBBBBBBBBBBBBBBBBBBBBB")
    u_zBxXML("CHAVE_CCCCCCCCCCCCCCCCCCCCCCC")
/*/
 
User Function zBxXML(cChaveNFe)
    Local aArea        := GetArea()
    Local lRet      := .T.
    Local cURL        := "https://www1.nfe.fazenda.gov.br/NFeDistribuicaoDFe/NFeDistribuicaoDFe.asmx?WSDL"
    Local cMsg      := ""
    Local oWsdl     := Nil
    Local cMsgRet   := ""
    Local cError    := ""
    Local cWarning  := ""
    Local cXmlGZip  := ""
    Local cArqXML   := ""
    Local cUfAutor  := SuperGetMV("MV_X_BXUF",  .F., "35")
    Local cTpAmb    := SuperGetMV("MV_X_BXAMB", .F., "1")
    Local cCNPJEmp  := Alltrim(Alltrim(FWArrFilAtu(FWCodEmp(),FWCodFil())[18]))
    Local lContinua := .T.
    Private oXmlDocZip
 
    //Instância a classe, setando as parâmetrizações necessárias
    oWsdl := TWsdlManager():New()
    oWsdl:cSSLCACertFile := SuperGetMV("MV_X_BXCA",  .F., "\certs\000001_ca.pem")
    oWsdl:cSSLCertFile   := SuperGetMV("MV_X_BXCER", .F., "\certs\000001_cert.pem")
    oWsdl:cSSLKeyFile    := SuperGetMV("MV_X_BXKEY", .F., "\certs\000001_key.pem")
    oWsdl:cSSLKeyPwd     := SuperGetMV("MV_X_BXPSW", .F., "senha")
    oWsdl:nSSLVersion    := SuperGetMV("MV_X_BXPRO", .F., "0")
	oWsdl:lSSLInsecure   := SuperGetMV("MV_X_SSLIN", .F., .T.)
    oWsdl:nTimeout       := 120
 
    //Tenta fazer o Parse da URL
    lRet := oWsdl:ParseURL(cURL)
    If ! lRet 
        ConOut("[u_zBxXML] - Erro ParseURL: " + oWsdl:cError)
        lContinua := .F.
    EndIf
     
    //Se for continuar o processamento
    If lContinua
     
        //Tenta definir a operação
        lRet := oWsdl:SetOperation("nfeDistDFeInteresse")
        If ! lRet 
            ConOut("[u_zBxXML] - Erro SetOperation: " + oWsdl:cError)
            lContinua := .F.
        EndIf
    EndIf
     
    //Se for continuar
    If lContinua
        //Monta a mensagem que será enviada
        cMsg := '<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">'                        + CRLF
        cMsg += '    <soapenv:Header/>'                                                                              + CRLF
        cMsg += '    <soapenv:Body>'                                                                                + CRLF
        cMsg += '        <nfeDistDFeInteresse xmlns="http://www.portalfiscal.inf.br/nfe/wsdl/NFeDistribuicaoDFe">'  + CRLF
        cMsg += '                <nfeDadosMsg>'                                                                      + CRLF
        cMsg += '                    <distDFeInt xmlns="http://www.portalfiscal.inf.br/nfe" versao="1.01">'          + CRLF
        cMsg += '                        <tpAmb>'+cTpAmb+'</tpAmb>'                                                  + CRLF
        cMsg += '                     <cUFAutor>'+cUfAutor+'</cUFAutor>'                                              + CRLF
        cMsg += '                        <CNPJ>'+cCNPJEmp+'</CNPJ>'                                                  + CRLF
        cMsg += '                      <consChNFe>'                                                                    + CRLF
        cMsg += '                           <chNFe>'+alltrim(cChaveNFe)+'</chNFe>'                                  + CRLF
        cMsg += '                      </consChNFe>'                                                                   + CRLF
        cMsg += '                    </distDFeInt>'                                                                  + CRLF
        cMsg += '                </nfeDadosMsg>'                                                                     + CRLF
        cMsg += '            </nfeDistDFeInteresse>'                                                                 + CRLF
        cMsg += '        </soapenv:Body>'                                                                            + CRLF
        cMsg += '    </soapenv:Envelope>'                                                                            + CRLF
         
        //Envia uma mensagem SOAP personalizada ao servidor
        lRet := oWsdl:SendSoapMsg(cMsg)
        If ! lRet 
            ConOut("[u_zBxXML] - Erro SendSoapMsg: " + oWsdl:cError)
            ConOut("[u_zBxXML] - Erro SendSoapMsg FaultCode: " + oWsdl:cFaultCode)
            lContinua := .F.
        EndIf
    EndIf
 
    //Se for continuar
    If lContinua
        //Pega a resposta do SOAP
        cMsgRet := oWsdl:GetSoapResponse()
                            
        //Transforma a resposta em um objeto
        oXmlDocZip := XmlParser(cMsgRet, "_", @cError, @cWarning)
         
        //Se existir Warning, mostra no console.log
        If ! Empty(cWarning)
            ConOut("[u_zBxXML] - Alerta cWarning: " + cWarning)
        EndIf
         
        //Se houve erro, não permitirá prosseguir
        If ! Empty(cError)
            ConOut("[u_zBxXML] - Erro cError: " + cError)
            lContinua := .F.
        EndIf
    EndIf
 
    //Se for continuar
    If lContinua
        //Se a tag DocZip existir (for diferente de Undefinied)
        If (Type("oXmlDocZip:_SOAP_ENVELOPE:_SOAP_BODY:_NFEDISTDFEINTERESSERESPONSE:_NFEDISTDFEINTERESSERESULT:_RETDISTDFEINT:_LOTEDISTDFEINT:_DOCZIP") != "U")
 
            //Pega tag que contém XML em zip
            cXmlGZip := oXmlDocZip:_SOAP_ENVELOPE:_SOAP_BODY:_NFEDISTDFEINTERESSERESPONSE:_NFEDISTDFEINTERESSERESULT:_RETDISTDFEINT:_LOTEDISTDFEINT:_DOCZIP:TEXT
             
            //Gera arquivo XML
            cArqXML := fGeraXML(cXmlGZip, cChaveNFe)
        else
            conout("[u_zBxXML] - Ocorreu algum problema no momento de baixar o arquivo da sefaz!")
        endif
    EndIf
 
    RestArea(aArea)
Return cArqXML
 
/*-------------------------------------------------------------------------------*
 | Func:  fGeraXML                                                               |
 | Desc:  Função para gerar o arquivo XML em uma pasta                           |
 *-------------------------------------------------------------------------------*/
 
Static Function fGeraXML(cConteudo, cChave)
    Local aArea        := getArea()
    Local lRet         := .T. 
    Local cArquivo     := cChave + ".xml"
    Local cDiretorio := Alltrim(SuperGetMV("MV_X_BXDIR", .F., "C:\TOTVS\XML\"))
    Local nTamanho     := 0
    Local cUnXML       := ""
    Local cDecode64  := ""
    Local cArqFull   := ""
    Local lHouveErro := .F.
     
    //Se o último caracter do diretório não for \, será barra \
    If SubStr(cDiretorio, Len(cDiretorio), 1) != "\"
        cDiretorio += "\"
    EndIf
     
    //Define o caminho final do arquivo
    cArqFull := cDiretorio + cArquivo
     
    //Pega o tamanho e descriptografa o conteúdo
    nTamanho  := Len(cConteudo)
    cDecode64 := Decode64(cConteudo)
    lRet      := GzStrDecomp(cDecode64, nTamanho, @cUnXML)
      
    //Se deu certo
    If lRet
         
        //Se o diretório não existir, cria
        If ! ExistDir(cDiretorio)
            MakeDir(cDiretorio)
        EndIf
         
        //Cria o arquivo com o conteúdo
        lRet := MemoWrite(cDiretorio+cArquivo, cUnXML)
         
        //Se houve falha, mostra mensagem no console.log
        If ! lRet
            ConOut("[u_zBxXML][fGeraXML] - Não foi possivel criar o arquivo: " + cArqFull)
            lHouveErro := .T.
        EndIf
     
    //Se não deu certo, mostra mensagem no console.log
    Else
        ConOut("[u_zBxXML][fGeraXML] - Houve algum erro na descompactação do arquivo!")
        lHouveErro := .T.
    EndIf
 
    //Se houve erro, zera o nome do arquivo para retornar em branco
    If lHouveErro
        cArqFull := ""
    EndIf
 
    RestArea(aArea)
Return cArqFull

Bom pessoal, por hoje é só.

Abraços e até a próxima.

Dan Atilio (Daniel Atilio)
Especialista em Engenharia de Software pela FIB. Entusiasta de soluções Open Source. E blogueiro nas horas vagas.

74 Responses

  1. Fco. C. Dantas q disse:

    O Endereço da URL não é valido o que impossibilita a validação.
    Eu não achei nenhum outro endereço na net.
    Se tiver um endereço com o WSDL valido, seria muto bem vindo.

  2. Súlivan Simões disse:

    Bom dia Dantas, tudo certo?

    O endereço da URL presente na função, é válido sim. Ela está funcionando corretamente.

    Como conversamos via Skype. O problema era que a você não tinha copiado a pasta Certs do TSS para a Protheus_data, e isso acarretava erro no momento de fazer o parse.

    Feito isso, a rotina funcionou!

    Atenciosamente.

  3. Dayvid Nogueira disse:

    Bom dia,
    Primeiramente gostaria de parabenizar pelo conteúdo da função e de todo o site, estão fazendo um excelente trabalho!
    Estou necessitando dessa função, pois desenvolvi uma função que busca as informações do XML pelo arquivo txt, porem o arquivo precisa estar em um diretório.
    Estou com o seguinte erro em relação a função descrita, depois que passa pelo método oWsdl:SendSoapMsg(cMsg)

    Value = “A WSDL exception occurred at0:0 WsdlParser Exception : Error sending SOAP message: Peer certificate cannot be authenticated with given CA certificates ”

    Obrigado pela Atenção.

  4. Súlivan Simões disse:

    Bom dia Dayvid , beleza?

    Este é erro pode ser comum de acontecer.

    Siga os passos dos links para corrigi-lo:

    Dúvidas quanto a Parse:
    Link 01 – https://centraldeatendimento.totvs.com/hc/pt-br/articles/360022658731-MP-ADVPL-Peer-certificate-cannot-be-authenticated-with-given-CA-certificates

    Link 02 – http://tdn.totvs.com/display/tec/Acesso+a+Web+Services+que+exigem+certificados+de+CA

    Atenciosamente.

  5. Há algum limite de conexões e notas que podemos baixar no sefaz?

  6. Súlivan Simões disse:

    Boa noite Jorge,

    Desconheço tal limite. acredito que não tenha.

    Atenciosamente.

    • Dan_Atilio disse:

      Complementando a resposta do Súlivan, Jorge.
      Desconheço que o SEFAZ tenha limite, talvez o que você encontre limites seja no próprio AdvPL, como no número de licenças (se você for executar mais de uma vez).
      Abraços galera, e obrigado Súlivan.

  7. Valtencir disse:

    Boa noite,
    Com este exemplo eu consigo recuperar xml de documento de entrada?

    • Dan_Atilio disse:

      Bom dia Valtencir.
      Essa função criada pelo Súlivan, você consegue ir no Sefaz via webservice, e baixar o xml de uma nota para o CNPJ da sua empresa.
      Um grande abraço.

  8. GESSE ANTONIO ROLDAO disse:

    Primeiramente gostaria de parabenizar a todos o envolvidos na criação desta rotina.
    Agora tenho uma dúvida! Ela funciona só para NF-e que já foi manifestada (ciência ou confirmação da operação) ?
    é isso mesmo?

  9. Súlivan Simões disse:

    Bom dia Gesse, tudo bem?

    A Sefaz só permite que seja feito o download de XML das NF-e que já estão manifestadas pelo destinatário.
    Deste modo para que a rotina consiga baixar o XML a NFe precisa estar manifestada sim.
    Existe uma rotina para fazer tal procedimento no próprio Protheus, que é bem simples e funcional para usar.
    É a rotina Miniestação Destinatário, programa SPEDMANIFE

    At.te

  10. Eduardo Oliveira disse:

    Ótimo post, parabéns !!!
    Gostaria de saber se é possível consumir o mesmo WS para baixar todos os xmls ( ou o resumo dos xmls ) que foram gerados contra nosso CNPJ , é possível ?

  11. Súlivan Simões disse:

    Bom dia,

    Eduardo, possível é, mas o fonte precisaria sofrer alterações de acordo com a documentação do link
    http://www.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=iGDFY8YBs28=

    Outra ressalva é que antes do download seria preciso uma personalização para que o sistema fizesse o manifesto para só então efetuar o download.

    At.te

  12. Flavio Freitas disse:

    Estou com mesmo problema, fiz o passo do link da TOTVS mas continua com problema Súlivan. Teria como dar uma idéia?

  13. Ivan disse:

    Aqui ocorre o erro: “WsdlParser Exception : Unknown Wsdl tag at 30,1” ao tentar parsear a url.

  14. Eduardo Candido disse:

    Boa Tarde Pessoal,
    Para ter uma relato completo das mensagens, inicializem o serviço via console e setem a propriedade lverbose=.T. Além das mensagens do console, serao gerados os arquivos de log de envio e recepção.
    Sobre os problemas do parse, no meu caso, resolveu quando setei a propriedade lSSLInsecure = .T. (além das referencias dos certificados).
    Alguém poderia enviar o xml de solicitacao do sendsoap?
    O meu parse está ok, porem o sendsoap apresenta o erro
    SOAP Fault String: Server was unable to read request. —> Request format is invalid: Missing required soap:Body element.

    Request:

       

       

           

                   

                       

                            1

                       43

                            1111111111111

                         

                               1111111111111

                         

                       

                   

               

           

       

  15. Súlivan Simões disse:

    Bom dia Eduardo.

    Desculpe-me pela demora.
    Possível creio que seja, mas ainda não desenvolvi tal função.
    Uma ideia mais simples que você pode usar a rotina SPEDMANIFE a seu favor, pois ela consegue fazer essa tarefa de ver as NFes disparadas contra o CNPJ, então da pra fazer algo para a deixar a SPEDMANIFE fazendo o processo de manifestação/verificação na Sefaz e a rotina de download só efetuar em download. Seria duas rotinas trabalhando em conjunto. Observando que ainda não fiz tal função.

    Segue links uteis.
    http://tdn.totvs.com/pages/releaseview.action?pageId=210043776
    http://tdn.totvs.com/pages/releaseview.action?pageId=184779187
    http://tdn.totvs.com/pages/releaseview.action?pageId=184779213

  16. Súlivan Simões disse:

    Bom dia Flavio,

    Eu já peguei algo parecido. Mesmo fazendo o processo do link da TOTVS com o arquivo ca.pem continua dando problema. Bem, isso é um problema dos arquivos mesmo.
    O que eu fiz pra resolver foi o seguinte no meu caso.
    Eu peguei os arquivos cert.pem e _key.pem oriundos do ultimo certificado do cliente que não tinha esse problema e joguei na pasta certs da protheus_data.
    Dessa forma eu refiz o ca.pem conforme a documentação da TOTVS e deu certo.

    Mas isso foi possível, pois o certificado digital do cliente anterior eu não tinha problema. Então basicamente o que eu fiz foi atualizar somente o arquivo ca.pem.

    Abraço.

  17. Súlivan Simões disse:

    Ivan, você alterou alguma coisa no código?
    Pois utilizo a função diariamente e nunca tive este problema. Veja se a url está igual a do site. Tente fazer o download sem nenhuma alteração do fonte original.
    Recomendo atualizar o TSS e refazer o processo da pasta certs também pra ver.
    Qualquer novidade nos conte.

    Abraço.

  18. Súlivan Simões disse:

    Bom dia Eduardo,

    A configuração padrão que uso nos clinete do SSLConfigure é a que está abaixo. Não tenho problemas.

    [SSLConfigure]
    HSM=0
    SSL2=0
    SSL3=1
    TLS1_0=1
    TLS1_1=1
    TLS1_2=1
    Verbose=1
    BUGS=1

  19. Ivan disse:

    Funcionou, muito obrigado! Qual a URL e operação para verificar NFs emitidas contra o CNPJ?

  20. Súlivan Simões disse:

    Ivan, a url é a mesma a forma que monta o xml que deve ser diferente
    segue link da documentação: http://www.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=iGDFY8YBs28=

  21. Vinicius Henrique disse:

    Olá, boa tarde pessoal.

    Rotina funcionou perfeitamente, parabéns.

    Alguem já conseguiu criar algo para buscar todos os XML’s disparados contra o CNPJ?

    Muito obrigado.

  22. Vinicius Henrique disse:

    Bom dia Edurado, conseguiu realizar o procedimento de baixar todas as NFs disparadas contra seu CNPJ?

  23. David disse:

    Boa tarde, ótimo post, parabéns!
    Uma dúvida, no meu xml veio apenas algumas informações, por exempo no xml baixado direto da SEFAZ vem informações do frete , como faço para que essas informaçõe também venham através da rotina?

  24. Súlivan Simões disse:

    Bom dia David.
    Bem, não sei se entendi direito a dúvida.
    A rotina baixa o XML da Sefaz na íntegra. Porém, caso a nota em questão não esteja manifestada, o XML que irá ser baixado será apenas um resumo.

  25. David disse:

    Legal, obrigado. Vimos que terá que fazer o manifesto, conforme foi mencionado por você nas respostas acima!
    Valeu.

  26. Dayvid Nogueira disse:

    E no caso de uma transportadora, como ela baixa a nota completa, se ela ainda não emitiu o Ct-e e nem o manifesto ?

  27. Eduardo Clemente disse:

    alguem ja viu esse erro:
    oWsdl:cError
    An exception occurred at 0:0
    WsdlParser Exception : Unable to connect to https://www1.nfe.fazenda.gov.br/NFeDistribuicaoDFe/NFeDistribuicaoDFe.asmx?WSDL
    due to error: Couldn’t connect to server

  28. Eduardo Clemente disse:

    Bom dia,
    recebi essa mensagem quando executei a rotina:

    1

    1.2.0

    215

    Rejeicao: Falha no esquema xml

    2019-10-26T11:59:14-03:00

    000000000000000

    000000000000000

  29. Eduardo Clemente disse:

    porque esse erro e como arrumar. Grato

    1

    1.2.0

    215

    Rejeicao: Falha no esquema xml

    2019-10-26T11:59:14-03:00

    000000000000000

    000000000000000

  30. Eduardo Clemente disse:

    Estou com problemas nessa parte do fonte:

    //Se for continuar
    If lContinua
    //Se a tag DocZip existir (for diferente de Undefinied)
    If (Type(“oXmlDocZip:_SOAP_ENVELOPE:_SOAP_BODY:_NFEDISTDFEINTERESSERESPONSE:_NFEDISTDFEINTERESSERESULT:_RETDISTDFEINT:_LOTEDISTDFEINT:_DOCZIP”) != “U”

    Esta retornado ” U “, você saberia dizer o porque o DocZip esta retornando assim.

    Grato

  31. Rodrigo Borsato disse:

    Bom dia, estou com a seguinte falha:

    [U_ZBXXML] – ERRO SENDSOAPMSG: Could not connect to https://www1.nfe.fazenda.gov.br/NFeDistribuicaoDFe/NFeDistribuicaoDFe.asmx

    Alguém pode ajudar?

  32. Rodrigo Borsato disse:

    Só recebo esse retorno, os CNPJs da chave e requisição são os mesmos.
    Alguma ideia?

    1
    1.2.0
    641
    Rejeicao: NF-e indisponivel para o emitente
    2019-11-18T16:00:22-03:00

  33. Rodrigo Borsato disse:

    Já resolvi, meu antivirus estava bloqueando.

  34. Rodrigo Borsato disse:

    Já resolvi essa, obrigado (era o anti-vírus bloqueando)

  35. Súlivan Simões disse:

    Bom dia,

    @Eduardo Clemente, esse problema é seu firewall ou antivírus que está bloqueando.
    Desative-os e faça o teste.

    At.te

  36. Súlivan Simões disse:

    @Rodrigo Borsato
    sobre a rejeição 641 – Rejeicao: NF-e indisponivel para o emitente

    Como conversado, isso era porque o processo que você estava fazendo estava fora do padrão.
    Você estava tentando baixar uma nota que você mesmo emitiu.

    A rotina baixa as notas a qual você é o cliente, e não o emitente como está tentando fazer.
    Levando em consideração que se você é o emitente você já tem o XML,

    Para fazer o que precisa vai precisar adequar a rotina a sua necessidade e ver se a Sefaz permite tal operação, o que pode correr o risco de não ser permitido.

    At.te

  37. Saudações, vocês podem enviar o exemplo que busca as notas contra um CNPJ ou CPF?

    • Dan_Atilio disse:

      Boa tarde Marco, tudo bem?
      Esse exemplo foi montado usando a chave de acesso, mas caso você tenha interesse, pode verificar se Súlivan (eMail no cabeçalho do protheus.doc da rotina) gentilmente desenvolveu já algum exemplo com CNPJ.

  38. GERALDO disse:

    Legal este Rdmake , mas me tira uma duvida so consigo baixa xml contra meu cnpj ? cono usaria para gravar xml para enviar para meus clientes ? sempre da erro 640 ou 641

    640 Rejeição: CNPJ/CPF do interessado não possui permissão para consultar esta NF-e
    641 Rejeição: NF-e indisponível para o emitente

  39. Sulivan Simões disse:

    Bom dia Geraldo, tudo joia?

    Para baixar XML de NFE ou CTE emitidos contra o CNPJ já temos a rotina, segue o link
    https://terminaldeinformacao.com/2020/09/13/funcao-para-baixar-xml-de-nfe-e-cte-direto-da-sefaz-codigo-fonte-prw/

    Referente as rejeições tem que analisar o processo que está fazendo.
    1 – Se você estiver tentando baixar nota que você mesmo emitiu ou tentando fazer download de notas emitidas contra outros CNPJ diferentes do seu a Sefaz não irá permitir, pois a empresa precisa estar como destinatário na nota fiscal.

  40. Antonio Daniel disse:

    Link down, ainda tem a rotina?

  41. Para corrigir o erro “Unknown element WSCorIDSOAPHeader”
    Que ocorre no momento de realizar o download.

    Adicionem a seguinte linha ao código

    oWsdl:lProcResp := .F.

    Link tdn: https://tdn.totvs.com/display/tec/TWsdlManager%3AlProcResp

  42. Max disse:

    Olá pessoal ! Parabéns pelo trabalho ! É possível utilizar esse fonte com um certificado A3 ? Sempre usei esse fonte mas depois que instalamos o A3 ele não traz mais a tag NFEPROC. Ele começa da “<NFe xmlns="

    Um abraço

  43. Súlivan Simões disse:

    Boa tarde Max,
    Olha nunca fiz o teste com o certificado A3, mas os certificados são usados para autenticação no momento de pedir o XML para Sefaz.
    Pelo que você disse o sistema está baixando um XML, teria que analisar o conteúdo dele para ver o que está acontecendo de fato.
    Não possuo esse certificado para testar 🙁

  44. Vinicius Henrique disse:

    Ola, bom dia.

    Mais alguém com o problema (“[u_VHLXML] – Erro ParseURL: Xml Parser Exception : expected: p
    “) no retorno da linha 68?

    Alguém consegue me ajudar?

  45. Súlivan disse:

    Boa tarde,
    Vinicius você alterou alguma coisa no fonte postado?
    Caso não, esse problema ocorre para todas as chaves que você informa na rotina, ou é só em alguma especifica?

  46. Flavio Dias disse:

    Boa tarde,
    Estou com problema na seguinte situação
    lRet := MemoWrite(cDiretorio+cArquivo, cUnXML)
    sempre me retorina falso.
    Mesmo tendo o diretorio criado ele não salva o arquvo extenção xml. O que pdoeria ser?

  47. Desenvolvimento disse:

    Como conseguir baixar o XML completo?

  48. Harley Dias Koehler disse:

    O exemplo funcionou, mas como fazer para baixar o xml completo do CT-e? Alguem aqui conseguiu ?

  49. Sulivan Simões disse:

    Bom dia Harley, tudo joia?
    Já desenvolvi essa rotinas.
    Segue link: https://sulivansistemas.com/protheus-download-xml-sefaz/

  50. Sulivan Simões disse:

    Bom dia Desenvolvimento.
    Então para baixar o XML completo é obrigatório que a NF-e precise estar com alguma manifestação do destinatário.
    Você pode fazer isso usando a rotina padrão do Protheus: https://centraldeatendimento.totvs.com/hc/pt-br/articles/360033920194-MP-MDE-Como-manifestar-notas-na-rotina-SPEDMANIFE

  51. Edvar Vassaitis disse:

    Sulivan, muito obrigado pelo material, mas infelizmente a Sefaz suspendeu temporariamente a consulta através do serviço conschnfe conforme link abaixo:
    https://www.nfe.fazenda.gov.br/portal/informe.aspx?ehCTG=false&Informe=A6qvFRVbPSA=
    Existe alguma alternativa para baixar o XML?
    Vejo que existem alguns programas de terceiros que ainda conseguem baixar o XML

    Muito obrigado

  52. Súlivan Simões disse:

    Bom dia,
    Complementando o que o Atilio disse, Edvar.
    As consultas voltaram a funcionar normalmente sem precisar fazer nenhuma intervenção no código fonte desenvolvido.
    Um ponto importante a ser observado é que agora deve ser feito no máximo 20 consultas por hora, senão a Sefaz bloqueia por 1 hora, além das outras regras implementadas que também causam esse bloqueio.

    Vale ressaltar que se precisar buscar mais XML(s) por hora deve usar outra consulta. Essa consulta do link abaixo busca mais XML(s) e pega tudo foi disparado contra o CNPJ (https://terminaldeinformacao.com/2020/09/13/funcao-para-baixar-xml-de-nfe-e-cte-direto-da-sefaz-codigo-fonte-prw/)

    As novas regras publicadas da Sefaz, são:
    2 – O uso indevido relativo ao Web Service NFeDistribuicaoDFe nas consultas com tag: consChNFe e tag: consNSU:

    As consultas por chave de acesso e por NSU foram construídas para permitirem ao usuário buscar pontualmente alguma NF-e e de um período retroativo máximo de 90 (noventa) dias. Se o usuário necessitar buscar todas as NF-es de no máximo 90 dias de um CNPJ ator interessado, deve ser usada outra consulta

    2.1 Consultada uma quantidade de NF-e ou NSU superior ao limite permitido por hora:

    Será permitido um número limitado de consultas por chave de acesso ou NSU em um período de 1hora. Se o usuário continuar consultando após atingir o limite de consultas por chave de acesso ou NSU em 1h, retornará a mensagem 656 – Consumo indevido – ultrapassou o limite de 20 consultas por hora. Nesse caso, o CNPJ é bloqueado por 1 hora, sendo impedido de realizar novas consultas nesse intervalo. Decorrido o intervalo de tempo, o desbloqueio será automático.

    Observação: Em quaisquer dos três tipos de consulta, quando o usuário receber a mensagem 656 – consumo indevido, deve aguardar 1hora. Se retomar a consulta antes de completar 1 (uma) hora, o tempo é zerado e a contagem reiniciará até completar 1hora.

  53. Edvar Vassaitis disse:

    Bom dia Dan tudo bem ?
    Estava preocupado pois no primeiro comunicado eles não deram um prazo, e nesse já colocaram.
    Muito obrigado pelo retorno

  54. Edvar Vassaitis disse:

    Súlivan,
    Realmente temos que ter atenção nessas novas regras e adaptar o fonte atual para evitar consumo indevido.
    O Sr. poderia compartilhar o nome do WebService que utiliza para essa consulta que pega tudo que foi contra o CNPJ ?
    Agradeço muito pelo retorno.

  55. Edvar Vassaitis disse:

    Dan, muito obrigado pelo retorno.
    Estavamos preocupados pois no primeiro comunicado não havia prazo para retorno dos serviços.

  56. Súlivan Simões disse:

    Edvar, para adquirir o código fonte que utiliza para a consulta que pega tudo que foi contra o CNPJ. Segue o Link:
    https://sulivansistemas.com/wp/protheus-rotina-de-download-de-xml-de-nf-e-e-ct-e%e2%80%8b/

  57. Edvar Vassaitis disse:

    Súlivan bom dia tudo bem ?
    Realmente só gostaria que compartilhasse o webservice/metodo que utiliza para essa consulta, para que eu desenvolva internamente. Mas se não quiser compartilhar eu compreendo.
    Obrigado

  58. O SEFAZ limita a consulta em 20 consultas por hora.

  59. Súlivan disse:

    Boa noite,
    Sim leonardompereira, de acordo com as novas diretrizes da Sefaz essa consulta por chave agora tem limitação de 20 consultas por hora.
    Essa é uma diretriz da Sefaz imposta para todos serviços que utilizam essa consulta.
    At.te.

  60. SAMUEL PEREZ disse:

    Boa atarde Súlivan

    O link não está acessível, teria como reenviar?
    Outra dúvida, você ainda está oferecendo o produto que baixa os XML sem a limitação das 20 consultas? tenho um alto volume de NFs e apenas 20 consulta por hora é pouco.

  61. Súlivan Simões disse:

    *** INFORME ***
    Para corrigir o problema abaixo, que acontece no console, caso esteja passando por ele.

    Erro ParseURL: An exception occurred at 1:0
    WsdlParser Exception : Could not parse schema http://schemas.xmlsoap.org/wsdl/

    Você deve adicionar o seguinte trecho no código:
    oWsdl:bNoCheckPeerCert:=.F.

    Referencias:
    https://centraldeatendimento.totvs.com/hc/pt-br/articles/5151712642839
    https://tdn.totvs.com/display/tec/TWsdlManager%3AbNoCheckPeerCert

Deixe uma resposta