Question

While I've integrated several payment processors and shopping carts in the past, this Google Checkout API integration is not going well for me. I get a 400 response from Google, even when I use the diagnostic link. I'm sure something's wrong in my URL, but I can't seem to figure out what. I'm using a sandbox Merchant ID and Key.

Can someone help me see what I'm doing to get this 400 response, please?

I am using Java and posting from a server thus I'm calling the server to server API link:

https://sandbox.google.com/checkout/api/checkout/v2/merchantCheckout/Merchant/%SANDBOXID%

<?xml version="1.0" encoding="UTF-8"?>
<checkout-shopping-cart xmlns="http://checkout.google.com/schema/2">
    <shopping-cart>
        <merchant-private-data>
            <merchant-note>8Ra8fw4tBaOdP4v3lseykKO6crR0dFqhzWV0EmqKuVuQaN1w0mcScAAR71pbexXlVnrwpP8wNzehuc7wz3KO9JM6xfedW8106olarCZcZBs=</merchant-note>
        </merchant-private-data>
        <items>
            <item-name>MyName : MySubname</item-name>
            <item-description>Weigh in on this year's...</item-description>
            <unit-price currency="USD">100</unit-price>
            <quantity>1</quantity>
         </items>
     </shopping-cart>
</checkout-shopping-cart>

I am using Java to post this data. In the code below, the url above is sandboxLink in the code and checkReq is the XML post...

    public static String postCheckoutReqData(String userID, String gameName, boolean test) {

    String checkRequest = GoogleCheckoutXML.getCheckoutRequestXML(userID, gameName);

    if(checkRequest.indexOf("error,") != -1) return checkRequest;

    URL url = null;
    try {           
        String baseCodeString;          
        if(test) {
            url = new URL(GoogleCheckoutXML.sandboxLink + GoogleCheckoutXML.sandboxMerchID);
            baseCodeString = GoogleCheckoutXML.sandboxMerchID + ":" + GoogleCheckoutXML.sandboxMerchKey;
        }
        else {
            url = new URL(GoogleCheckoutXML.productionLink + GoogleCheckoutXML.merchantID);
            baseCodeString = GoogleCheckoutXML.merchantID + ":" + GoogleCheckoutXML.merchantKey;
        }
        //url = new URL(GoogleCheckoutXML.diagnose);
        byte[] bytes = (baseCodeString.getBytes());
        baseCodeString = new Base64().encodeAsString(bytes);
        URLConnection conn = url.openConnection();          
        conn.setDoOutput(true);
        conn.setRequestProperty("Authorization", "Basic " + baseCodeString);
        conn.setRequestProperty("Content-Type", "application/xml; charset=UTF-8");
        conn.setRequestProperty("Accept", "application/xml; charset=UTF-8");

        OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
        wr.write(checkRequest);
        wr.flush();

        // Get the response
        BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        String line;
        while ((line = rd.readLine()) != null) {
            line = line + rd.readLine();
        }

        wr.close();
        rd.close();
        return line;
    } 
    catch (Exception e) {   
        e.printStackTrace();
        return "error,Purchase Error posting communcation failed";
    }

The actual stack trace in Tomcat is:

java.io.IOException: Server returned HTTP response code: 400 for URL: https://sandbox.google.com/checkout/api/checkout/v2/merchantCheckout/Merchant/[withheld]
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1612)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
at com.[withheld]..GoogleCheckoutXML.postCheckoutReqData(GoogleCheckoutXML.java:194)
at com.[withheld]...l.getCheckoutLink(DubQueryImpl.java:270)
at com.[withheld]....GenerateCheckoutLinkServlet.doGet(GenerateCheckoutLinkServlet.java:56)
at com.[withheld]...doPost(GenerateCheckoutLinkServlet.java:73)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1001)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
Was it helpful?

Solution

I think I've solved a similar issue - it may, or may not, be yours ...

  1. Check the return code:

    int code = conn.getResponseCode(); // Integer (would be 400 in the case you give above) \String msg = conn.getResponseMessage(); // String (would be "Bad Request" in the case you give above

  2. Check for further details

    InputStream in = new BufferedInputStream(conn.getErrorStream());

    Read in to see what further information is being provided - I have found it to be quite helpful!

  3. In my case, my carefully prepared xml was losing the quotation marks somewhere along the way, trashing the <xml version="1.0" ... > right at the start and wreaking havoc from then onwards ...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top