Consumir Webservice ( SOAP )

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Consumir Webservice ( SOAP )

Mensagem por JoséQuintas »

Sinceramente....
Eu montei as rotinas de comunicação com a Sefaz, e simplesmente acho confuso o jeito que está sendo usado.

1) tem o xml normal
2) pode ter o xml de envio, que tem o xml normal como uma parte dele
3) tem o xml de comunicação, que tem os anteriores dentro
4) tem o envelope, que tem todos os xmls dentro

tem o soap da microsoft pra comunicação
tem a capicom da microsoft pra assinar, se for necessário

o DOM não é necessário em momento nenhum, a não ser que queira validar o xml.

Daqui a pouco posto um conjunto de tudo isso.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
Alexandre Silva
Usuário Nível 3
Usuário Nível 3
Mensagens: 376
Registrado em: 26 Mar 2007 00:16
Localização: Itapema - SC

Consumir Webservice ( SOAP )

Mensagem por Alexandre Silva »

Opa...Mestre...
Abaixo foi passada todos esses parametros..
O que preciso é pegar o xml do cte da empresa evelopar e mandar...
Se precisar posso mandar as senhas para teste em MP.


Name: averbaCTe20
Binding: ATMWebSvrBinding
Endpoint: http://homologacao.averba.com.br/webserver/index.soap
SoapAction: urn:ATMWebSvr#averbaCTe20
Style: rpc

Input:
use: encoded
namespace: urn:ATMWebSvr
encodingStyle: http://schemas.xmlsoap.org/soap/encoding/
message: averbaCTe20Request
parts:
usuario: xsd:string
senha: xsd:string
codatm: xsd:string
xmlCTe: xsd:string

********
Output:
use: encoded
namespace: urn:ATMWebSvr
encodingStyle: http://schemas.xmlsoap.org/soap/encoding/
message: averbaCTe20Response
parts:
return: xsd:string
Namespace: urn:ATMWebSvr
Transport: http://schemas.xmlsoap.org/soap/http
* Clipper 5.2e/Gaspro 4.0 /CDX/Blinker 7.0 Harbour 3.2 Console Hbmk2
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Consumir Webservice ( SOAP )

Mensagem por JoséQuintas »

Só aproveitei um intervalo aqui.
Seguindo o manual, o primeiro ponto é o XML, já com evelope e tudo.

Código: Selecionar todos

