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.

60 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

Deixe uma resposta