No artigo de hoje, vou mostrar para vocês como fazer a integração com a API dos Correios.
Pessoal, o exemplo apresentado aqui foi disponibilizado com a ajuda do grande Fernando Sauer ( LinkedIn ). No caso, essa customização basicamente se comunica com o WSDL dos correios (documentação disponível em https://www.correios.com.br/atendimento/ferramentas/sistemas/arquivos/web-service-de-rastreamento ).
Depois de fazer essa comunicação, é buscado o resultado em XML, e então conforme as posições do texto é definido um retorno em array.
Para utilizar, é necessário ter um usuário e senha com acesso ao SRO XML dos Correios. No caso, para armazenar essas informações, crie os parâmetros MV_X_CORSE (Correios Senha) e MV_X_CORUS (Correios Usuário).
Abaixo o código fonte desenvolvido:
//Bibliotecas #Include "TOTVS.ch" /*/{Protheus.doc} User Function zCorreios Função que realiza a consulta de um rastreio direto nos correios e monta um array com o resultado @author Fernando Sauer @since 01/02/2021 @version 1.0 @type function @return aInfRast, Array, Retorna um array com as informações do rastreio @example aDados := u_zCorreios("XXAA01010101") @obs Documentação da API: https://www.correios.com.br/atendimento/ferramentas/sistemas/arquivos/web-service-de-rastreamento Exemplo documentado e adaptado por Daniel Atilio Abaixo as posições do Array de retorno: aInfRast[01] --> Data de atualização da informação nos Correios aInfRast[02] --> Hora de atualização da informação nos Correios aInfRast[03] --> Descrição do status do rastreamento aInfRast[04] --> Local do código de Rastreamento aInfRast[05] --> Código de Rastreamento aInfRast[06] --> Município do Rastreamento aInfRast[07] --> Estado do Objeto de Rastreamento aInfRast[08] --> Endereço de retirada /*/ User Function zCorreios(cRastreio) Local aArea := GetArea() Local oWsdl Local xRet Local cError := "" Local cWarning := "" Local cResp := "" Local lContinua := .T. //Retorno Último rastreio Local nPosIni := 0 Local nPosFim := 0 Local nLeitura := 0 Local dDtRast := "" Local cHrRast := "" Local cDesRast := "" Local cLcRast := "" Local cCodRast := "" Local cMunRast := "" Local cEstRast := "" Local cEndereco := "" Local aInfRast := Array(8) Local cLograd := "" //Logradouro Local cNumero := "" //Número Local cLocalid := "" //Localidade //Usuário e senha dos Correios - "Habilitar Acesso ao SRO XML [Solicitação]" Local cPWDCo := SuperGetMv("MV_X_CORSE", .F., 'XXXXXXXX') Local cUsuCo := SuperGetMv("MV_X_CORUS", .F., 'YYYYYYYY') Default cRastreio := "" //Código precisa estar preenchido If ! Empty(cRastreio) MsgInfo("Código de rastreio em branco") Else //Faz a comunicação com a API oWsdl := TWsdlManager():New() oWsdl:lSSLInsecure := .T. If xRet := ! oWsdl:ParseURL( "https://webservice.correios.com.br/service/rastro/Rastro.wsdl" ) MsgInfo( "Erro Parse: " + oWsdl:cError ) lContinua := .F. EndIf //Define a operação como buscaEventos If lContinua .And. xRet := !oWsdl:SetOperation( "buscaEventos" ) MsgInfo( "Erro SetOperation: " + oWsdl:cError ) lContinua := .F. EndIf //Se não houve erros If lContinua cMsgWs := '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:res="http://resource.webservice.correios.com.br/"> cMsgWs += '<soapenv:Header/>' cMsgWs += '<soapenv:Body>' cMsgWs += '<res:buscaEventos> cMsgWs += '<usuario>' + cUsuCo + '</usuario> cMsgWs += '<senha>' + cPWDCo + '</senha> cMsgWs += '<tipo>L</tipo> cMsgWs += '<resultado>U</resultado> cMsgWs += '<lingua>101</lingua> cMsgWs += '<objetos>'+ AllTrim(cRastreio) + '</objetos> cMsgWs += '</res:buscaEventos> cMsgWs += '</soapenv:Body> cMsgWs += '</soapenv:Envelope> //Busca o resultado da consulta xRet := oWsdl:SendSoapMsg(cMsgWs) xRet := oWsdl:SendSoapMsg(cMsgWs) cResp := oWsdl:GetParsedResponse() cRespost := oWsdl:GetSoapResponse() oXml := XmlParser( cRespost, "_", @cError, @cWarning ) //Data de atualização da informação nos Correios nPosIni := At("<data>", cRespost) + 6 nPosFim := At("</data>", cRespost) nLeitura := nPosFim - nPosIni dDtRast := SubStr(cRespost, nPosIni, nLeitura) //Hora de atualização da informação nos Correios nPosIni := At("<hora>", cRespost) + 6 nPosFim := At("</hora>", cRespost) nLeitura := nPosFim - nPosIni cHrRast := SubStr(cRespost, nPosIni, nLeitura) //Descrição do status do rastreamento nPosIni := At("<descricao>", cRespost) + 11 nPosFim := At("</descricao>", cRespost) nLeitura := nPosFim - nPosIni cDesRast := SubStr(cRespost, nPosIni, nLeitura) cDesRast := DecodeUTF8(cDesRast, "cp1252") //Local do código de Rastreamento nPosIni := At("<local>", cRespost) + 7 nPosFim := At("</local>", cRespost) nLeitura := nPosFim - nPosIni cLcRast := SubStr(cRespost, nPosIni, nLeitura) cLcRast := DecodeUTF8(cLcRast, "cp1252") //Código de Rastreamento nPosIni := At("<numero>", cRespost) + 8 nPosFim := At("</numero>", cRespost) nLeitura := nPosFim - nPosIni cCodRast := SubStr(cRespost, nPosIni, nLeitura) cCodRast := DecodeUTF8(cCodRast, "cp1252") //Município do Rastreamento nPosIni := At("<cidade>", cRespost) + 8 nPosFim := At("</cidade>", cRespost) nLeitura := nPosFim - nPosIni cMunRast := SubStr(cRespost, nPosIni, nLeitura) cMunRast := DecodeUTF8(cMunRast, "cp1252") //Estado do Objeto de Rastreamento nPosIni := At("<uf>", cRespost) + 4 nPosFim := At("</uf>", cRespost) nLeitura := nPosFim - nPosIni cEstRast := SubStr(cRespost, nPosIni, nLeitura) cEstRast := DecodeUTF8(cEstRast, "cp1252") //Endereço de retirada If "<endereco>" $ cRespost nPosIni := At("<endereco>", cRespost) + 10 nPosFim := At("</endereco>", cRespost) nLeitura := nPosFim - nPosIni cEndereco := SubStr(cRespost, nPosIni, nLeitura) cEndereco := DecodeUTF8(cEndereco, "cp1252") nPosIni := At("<logradouro>", cEndereco) + 12 nPosFim := At("</logradouro>", cEndereco) nLeitura := nPosFim - nPosIni cLograd := SubStr(cEndereco, nPosIni, nLeitura) cLograd := DecodeUTF8(cLograd, "cp1252") nPosIni := At("<numero>", cEndereco) + 8 nPosFim := At("</numero>", cEndereco) nLeitura := nPosFim - nPosIni cNumero := SubStr(cEndereco, nPosIni, nLeitura) cNumero := DecodeUTF8(cNumero, "cp1252") nPosIni := At("<localidade>", cEndereco) + 12 nPosFim := At("</localidade>", cEndereco) nLeitura := nPosFim - nPosIni cLocalid := SubStr(cEndereco, nPosIni, nLeitura) cLocalid := DecodeUTF8(cLocalid, "cp1252") cEndereco := cLograd + ", " + cNumero + " " + cLocalid Else cEndereco := "" EndIf //Define o retorno aInfRast[01] := dDtRast aInfRast[02] := cHrRast aInfRast[03] := cDesRast aInfRast[04] := cLcRast aInfRast[05] := cCodRast aInfRast[06] := Capital(cMunRast) aInfRast[07] := cEstRast aInfRast[08] := Capital(cEndereco) EndIf EndIf RestArea(aArea) Return aInfRast
Bom pessoal, por hoje é só.
Abraços e até a próxima.
Estou desenvolvendo um programa quase igual ao seu para os correios.
// Cria o objeto da classe TWsdlManager
oWsdl := TWsdlManager():New()
oWsdl:lSSLInsecure := .T.
xRet := oWsdl:ParseURL(“https://apphom.correios.com.br/SigepMasterJPA/AtendeClienteService/AtendeCliente?wsdl”)
If xRet == .F.
Alert( “Erro 0: ” + oWsdl:cError )
Return
EndIf
xRet := oWsdl:SetOperation( “verificaDisponibilidadeServico” )
If xRet == .F.
Alert( “Erro 1: ” + oWsdl:cError )
Return
EndIf
cMsgWs := ”
cMsgWs += ”
cMsgWs += ”
cMsgWs += ”
cMsgWs += ‘17000190’
cMsgWs += ‘04162’
cMsgWs += ‘05311900’
cMsgWs += ‘05311900’
cMsgWs += ‘sigep’
cMsgWs += ‘n5f9t8’
cMsgWs += ”
cMsgWs += ”
cMsgWs += ”
//Busca o resultado da consulta
xRet := oWsdl:SendSoapMsg(cMsgWs)
If xRet == .F.
Alert( “Erro 2: ” + oWsdl:cError ) //ERRO AQUI: SOAP Fault Code: soap:Client SOAP Fault String: Error reading XMLStreamReader.
Return
EndIf
cResp := oWsdl:GetParsedResponse()
cRespost := oWsdl:GetSoapResponse()
Esse exemplo acima é do próprio manual para teste.
Apresenta o erro (SOAP Fault Code: soap:Client SOAP Fault String: Error reading XMLStreamReader.)
Você poderia me ajudar? Já aconteceu com você esse tipo de erro?
Olá jovem.
No caso, não sei se o comentário cortou os caracteres de maior e menor, mas no seu cMsgWs, você esta enviando as tags abrindo e fechando certinho?