3

I'm experimenting with using Google Checkout and am having a problem posting to the checkout server. Here is my code:

XNamespace ns = XNamespace.Get("http://checkout.google.com/schema/2");

XDocument cart = new XDocument();
XElement rootElement = new XElement(ns + "checkout-shopping-cart",
    new XElement("shopping-cart",
        new XElement("items",
            new XElement("item",
                new XElement("item-name", "doodad"),
                new XElement("item-description", "Description for the doodad"),
                new XElement("unit-price", 9.99, new XAttribute("currency", "GBP")),
                new XElement("quantity", 1)
            )
         )
    )
);

cart.Add(rootElement);

string authKey = "111222333444:NOTAREALKEY";
authKey = EncodeToBase64(authKey);

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://checkout.google.com/cws/v2/Merchant/111222333444/merchantCheckout");

request.Method = "POST";
byte[] byteArray = Encoding.UTF8.GetBytes(cart.ToString());
request.ContentType = "application/xml; charset=UTF-8";
request.ContentLength = byteArray.Length;
request.Headers.Add("Authorization: Basic " + authKey);
request.Accept = "application/xml; charset=UTF-8";

Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();

HttpWebResponse response = (HttpWebResponse)request.GetResponse(); // Exception here!
dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
string responseText = reader.ReadToEnd();

reader.Close();
dataStream.Close();
response.Close();

When I call GetResponse(), I get a (400) Bad Request.

Any assistance on this would be gratefully received.

DavidGouge
  • 4,583
  • 6
  • 34
  • 46

3 Answers3

4

Your XML looks broken as Jon Skeet points out :-). In order to further aid debugging - there may be more information about the error in the response. WebException has a Response object that might have a more detailed error message that can be read by calling its GetResponseStream() method.

Duncan Smart
  • 31,172
  • 10
  • 68
  • 70
  • 1
    Aha! Thank you, the error in the WebException's Response did indeed point me in the right direction. (Although it may as well have said 'Dave, you're being an idiot!'). I was using a sandbox merchant ID, but the live url. Thanks ever so much for the help. – DavidGouge Jan 27 '10 at 15:05
2

Not knowing anything about the Google Checkout API, are you sure you don't need the namespace on each of those elements?

XElement rootElement = new XElement(ns + "checkout-shopping-cart",
    new XElement(ns + "shopping-cart"),
        new XElement(ns + "items",
                     // etc

That's certainly what the Checkout API guide suggests to me - note that "xmlns=..." means that's the namespace for this element and all descendant elements unless otherwise specified.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • I dont think so, according to the API docs: http://code.google.com/apis/checkout/developer/Google_Checkout_XML_API.html#checkout_integration_options – DavidGouge Jan 27 '10 at 14:12
  • @DavidGouge: I think you've missed the fact that it's xmlns="..." rather than xmlns:foo="...". – Jon Skeet Jan 27 '10 at 14:12
  • Not sure I follow, but having double checked the xml I'm generating, it seems I'm getting a blank namespace on the children of the root element. Wonder if that is causing the problems. doodad Description for the doodad 9.99 1 – DavidGouge Jan 27 '10 at 14:17
  • @DavidGouge: Yes, that's because you haven't specified a namespace - it's effectively "undoing" the xmlns="..." from the parent. Have you tried my suggestion? – Jon Skeet Jan 27 '10 at 14:20
  • Ok, I've added the 'ns + ' to each element (and also fixed a bug that was creating an empty 'shopping-cart' element) but I get the same Bad Request error. I'm starting to think that it's not the content of the post that's the problem as I would expect *a* response from google telling me it's rubbish. – DavidGouge Jan 27 '10 at 14:31
  • The fact that it's returning you "bad request" *is* telling you it's rubbish. That's the point of the bad request status code. Not including the namespaces may well not be the *only* problem, but I think it was *a* problem. – Jon Skeet Jan 27 '10 at 14:41
  • Thank you so much for the help. Seems it was a combination of the xml being incorrect and me using a sandbox merchant ID with the live url. Thanks very much for the help and the push in the right direction. :D – DavidGouge Jan 27 '10 at 15:07
0

You still can read response message, if exception is WebException. This will give you more information on what's wrong:

try {
   response = (HttpWebResponse)request.GetResponse();
}
catch (WebException ex1) {
   response = ex1.Response();
}
Tomas Kirda
  • 8,347
  • 3
  • 31
  • 23