How to format Savon Request for Cybersource SOAP API How to format Savon Request for Cybersource SOAP API ruby ruby

How to format Savon Request for Cybersource SOAP API


First let me say my knowledge of Ruby is minimal, so I can't help with the Savon client. But I did try your raw xml request, and realized that precisely the requestMessage ended up in the wrong namespace:

<data:requestMessage>

refers to xmlns:data="urn:schemas-cybersource-com:transaction-data:TransactionProcessor"

when it should be xmlns:data="urn:schemas-cybersource-com:transaction-data-1.129"

I see you have commented out the namespace parameter in your client initialization. That may be the way to set the namespace in case the client doesn't read it from the wsdl.

As per this answer you can specify different namespaces as needed.


Update

Ok, I think I got it to work. Take a look at this script:

require 'savon'soap_header = <<-HEREDOC         <wsse:Security>      <wsse:UsernameToken>    <wsse:Username>username</wsse:Username>    <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">transaction_key</wsse:Password>      </wsse:UsernameToken>    </wsse:Security>        HEREDOCclient = Savon.client(  wsdl: 'https://ics2wstest.ic3.com/commerce/1.x/transactionProcessor/CyberSourceTransaction_1.129.wsdl',  soap_header: soap_header,  env_namespace: 'soapenv',  element_form_default: :unqualified,  namespace: "urn:schemas-cybersource-com:transaction-data-1.129",  namespaces: {    "xmlns:wsse": "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"  },  pretty_print_xml: true,  #logger: Rails.logger,  log: true)message = {    merchantID: "merch_id",    merchantReferenceCode: rand(100),    billTo: {    firstName: "Saul",    lastName: "Goodman",    street1: "1295 Charleston Road",    city: "Mountain View",    state: "CA",    postalCode: "94043",    country: "US",    email: "test@example.com",    },    item: {    unitPrice: "50.00",    quantity: "1",    },    purchaseTotals: {    currency: "USD"    },    card: {    accountNumber: "4111111111111111",    expirationMonth: "12",    expirationYear: "2020"    },    ccAuthService: {      :@run => "true"    }}response = client.call(:run_transaction, message: message, :attributes => {              'xmlns' => 'urn:schemas-cybersource-com:transaction-data-1.129',})response.body[:response]

With this I'm getting Authentication failed as expected.So, a couple of things that were wrong:

  • The header definition should leave out the Header node, just start with the inner nodes (Security)

  • The run => true in ccAuthService is an attribute, not an inner node.

  • The whole namespacing mess of the requestMessage.