4

I'm trying to communicate with a soap service and I know that I should send a SOAP Envelope like this:

POST /webpay_test/SveaWebPay.asmx HTTP/1.1
Host: webservices.sveaekonomi.se
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "https://webservices.sveaekonomi.se/webpay/CreateOrder"

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <CreateOrder xmlns="https://webservices.sveaekonomi.se/webpay">
      <request>
        <Order>
          <ClientOrderNr>string</ClientOrderNr>
          <CustomerReference>string</CustomerReference>
          <OrderDate>dateTime</OrderDate>
          <CountryCode>string</CountryCode>
          <SecurityNumber>string</SecurityNumber>
          <CustomerEmail>string</CustomerEmail>
          <IsCompany>boolean</IsCompany>
          <PreApprovedCustomerId>long</PreApprovedCustomerId>
          <AddressSelector>string</AddressSelector>
        </Order>
        <InvoiceRows>
          <ClientInvoiceRowInfo>
            <ArticleNr>string</ArticleNr>
            <Description>string</Description>
            <PricePerUnit>double</PricePerUnit>
            <NrOfUnits>double</NrOfUnits>
            <Unit>string</Unit>
            <VatPercent>int</VatPercent>
            <DiscountPercent>int</DiscountPercent>
            <ClientOrderRowNr>int</ClientOrderRowNr>
          </ClientInvoiceRowInfo>
          <ClientInvoiceRowInfo>
            <ArticleNr>string</ArticleNr>
            <Description>string</Description>
            <PricePerUnit>double</PricePerUnit>
            <NrOfUnits>double</NrOfUnits>
            <Unit>string</Unit>
            <VatPercent>int</VatPercent>
            <DiscountPercent>int</DiscountPercent>
            <ClientOrderRowNr>int</ClientOrderRowNr>
          </ClientInvoiceRowInfo>
        </InvoiceRows>
      </request>
    </CreateOrder>
  </soap:Body>
</soap:Envelope>

here is the code I've wrote:

client = Savon::Client.new("https://webservices.sveaekonomi.se/webpay_test/SveaWebPay.asmx?wsdl")
res = client.create_order do |soap|  
    soap.namespace = "https://webservices.sveaekonomi.se/webpay_test/CreateOrder.asmx"
    soap.body = { :auth         => {  :username => "username", :password => "pass", :client_number => "1111" }, 
                  :order        => {  :client_order_nr => "1000000", :customer_reference => "4212", :order_date => Date.today, 
                                      :country_code => "SE", :security_number => "1111111111", :is_company => false, 
                                      :customer_email => "me@gmail.com", :pre_approved_customer_id => 0 },
                  :invoice_rows => { :client_invoice_row_info => { :article_nr => "x100", :description => "something cool -- description",
                                      :price_per_unit => 100, :nr_of_units => 3, :unit => "SEK", :vat_percent => 25,
                                      :discount_percent => 0, :client_order_row_nr => "1"},
                                     :client_invoice_row_info => { :article_nr => "x200", :description => "something cooler -- description",
                                      :price_per_unit => 200, :nr_of_units => 2, :unit => "SEK", :vat_percent => 25,
                                      :discount_percent => 0, :client_order_row_nr => "1" }  
                                   }
    }
end

and it generates this, which is different from what I have as the template and that's why I'm getting an error:

<?xml version="1.0" encoding="UTF-8"?><env:Envelope xmlns:wsdl="https://webservices.sveaekonomi.se/webpay_test/CreateOrder.asmx" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Body>
<wsdl:CreateOrder>
<invoiceRows>
  <clientInvoiceRowInfo>
    <clientOrderRowNr>1</clientOrderRowNr>
    <pricePerUnit>200</pricePerUnit>
    <nrOfUnits>2</nrOfUnits>
    <unit>SEK</unit>
    <vatPercent>25</vatPercent>
    <articleNr>x200</articleNr>
    <discountPercent>0</discountPercent>
    <description>something cooler -- description</description>
  </clientInvoiceRowInfo>
</invoiceRows>
<order>
    <customerEmail>me@gmail.com</customerEmail>
    <preApprovedCustomerId>0</preApprovedCustomerId>
    <countryCode>SE</countryCode>
    <clientOrderNr>1000000</clientOrderNr>
    <securityNumber>11111111</securityNumber>
    <customerReference>4212</customerReference>
    <isCompany>false</isCompany>
    <orderDate>2010-06-28</orderDate>
</order>
<auth>
    <password>pass</password>
    <clientNumber>1111</clientNumber>
    <username>username</username>
</auth>
</wsdl:CreateOrder>
</env:Body>
</env:Envelope>

and here is the response:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Body>
    <CreateOrderResponse xmlns="https://webservices.sveaekonomi.se/webpay">
      <CreateOrderResult>
        <Accepted>false</Accepted>
        <ErrorMessage>Failed to create or authorize order</ErrorMessage>
        <SveaOrderNr>0</SveaOrderNr>
        <RejectionCode>Error</RejectionCode>
        <WillBuyInvoices xsi:nil="true" />
        <AuthorizeId>0</AuthorizeId>
        <AuthorizedAmount xsi:nil="true" />
        <ExpirationDate xsi:nil="true" />
      </CreateOrderResult>
    </CreateOrderResponse>
  </soap:Body>
</soap:Envelope>

could anyone tell me how can I solve this problem. and since I'm a newbie when it comes to SOAP would you also tell me if the order of the xml tags in the soap:Body tag is important or not?

Allen Bargi
  • 14,674
  • 9
  • 59
  • 58

2 Answers2

9

Thanks to Steve, I found "Why is “wsdl” namespace interjected into action name when using savon for ruby soap communication?" where Nick and Steve were talking about a similar problem.

Like Nick, my problem was in the way Savon is cooking up a SOAP envelope. As recommended by Nick, I ended up monkey patching a couple of methods in the Savon SOAP class. It's in lib/savon/soap.rb and I'm good to go now.

I'm a novice when it comes to SOAP and it's my first time writing a SOAP client, but honestly it SUCKS! I still remember my first time writing a client for a REST service and gosh it was fun.

REST ROCKS, SOAP SUCKS. that's all!

Community
  • 1
  • 1
Allen Bargi
  • 14,674
  • 9
  • 59
  • 58
3

You are missing the <request> element.

Try replacing your soap.body with a single hash with a key of ::request and a value of the existing hash record that you have already.


EDIT 1:

Your namespace line within your code should be "https://webservices.sveaekonomi.se/webpay" not the full URL you have there currently.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Steve Weet
  • 28,126
  • 11
  • 70
  • 86
  • Thanks for mentioning that. I added the request tag, but I still get the error. one thing is that savon generate env tags while the it should be soap tags. although both are sharing the same xmlns attribute? could it be the source of problm? the other thing is on CreateOrder tag. the specification asked for something like while the savon is generating some like this – Allen Bargi Jun 29 '10 at 10:21
  • Edited with another possible issue. – Steve Weet Jun 29 '10 at 11:31