SOAP на Rails, не может вызвать метод с WSDL, используя Savon
Я хочу использовать веб-сервис финансового учреждения для "verifyTransaction". Метод получает две строки в качестве входных данных и возвращает double в качестве выходных данных.
double verifyTransaction (
String RefNum,
String MerchantID
)
Я использовал Savon в rails 3.1 для вызова метода.
client = Savon::Client.new do |wsdl|
wsdl.document = "https://acquirer.sb24.com/ref-payment/ws/ReferencePayment?WSDL"
end
response = client.request :wsdl, "verifyTransaction" do
soap.body ={"RefNum" => "ReferenceNumber", "MerchantID" => "MymerchantId"}
end
но я получил эту ошибку:
Savon::SOAP::Fault ((env:Client) caught exception while handling request: unexpected encoding style: expected=http://schemas.xmlsoap.org/soap/encoding/, actual=)
Есть мысли о том, как это решить?
2 ответа
Я решил проблему с помощью SoapUI.
Я открыл WSDL в SoapUI, сгенерировал пример запросов и скопировал / вставил его в Savon следующим образом:
client = Savon::Client.new do |wsdl|
wsdl.document = "https://acquirer.sb24.com/ref-payment/ws/ReferencePayment?WSDL"
end
response = client.request "verifyTransaction" do
soap.xml = 'XML will be here'
end
Работало нормально!:)
Поскольку у меня нет действительной информации, чтобы на самом деле попробовать это, все, что я смог сделать, - это вернуть HTTP 400 вместо другого перечисленного сбоя SOAP или ответа 500 от службы.
Савон был настроен только с основами:
client = Savon::Client.new do
wsdl.document = "https://acquirer.sb24.com/ref-payment/ws/ReferencePayment?WSDL"
end
Разница, которую я обнаружил, заключалась в указании пространства имен для конкретного запроса. Измените: wsdl на "urn: Foo".
[26] pry(main)> client.request "urn:Foo", :verify_transaction do
[26] pry(main)* soap.body = { "RefNum" => "1", "MerchantID" => "1" }
[26] pry(main)* end
Отладка вывода из запроса:
D, [2011-10-31T09:05:17.202044 #1784] DEBUG -- : SOAP request: https://acquirer.sb24.com/ref-payment/ws/ReferencePayment
D, [2011-10-31T09:05:17.202314 #1784] DEBUG -- : SOAPAction: "verifyTransaction", Content-Type: text/xml;charset=UTF-8, Content-Length: 322
D, [2011-10-31T09:05:17.202414 #1784] DEBUG -- : <?xml version="1.0" encoding="UTF-8"?><env:Envelope xmlns:urn:Foo="urn:Foo" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ins0="urn:Foo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"><env:Body><urn:Foo:verifyTransaction><MerchantID>1</MerchantID><RefNum>1</RefNum></urn:Foo:verifyTransaction></env:Body></env:Envelope>
D, [2011-10-31T09:05:17.202574 #1784] DEBUG -- : HTTPI executes HTTP POST using the httpclient adapter
D, [2011-10-31T09:05:18.780446 #1784] DEBUG -- : SOAP response (status 400):
D, [2011-10-31T09:05:18.780669 #1784] DEBUG -- :
Savon::HTTP::Error:
from /usr/local/rvm/gems/ruby-1.8.7-p334/gems/savon-0.9.7/lib/savon/soap/response.rb:100:in `raise_errors'
Более длинное объяснение
Вот как я придумал формат выше.
Пространство имен может быть важным для некоторых служб. Внимательно посмотрев на wsdl, это фактическое действие, которое используется, поскольку ссылка на порт - это порт "PaymentIF":
<message name="PaymentIF_verifyTransaction">
<part name="String_1" type="xsd:string"/>
<part name="String_2" type="xsd:string"/>
</message>
В определении порта фактическое сообщение упоминается как "tns:PaymentIF_verifyTransaction":
<portType name="PaymentIF">
...
<operation name="verifyTransaction" parameterOrder="String_1 String_2">
<input message="tns:PaymentIF_verifyTransaction"/>
<output message="tns:PaymentIF_verifyTransactionResponse"/>
</operation>
...
</portType>
Итак, оглядываясь назад снова, пространство имен "tns":
xmlns:tns="urn:Foo"