Well hello Simon!
It looks like Authorize.NET updated their service with new fields but forgot to add them to the WSDL.
This is a sample request that I sent (intercepted using Fiddler):
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPo3vYq2eC/5VIuiUcm2hEtw8AABBBJr/dLQF7z02Y7UKwphq24W1n9j0XlQ1MiAlOjy5fO14ACQAA</VsDebuggerCausalityData>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<GetCustomerProfile xmlns="https://api.authorize.net/soap/v1/">
<merchantAuthentication>
<name>95U6bwXXXXX</name>
<transactionKey>8tf62gV7XXXXXX</transactionKey>
</merchantAuthentication>
<customerProfileId>37745529</customerProfileId>
</GetCustomerProfile>
</s:Body>
</s:Envelope>
This is the response:
<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>
<GetCustomerProfileResponse xmlns="https://api.authorize.net/soap/v1/">
<GetCustomerProfileResult>
<resultCode>Ok</resultCode>
<messages>
<MessagesTypeMessage>
<code>I00001</code>
<text>Successful.</text>
</MessagesTypeMessage>
</messages>
<profile>
<merchantCustomerId>33938</merchantCustomerId>
<email>4691705@EXAMPLE.COM</email>
<customerProfileId>37745529</customerProfileId>
<paymentProfiles>
<CustomerPaymentProfileMaskedType>
<billTo>
<firstName>TEST</firstName>
<lastName>USER</lastName>
<company>Defender Razor</company>
<address>1 RODEO DRIVE</address>
<city>BEVERLY HILLS</city>
<state>CA</state>
<zip>90210</zip>
<country>UNITED STATES</country>
</billTo>
<customerProfileId>0</customerProfileId>
<customerPaymentProfileId>34313485</customerPaymentProfileId>
<payment>
<creditCard>
<cardNumber>XXXX5108</cardNumber>
<expirationDate>XXXX</expirationDate>
</creditCard>
</payment>
</CustomerPaymentProfileMaskedType>
</paymentProfiles>
</profile>
</GetCustomerProfileResult>
</GetCustomerProfileResponse>
</soap:Body>
</soap:Envelope>
Everything here is correct - as you can see the payment
node is being sent correctly.
However - with .NET deserialization the order of attributes matters - as specified in the generated References.cs
file.
[System.Xml.Serialization.XmlElementAttribute(Order=0)]
It turns out that two new fields were added to the response billTo
and customerProfileId
but they weren't added to the WSDL.
So when trying to deserialize the field billTo
is found but that isn't what was expected - so everything ends up null.
If you add these two lines (and be careful to add them to exactly this type) then you can regenerate the references.cs file (by right clicking on the service reference and regenerating the file).
If you were generating your proxy from the URL https://api.authorize.net/soap/v1/Service.asmx?WSDL
then you will need to download this file locally as Service.wsdl
and generate the proxy from there.
<s:element minOccurs="1" maxOccurs="1" name="billTo" type="tns:CustomerAddressType"/>
<s:element minOccurs="1" maxOccurs="1" name="customerProfileId" type="s:long" />
<s:complexType name="CustomerPaymentProfileMaskedType">
<s:complexContent mixed="false">
<s:extension base="tns:CustomerPaymentProfileBaseType">
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="billTo" type="tns:CustomerAddressType"/>
<s:element minOccurs="1" maxOccurs="1" name="customerProfileId" type="s:long" />
<s:element minOccurs="1" maxOccurs="1" name="customerPaymentProfileId" type="s:long" />
<s:element minOccurs="0" maxOccurs="1" name="payment" type="tns:PaymentMaskedType" />
<s:element minOccurs="0" maxOccurs="1" name="driversLicense" type="tns:DriversLicenseMaskedType" />
<s:element minOccurs="0" maxOccurs="1" name="taxId" type="s:string" />
</s:sequence>
</s:extension>
</s:complexContent>
</s:complexType>
I lost over 12 hours of payments before this was detected. Fortunately I have the customer's emails but this was very bad. You can't just add fields to a response where the order matters. And even worse than that you can't just forget to add them to the WSDL.
This was the quick fix for me. I may switch to using the proper API at some point - and I've reported this to Authorize.net hoping they may respond too.
This is the differences in References.cs after I made my change. As you can see the Order
property has been incremented :