FUNCTION SOAPEnvelope( cInsideXml. cSoapAction )
   LOCAL cText := ""
   cText += [<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:xmethods-delayed-quotes">]
   cText += [<soapenv:Header/>]
   cText += [<soapenv:Body>]
   cText += [<urn:] + cSoapAction + [ soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">]
   cText += [<args>]
   cText += cInsideXml
   cText += [</args>]
   cText += [</urn:] + cSoapAction + [>]
   cText += [</soapenv:Body>]
   cText += [</soapenv:Envelope>]
   RETURN cText
cInsideXml => é a parte com os argumentos, que varia
cSoapAction => o nome da função a ser chamada, que varia também
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Consumir Webservice ( SOAP )

Mensagem por JoséQuintas »

Falta o teste prático.
Aqui meu SOAP do projeto NFE/CTE/MDFE, com leves modificações
Nota: Em versões anterior do Harbour, bytearray era retornado como array de Ascii, depois como string. A rotina manteve como precaução testar os dois tipos de retorno.

Código: Selecionar todos

FUNCTION MicrosoftXmlSoapPost( cXmlSoap, cSoapAction )
   LOCAL oServer, nCont, clRetorno := "*ERRO*", cXmlRetorno := ""
   BEGIN SEQUENCE WITH { |e| Break(e) }
      oServer := win_OleCreateObject( "MSXML2.ServerXMLHTTP")
      oServer:Open( "POST", ::cWebService, .F. )
      oServer:SetRequestHeader( "SOAPAction", cSoapAction )
      oServer:SetRequestHeader( "Content-Type", "application/soap+xml; charset=utf-8" )
      oServer:Send( cXmlSoap )
      oServer:WaitForResponse( 500 )
      cRetorno := oServer:ResponseBody
   ENDSEQUENCE
   IF ValType( cRetorno ) == "C"
      cXmlRetorno := cRetorno
   ELSEIF cRetorno == NIL
      cXmlRetorno := "*ERRO*"
   ELSE
      cXmlRetorno := ""
      FOR nCont = 1 TO Len( cRetorno )
         cXmlRetorno += Chr( cRetorno[ nCont ] )
      NEXT
   ENDIF
   RETURN cXmlRetorno

Código: Selecionar todos

// uso das rotinas
cSeuXml := "***seu xml com argumentos***"
cRetorno := MicrosoftXmlSoapPost( SoapEnvelope( cSeuXml ) )
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Consumir Webservice ( SOAP )

Mensagem por JoséQuintas »

Comparando o manual e o webservice, parece que o exemplo não bate.
Veja se consegue exemplo atualizado.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
Alexandre Silva
Usuário Nível 3
Usuário Nível 3
Mensagens: 376
Registrado em: 26 Mar 2007 00:16
Localização: Itapema - SC

Consumir Webservice ( SOAP )

Mensagem por Alexandre Silva »

Apos varias tentativas, só tenho retorno NIL...
Veja exemplo com Usuario e senha para testes.. basta ter um xml de Cte para testar..
é complicado quando nao se sabe..

Código: Selecionar todos

function main()
local cseuxml:=''
cls
cWebService:="http://homologacao.averba.com.br/webserver/index.soap"
SoapAction:='averbaCTe'
cxlido:=memoread('meux.xml')
cseuxml+=[<usuario xsi:type="xsd:string">TESTES</usuario>]
cseuxml+=[<senha xsi:type="xsd:string">BASE</senha>]
cseuxml+=[<codatm xsi:type="xsd:string">11340073</codatm>]
cseuxml+='<xmlCTe xsi:type="xsd:string"><![CDATA['
cseuxml+=cxlido
cseuxml+=']]>'
cseuxml+='</xmlCTe>'
*--
cRetorno := MicrosoftXmlSoapPost( SoapEnvelope(cSeuXml,SoapAction) )
alert(cretorno)
quit

*------------------------------------------------
*------------------------------------------------
FUNCTION SOAPEnvelope( cInsideXml, cSoapAction )
LOCAL cText := ""
cText += [<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:ATMWebSvr">]
cText += [<soapenv:Header/>]
cText += [<soapenv:Body>]  // abaixo colocado space apos cSoapAction
cText += [<urn:]+cSoapAction+' '+[soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">]
cText += [<args>]
cText += cInsideXml
cText += [</args>]
cText += [</urn:] + cSoapAction + [>]
cText += [</soapenv:Body>]
cText += [</soapenv:Envelope>]
HB_MemoWrit('vai.xml',ctext)
RETURN cText


FUNCTION MicrosoftXmlSoapPost( cXmlSoap, cSoapAction )
LOCAL oServer, nCont, cRetorno := "*ERRO*", cXmlRetorno := ""
BEGIN SEQUENCE WITH { |e| Break(e) }
   oServer := win_OleCreateObject( "MSXML2.ServerXMLHTTP")
   oServer:Open( "POST", ::cWebService, .F. )
   oServer:SetRequestHeader( "SOAPAction", cSoapAction )
   oServer:SetRequestHeader( "Content-Type", "application/soap+xml; charset=utf-8" )
   oServer:Send( cXmlSoap )
   oServer:WaitForResponse( 500 )
   cRetorno := oServer:ResponseBody
ENDSEQUENCE
IF ValType( cRetorno ) == "C"
   cXmlRetorno := cRetorno
ELSEIF cRetorno == NIL
   cXmlRetorno := "*ERRO*"
ELSE
   cXmlRetorno := ""
   FOR nCont = 1 TO Len( cRetorno )
      cXmlRetorno += Chr( cRetorno[ nCont ] )
   NEXT
ENDIF
RETURN cXmlRetorno


* Clipper 5.2e/Gaspro 4.0 /CDX/Blinker 7.0 Harbour 3.2 Console Hbmk2
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Consumir Webservice ( SOAP )

Mensagem por JoséQuintas »

Meu teste simples:
Peguei o XML de exemplo do manual sem mexer em nada.

Código: Selecionar todos

PROCEDURE Main
   LOCAL cXml, cSoapAction, cUrl, cRetorno

   cUrl := "http://homologacao.averba.com.br/webserver/index.soap"

   cSoapAction := [adicionarAverbacao]

   cXml := ""
   cXml += [<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:xmethods-delayed-quotes">]
   cXml += [<soapenv:Header/>]
   cXml += [<soapenv:Body>]
   cXml += [<urn:adicionarAverbacao soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">]
   cXml += [<args>]
   cXml += [<usuario>SEU_LOGIN</usuario>]
   cXml += [<senha>SUA_SENHA</senha>]
   cXml += [<emit_nome>EMITENTE</emit_nome>]
   cXml += [<emit_cnpj>53.561.748/0001-20</emit_cnpj>]
   cXml += [<emit_cidade>Cotia</emit_cidade>]
   cXml += [<emit_uf>SP</emit_uf>]
   cXml += [<tipo_documento>CTE</tipo_documento>]
   cXml += [<num_documento>1</num_documento>]
   cXml += [<serie_documento>1</serie_documento>]
   cXml += [<data_emissao>27/09/2013</data_emissao>]
   cXml += [<tipo_mercadoria>ARROZ</tipo_mercadoria>]
   cXml += [<tipo_embarque>RODOVIARIO</tipo_embarque>]
   cXml += [<valor_mercadoria>1.200,00</valor_mercadoria>]
   cXml += [<placa>AAA1234</placa>]
   cXml += [<remet_nome>EMITENTE</remet_nome>]
   cXml += [<remet_cnpj>53.561.748/0001-20</remet_cnpj>]
   cXml += [<remet_cidade>Cotia</remet_cidade>]
   cXml += [<remet_uf>SP</remet_uf>]
   cXml += [<dest_nome>EMITENTE</dest_nome>]
   cXml += [<dest_cnpj>53.561.748/0001-20</dest_cnpj>]
   cXml += [<dest_cidade>Cotia</dest_cidade>]
   cXml += [<dest_uf>SP</dest_uf>]
   cXml += [<consig_nome>CONSIGNATÁRIO</consig_nome>]
   cXml += [<consig_cnpj>53.561.748/0001-20</consig_cnpj>]
   cXml += [<consig_cidade>Cotia</consig_cidade>]
   cXml += [<consig_uf>SP</consig_uf>]
   cXml += [</args>]
   cXml += [</urn:adicionarAverbacao>]
   cXml += [</soapenv:Body>]
   cXml += [</soapenv:Envelope>]

   cRetorno := MicrosoftXmlSoapPost( cXml, cSoapAction, cUrl )

   ? cRetorno
   RETURN



FUNCTION MicrosoftXmlSoapPost( cXmlSoap, cSoapAction, cWebService )
 LOCAL oServer, nCont, cRetorno := "*ERRO*", cXmlRetorno := ""
 BEGIN SEQUENCE WITH { |e| Break(e) }
   oServer := win_OleCreateObject( "MSXML2.ServerXMLHTTP")
   oServer:Open( "POST", cWebService, .F. )
   oServer:SetRequestHeader( "SOAPAction", cSoapAction )
   oServer:SetRequestHeader( "Content-Type", "application/soap+xml; charset=utf-8" )
   oServer:Send( cXmlSoap )
   oServer:WaitForResponse( 500 )
   cRetorno := oServer:ResponseBody
 ENDSEQUENCE
 IF ValType( cRetorno ) == "C"
   cXmlRetorno := cRetorno
 ELSEIF cRetorno == NIL
   cXmlRetorno := "*ERRO*"
 ELSE
   cXmlRetorno := ""
   FOR nCont = 1 TO Len( cRetorno )
    cXmlRetorno += Chr( cRetorno[ nCont ] )
   NEXT
 ENDIF
 RETURN cXmlRetorno
Como eu disse, o SOAP é enviar um XML e receber outro de resposta.
A resposta foi esta:

Código: Selecionar todos

<?xml version="1.0" encoding="ISO-8859-1"?><SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body><SOAP-ENV:Fault><faultcode xsi:type="xsd:string">SOAP-ENV:Client</faultcode><faultactor xsi:type="xsd:string"></fau
ltactor><faultstring xsi:type="xsd:string">Operation &apos;&apos; is not defined in the WSDL for this service</faultstring><detail
 xsi:type="xsd:string"></detail></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>
O fonte tem duas coisas: o XML e o nome da operação.
Se está rejeitando, ou o XML está errado no manual, ou o nome da operação. Não tem mais nada além disso.

A propósito, a mensagem de erro retornada (dentro desse xml) é esta:
Operation &apos;&apos; is not defined in the WSDL for this service
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Consumir Webservice ( SOAP )

Mensagem por JoséQuintas »

Só fiz uns chutes, mas continua igual.
Tentei mexer no endereço e na operação:

Código: Selecionar todos

  cUrl := "http://homologacao.averba.com.br/webserver/index.soap?wsdl"
   cSoapAction := [http://homologacao.averba.com.br/webserver/index.soap?wsdl/adicionarAverbacao]
Corrigindo a mensagem anterior, são 3 coisas: endereço do webservice, operação e xml.

E só pra lembrar: a comunicação chama a operação, que é uma função do servidor. Se fosse simples, o servidor estaria liberado à vontade pra todos. Então a segurança é exatamente essas 3 coisas, que precisam estar rigorosamente corretas.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Consumir Webservice ( SOAP )

Mensagem por JoséQuintas »

Li também sua outra mensagem.
Aparentemente agora foi, era a Soap Action, mas mexi em outras coisas e deixei, já que fizeram parte do teste (não significa que precisa delas).
Como era de se esperar, agora são os dados informados.

Nota:
Agora a resposta é da operação averbaCTe20, e reclama de usuário/senha/etc.
Então resolvidas 2 coisas: o endereço do webservice, e a SOAP Action.
Agora o resto é com o XML - note que Soap Action também está dentro do XML.
E agora é com você, já que depende de usuário/senha.

Código: Selecionar todos

PROCEDURE Main
   LOCAL cXml, cSoapAction, cUrl, cRetorno

   cUrl := "http://homologacao.averba.com.br/webserver/index.soap"

   cSoapAction := [urn:ATMWebSvr#averbaCTe20]

   cXml := ""
   cXml += [<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:xmethods-delayed-quotes">]
   cXml += [<soapenv:Header/>]
   cXml += [<soapenv:Body>]
   cXml += [<urn:averbaCTe20 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="urn:ATMWebSvr" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="urn:ATMWebSvr">]
   cXml += [<service name="ATMWebSvr"><port name="ATMWebSvrPort" binding="tns:ATMWebSvrBinding"><soap:address location="http://homologacao.averba.com.br/webserver/index.soap"/></port></service>]
   cXml += [<args>]
   cXml += [<usuario>SEU_LOGIN</usuario>]
   cXml += [<senha>SUA_SENHA</senha>]
   cXml += [<emit_nome>EMITENTE</emit_nome>]
   cXml += [<emit_cnpj>53.561.748/0001-20</emit_cnpj>]
   cXml += [<emit_cidade>Cotia</emit_cidade>]
   cXml += [<emit_uf>SP</emit_uf>]
   cXml += [<tipo_documento>CTE</tipo_documento>]
   cXml += [<num_documento>1</num_documento>]
   cXml += [<serie_documento>1</serie_documento>]
   cXml += [<data_emissao>27/09/2013</data_emissao>]
   cXml += [<tipo_mercadoria>ARROZ</tipo_mercadoria>]
   cXml += [<tipo_embarque>RODOVIARIO</tipo_embarque>]
   cXml += [<valor_mercadoria>1.200,00</valor_mercadoria>]
   cXml += [<placa>AAA1234</placa>]
   cXml += [<remet_nome>EMITENTE</remet_nome>]
   cXml += [<remet_cnpj>53.561.748/0001-20</remet_cnpj>]
   cXml += [<remet_cidade>Cotia</remet_cidade>]
   cXml += [<remet_uf>SP</remet_uf>]
   cXml += [<dest_nome>EMITENTE</dest_nome>]
   cXml += [<dest_cnpj>53.561.748/0001-20</dest_cnpj>]
   cXml += [<dest_cidade>Cotia</dest_cidade>]
   cXml += [<dest_uf>SP</dest_uf>]
   cXml += [<consig_nome>CONSIGNATÁRIO</consig_nome>]
   cXml += [<consig_cnpj>53.561.748/0001-20</consig_cnpj>]
   cXml += [<consig_cidade>Cotia</consig_cidade>]
   cXml += [<consig_uf>SP</consig_uf>]
   cXml += [</args>]
   cXml += [</urn:averbaCTe20>]
   cXml += [</soapenv:Body>]
   cXml += [</soapenv:Envelope>]

   cRetorno := MicrosoftXmlSoapPost( cXml, cSoapAction, cUrl )

   ? cRetorno
   RETURN

FUNCTION MicrosoftXmlSoapPost( cXmlSoap, cSoapAction, cWebService )
 LOCAL oServer, nCont, cRetorno := "*ERRO*", cXmlRetorno := ""
 BEGIN SEQUENCE WITH { |e| Break(e) }
   oServer := win_OleCreateObject( "MSXML2.ServerXMLHTTP")
   oServer:Open( "POST", cWebService, .F. )
   oServer:SetRequestHeader( "SOAPAction", cSoapAction )
   oServer:SetRequestHeader( "Content-Type", "application/soap+xml; charset=utf-8" )
   oServer:Send( cXmlSoap )
   oServer:WaitForResponse( 500 )
   cRetorno := oServer:ResponseBody
 ENDSEQUENCE
 IF ValType( cRetorno ) == "C"
   cXmlRetorno := cRetorno
 ELSEIF cRetorno == NIL
   cXmlRetorno := "*ERRO*"
 ELSE
   cXmlRetorno := ""
   FOR nCont = 1 TO Len( cRetorno )
    cXmlRetorno += Chr( cRetorno[ nCont ] )
   NEXT
 ENDIF
 RETURN cXmlRetorno
mensagem de retorno

Código: Selecionar todos

<?xml version="1.0" encoding="ISO-8859-1"?><SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" x
mlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.or
g/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><averbaCTe20Response><return
xsi:type="xsd:string"><MSGS>
  <ERRO>
    <NUMDOC>NF</NUMDOC>
    <SERIEDOC>NF</SERIEDOC>
    <FILIALDOC>NF</FILIALDOC>
    <LINHAARQ>NF</LINHAARQ>
    <ERRODETALHE>
      <CODIGO>900</CODIGO>
      <VALORENVIADO></VALORENVIADO>
      <VALORESPERADO></VALORESPERADO>
      <LIMITE></LIMITE>
      <DESCCOMPLETA>Usuario nao informado</DESCCOMPLETA>
    </ERRODETALHE>
  </ERRO>
</MSGS>
</return></averbaCTe20Response></SOAP-ENV:Body></SOAP-ENV:Envelope>
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Consumir Webservice ( SOAP )

Mensagem por JoséQuintas »

A minha versão final pra isso, e meus porquês:

SOAP da Microsoft em separado:
Já viu. É o mesmo desde a primeira vez, então melhor deixar separado porque tá pronto pra qualquer uso.

SOAP do envelope em separado:
Vai usar o mesmo pra todo projeto. Melhor deixar separado assim acertou um já acertou todos

XmlTag():
Pra mim ajuda a clarear o fonte da montagem, e evita errar no abre/fecha de tags.

Só como comentário adicional, é nesse estilo que fiz minha classe de NFE/CTE/MDFE/CCE.
Uma única rotina de SOAP, e uma única rotina de envelope, mas tudo na classe.

Código: Selecionar todos

PROCEDURE Main
   LOCAL cXml, cSoapAction, cWebservice, cOperation, cRetorno

   cWebservice := "http://homologacao.averba.com.br/webserver/index.soap"
   cSoapAction := [urn:ATMWebSvr#averbaCTe20]
   cOperation  := [averbaCTe20]

   cXml := ""
   cXml += [<args>]
   cXml += XmlTag( "usuario", "SEU_LOGIN" )
   cXml += XmlTag( "senha", "SUA_SENHA" )
   cXml += XmlTag( "emit_nome", "EMITENTE" )
   cXml += XmlTag( "emit_cnpj", "53.561.748/0001-20" )
   cXml += XmlTag( "emit_cidade", "Cotia" )
   cXml += XmlTag( "emit_uf", "SP" )
   cXml += XmlTag( "tipo_documento", "CTE" )
   cXml += XmlTag( "num_documento", "1" )
   cXml += XmlTag( "serie_documento", "1" )
   cXml += XmlTag( "data_emissao", "27/09/2013" )
   cXml += XmlTag( "tipo_mercadoria", "ARROZ" )
   cXml += XmlTag( "tipo_embarque", "RODOVIARIO" )
   cXml += XmlTag( "valor_mercadoria", "1.200,00" )
   cXml += XmlTag( "placa", "AAA1234" )
   cXml += XmlTag( "remet_nome", "EMITENTE" )
   cXml += XmlTag( "remet_cnpj", "53.561.748/0001-20" )
   cXml += XmlTag( "remet_cidade", "Cotia" )
   cXml += XmlTag( "remet_uf", "SP" )
   cXml += XmlTag( "dest_nome", "EMITENTE" )
   cXml += XmlTag( "dest_cnpj", "53.561.748/0001-20" )
   cXml += XmlTag( "dest_cidade", "Cotia" )
   cXml += XmlTag( "dest_uf", "SP" )
   cXml += XmlTag( "consig_nome", "CONSIGNATÁRIO" )
   cXml += XmlTag( "consig_cnpj", "53.561.748/0001-20" )
   cXml += XmlTag( "consig_cidade", "Cotia" )
   cXml += XmlTag( "consig_uf", "SP" )
   cXml += [</args>]

   cXml := SoapEnvelope( cXml, cOperation )

   cRetorno := MicrosoftXmlSoapPost( cXml, cSoapAction, cWebservice )

   ? cRetorno
   RETURN


FUNCTION XmlTag( cNome, cConteudo )
   IF Empty( cConteudo )
      RETURN "<" + cNome + " />"
   ENDIF
   RETURN "<" + cNome + ">" + cConteudo + "</" + cNome + ">"


FUNCTION SoapEnvelope( cXml, cOperation )
   LOCAL cXmlEnvelope
   cXmlEnvelope := ""
   cXmlEnvelope += [<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ] + ;
                   [xmlns:xsd="http://www.w3.org/2001/XMLSchema" ] + ;
                   [xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" ] + ;
                   [xmlns:urn="urn:xmethods-delayed-quotes">]
   cXmlEnvelope += [<soapenv:Header/>]
   cXmlEnvelope += [<soapenv:Body>]
   cXmlEnvelope += [<urn:] + cOperation + [ xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" ] + ;
                   [xmlns:xsd="http://www.w3.org/2001/XMLSchema" ] + ;
                   [xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ] + ;
                   [xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" ] + ;
                   [xmlns:tns="urn:ATMWebSvr" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" ] + ;
                   [xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" ] + ;
                   [xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="urn:ATMWebSvr">]
   cXmlEnvelope += [<service name="ATMWebSvr"><port name="ATMWebSvrPort" binding="tns:ATMWebSvrBinding">] + ;
                   [<soap:address location="http://homologacao.averba.com.br/webserver/index.soap"/></port></service>]
   cXmlEnvelope += cXml // aqui seu XML dentro do envelope
   cXmlEnvelope += [</urn:] + cOperation + [>]
   cXmlEnvelope += [</soapenv:Body>]
   cXmlEnvelope += [</soapenv:Envelope>]
   RETURN cXmlEnvelope



FUNCTION MicrosoftXmlSoapPost( cXmlSoap, cSoapAction, cWebService )
   LOCAL oServer, nCont, cRetorno := "*ERRO*", cXmlRetorno := ""
   BEGIN SEQUENCE WITH { |e| Break(e) }
      oServer := win_OleCreateObject( "MSXML2.ServerXMLHTTP")
      oServer:Open( "POST", cWebService, .F. )
      oServer:SetRequestHeader( "SOAPAction", cSoapAction )
      oServer:SetRequestHeader( "Content-Type", "application/soap+xml; charset=utf-8" )
      oServer:Send( cXmlSoap )
      oServer:WaitForResponse( 500 )
      cRetorno := oServer:ResponseBody
   ENDSEQUENCE
   IF ValType( cRetorno ) == "C"
      cXmlRetorno := cRetorno
   ELSEIF cRetorno == NIL
      cXmlRetorno := "*ERRO*"
   ELSE
      cXmlRetorno := ""
      FOR nCont = 1 TO Len( cRetorno )
        cXmlRetorno += Chr( cRetorno[ nCont ] )
      NEXT
   ENDIF
   RETURN cXmlRetorno
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
Alexandre Silva
Usuário Nível 3
Usuário Nível 3
Mensagens: 376
Registrado em: 26 Mar 2007 00:16
Localização: Itapema - SC

Consumir Webservice ( SOAP )

Mensagem por Alexandre Silva »

Muito obrigado
Ainda estou em testes
Vi que vc acrescentou, mais coisas no envelope:
xmlns:tns="
xmlns:wsd=
Isto deve ter feito a diferença...

Mas aqui, nao era para ter outro parametro ? xmethods-delayed-quotes

Código: Selecionar todos

cXmlEnvelope += [<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ] + ;
	                   [xmlns:xsd="http://www.w3.org/2001/XMLSchema" ] + ;
	                   [xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" ] + ;
	                   [xmlns:urn="urn:xmethods-delayed-quotes">]

Pergunta de iniciante.
No manual o conteudo do xml que vai dentro do envelope deve ter isso :
parts:
usuario: xsd:string
senha: xsd:string
codatm: xsd:string
xmlCTe: xsd:string

esses parametros, sao do Xml que vai. eu coloquei como está abaixo..
1-Nao vai esse xsd:string ?
2-Devo usar ![CDATA[' porque é um xml dentro dentro de outro xml..

Código: Selecionar todos

cxlido:=memoread('meux.xml')
cXml := ""
cXml += [<args>]
cXml += XmlTag( "usuario", "TESTES" )
cXml += XmlTag( "senha", "BASE" )
cXml += XmlTag( "codatm", "11340073" )
cxml +='<xmlCTe><![CDATA['
cxml +=cxlido
cxml +=']]>'
cxml +='</xmlCTe>'
cXml += [</args>]
* Clipper 5.2e/Gaspro 4.0 /CDX/Blinker 7.0 Harbour 3.2 Console Hbmk2
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Consumir Webservice ( SOAP )

Mensagem por JoséQuintas »

Eu entendo como funciona um SOAP, mas não sei como interpretar algumas coisas.
Por exemplo, essa parte tirei do manual do webservice, mas foi chute.
Ele mostra como é o XML de ida e de volta, mas não sei traduzir isso.

http://homologacao.averba.com.br/webser ... .soap?wsdl

Nessas horas um arquivo pronto, ou um bom manual ajudariam muito.
Como essas coisas foram para o envelope, usado na comunicação, não alteram o conteúdo do XML que interessa.

Imagine assim:
Um webservice SOAP é igual a uma LIB usada no Clipper/Harbour, com a diferença de que está na internet.
Pra usar uma função da LIB/Webservice, precisa saber o nome dela, e que parâmetros precisa passar pra função.
Acontece que cada programador tem seu estilo, então cada LIB/Webservice tem seu "jeito".
A única parte padrão em tudo que existe, é que tudo é feito por XML.
Cada LIB/Webservice de cada programador tem um estilo, então cada LIB/Webservice tem seu envelope particular, e sua exigência dentro do XML.

Eu aprendi esse conceito, que seria o mesmo pra fazer um programa usando LIB de terceiros.

A partir daí, cada nova LIB/Webservice vai ser um novo aprendizado sobre as particularidades.

Dá pra ter alguma ajuda olhando aquele manual do webservice, que todos os webservices acabam fornecendo automaticamente.
Mas precisa tempo e paciência pra entender cada um.

Se aprender direito o conceito de como funciona, pode até conversar com quem já fez PRA ESSE WEBSERVICE, sabendo do que vai precisar.
Como viu, nesse webservice, agora são 5 coisas:
- Operação SOAP que vai no envelope
- Operação SOAP (Soap Action) que vai na comunicação
- Endereço de comunicação
- Envelope
- XML interno

Por enquanto aparentemente os 4 primeiros estão resolvidos, já que houve a comunicação.
A mensagem de erro reclama de usuário/senha, e isso faz parte do ítem 5.
Então deixe os 4 como estão, e trabalhe somente no 5.

Tem horas que é mais fácil fazer como teste/erro, ainda mais quando existe ambiente de teste, que é o que está usando. (homologação=teste)
Pode brincar à vontade, desde que não faça um loop infinito mandando coisas sem parar.
É só olhar essa parte do retorno que contém o erro. (como deve ter percebido, o retorno também tem um envelope com particularidades, mas o que interessa está dentro dele, no "body" (corpo) do envelope)
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Consumir Webservice ( SOAP )

Mensagem por JoséQuintas »

Voltando a sua pergunta:

usuario: xsd:string
senha: xsd:string
codatm: xsd:string
xmlCTe: xsd:string

Isso é um manual do webservice.
xsd:string indica string, assim como na estrutura do DBF o "C" indica que o campo é caractere.

Por isso confunde sobre o que precisa ou não no XML, a não ser que entre fundo e aprenda como interpretar esse manual.
Isso eu não me interessei em aprender, então algumas coisas acabo indo no chute.
O melhor mesmo seria um exemplo pronto, com alguém que já fez, já que o manual que enviaram parece estar desatualizado.
Mas parece faltar pouco agora.

Ainda sobre esse manual do próprio webservice que indiquei:
Ele tem tudo misturado, de todas as funções/operações.

O que posso imaginar é:
averbaCTeRequest - faz parte do envio para o averbaCTe
averbaCTeResponse - faz parte da resposta do averbaCTe
averbaATMRequest - parametros comuns válidos pra envio
averbaATMResponse - parametros comuns válidos de retorno

E os parâmetros comuns, não quer dizer que cada um deles seja obrigatório.
Mas o formato de manual não é o mesmo formato de XML. Como percebeu, tem texto pra indicar o tipo de informação, e que não entra no xml de envio.
Pra mim que não sei interpretar esse tipo de manual, ele me confunde. Só mesmo quando não tem outra opção pra tirar dúvida.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
Alexandre Silva
Usuário Nível 3
Usuário Nível 3
Mensagens: 376
Registrado em: 26 Mar 2007 00:16
Localização: Itapema - SC

Consumir Webservice ( SOAP )

Mensagem por Alexandre Silva »

Agradeço todas essas orientaçoes..
estou vendo como a seguradora para obter um xml final com envelope, entao vou fazer e comparar..

Obrigado
* Clipper 5.2e/Gaspro 4.0 /CDX/Blinker 7.0 Harbour 3.2 Console Hbmk2
Avatar do usuário
Alexandre Silva
Usuário Nível 3
Usuário Nível 3
Mensagens: 376
Registrado em: 26 Mar 2007 00:16
Localização: Itapema - SC

Consumir Webservice ( SOAP )

Mensagem por Alexandre Silva »

Entao.. a seguradaora me mandu um XML, do jeito que eles querem...
apenas editei para colocar usuario e senha e codigo que eles usam..(ver anexo)

salvei em xml.. mandei ler e mandar..
retorna a mesma coisa <DESCCOMPLETA>Usuario nao informado</DESCCOMPLETA>
mesma mensagem que o Jose recebeu. entao tem algo faltando nessa rotina..

Eles me retornarem ..
O exemplo de envelope soap que te passamos foi testado com sucesso.
Sendo assim, verifique sua programação pois há alguma falha quanto a informação do usuário no envelope soap.


Por Favor me ajudem. :(

Código: Selecionar todos


function main()
cWebservice := "http://homologacao.averba.com.br/webserver/index.soap"
cSoapAction := [urn:ATMWebSvr#averbaCTe20]
cOperation  := [averbaCTe20]
cXml:=memoread('teste.xml')  // le como string
cRetorno := MicrosoftXmlSoapPost( cXml, cSoapAction, cWebservice )
HB_MemoWrit('retorno.xml',cRetorno)
? cRetorno
RETURN
 

FUNCTION MicrosoftXmlSoapPost( cXmlSoap, cSoapAction, cWebService )
LOCAL oServer, nCont, cRetorno := "*ERRO*", cXmlRetorno := ""
BEGIN SEQUENCE WITH { |e| Break(e) }
   oServer := win_OleCreateObject( "MSXML2.ServerXMLHTTP")
   oServer:Open( "POST", cWebService, .F. )
   oServer:SetRequestHeader( "SOAPAction", cSoapAction )
   oServer:SetRequestHeader( "Content-Type", "application/soap+xml; charset=utf-8" )
   oServer:Send( cXmlSoap )
   oServer:WaitForResponse( 500 )
   cRetorno := oServer:ResponseBody
ENDSEQUENCE
IF ValType( cRetorno ) == "C"
   cXmlRetorno := cRetorno
ELSEIF cRetorno == NIL
   cXmlRetorno := "*ERRO*"
ELSE
   cXmlRetorno := ""
   FOR nCont = 1 TO Len( cRetorno )
     cXmlRetorno += Chr( cRetorno[ nCont ] )
   NEXT
ENDIF
RETURN cXmlRetorno
Anexos
teste.xml
(8.6 KiB) Baixado 160 vezes
* Clipper 5.2e/Gaspro 4.0 /CDX/Blinker 7.0 Harbour 3.2 Console Hbmk2
Responder