Windows DevCenter    
 Published on Windows DevCenter (http://www.windowsdevcenter.com/)
 See this if you're having trouble printing code examples


Build a .NET App for Google Checkout

by Martin Omander
01/09/2007

Google Checkout is a new service designed to make online shopping faster, safer, and more convenient by integrating with sites to help people pay for goods and services online. In this article, I'll explain how Google Checkout works, give you an overview of its API, and then show you how to develop an application for it using .NET. I've also included sample code for the application. (Full disclosure: I work for Google, where I help large merchants integrate with Google Checkout.)

To start, let's take Google Checkout for a spin. Buy.com is one of the merchants that have integrated with Checkout. If you go to Buy.com's website, put an item in your shopping basket, and click the Checkout link, you will see two ways of completing the purchase (Figure 1). You can either use Buy.com's regular checkout process, or you can use Google's Checkout.

Figure 1
Figure 1: Google Checkout, integrated with Buy.com

If you click the Google Checkout button, you are taken to Google's website, where you can either log in or create a Google account (Figure 2). Once you have logged in, you can choose your shipping method, shipping address, and which credit card to pay with. Finally, as shown in Figure 3, you are asked to confirm your selections and place the order.

Figure 2
Figure 2: Google Checkout

Figure 3
Figure 3: Placing an order with Google Checkout

In other words, Google Checkout is an alternative checkout process, not a form of payment. Once a customer has created a Google account, she doesn't have to keep filling in credit card numbers and addresses on different merchants' websites, because Google has that information on file. She also doesn't have to remember login details for dozens of different merchant websites. And her credit card number is safer because Google doesn't share it with merchants.

What's in It for the Merchant?

First of all, merchants who offer Checkout get a Checkout shopping cart symbol in their AdWords ads (Figure 4). This symbol, and customers' knowledge of how fast and secure Checkout is, is designed to result in a higher conversion rate and more repeat business.

Figure 4
Figure 4: The Google Checkout shopping cart symbol

As I was writing this article, Google announced that there will be no processing fees for merchants during all of 2007. On January 1, 2008, Google will start charging a transaction fee of 2 percent plus 20 cents per transaction. But if the merchant is using AdWords, he will get $10 worth of sales processed for free for every $1 he spends on AdWords. For example, if the merchant is spending $1,000 on AdWords per month, he will get the first $10,000 worth of Checkout orders processed for free every month.

Finally, merchants using Checkout will be protected by Google's fraud prevention efforts. Google's fraud prevention tools stop invalid orders from reaching the merchant. And Google's Payment Guarantee policy helps protect merchants from chargebacks.

This article is about technology and not marketing, so I won't go into more detail here. Anyone who wants more business info about Checkout from a merchant's point of view can go to https://checkout.google.com/sell.

Checkout API Overview

The Checkout API consists of four major components:

  1. Cart posting API
  2. Notifications API
  3. Order processing API
  4. Merchant-calculation callback API

Cart Posting API

This is the only mandatory component of the API. That is, if you as a merchant want to implement the bare minimum of integration, this is it. Cart posting is the mechanism through which a customer is taken from the merchant's website to Google, and by which the customer's shopping cart contents come with her.

There are two ways of posting carts to Google. The preferred approach when using ASP.NET is this:

  1. Display the Google Checkout button to the customer on a web page.
  2. When the customer clicks the button, compose a <checkout-shopping-cart> XML document with the customer's items in it.
  3. Do a server-to-server post from the merchant's server to Google.
  4. Google will reply with a <checkout-redirect> XML document.
  5. Redirect the customer to the URL found in the <checkout-redirect> document.

This is all that is needed for Checkout integration. The merchant will be notified by email when orders are placed. He can see all orders when he logs in to Google Checkout. From there he can also charge orders, mark them as shipped, cancel orders, and issue refunds.

The other approach is to encrypt and sign the shopping cart XML and send it to the customer's browser as part of a web form. The customer will then post that form to Google. This is easy to implement in classic ASP, PHP, JSP, etc. But as ASP.NET pages post forms back to themselves, the first approach is cleaner to implement with .NET. This second approach will not be discussed further in this article.

Notification API

Processing orders manually is fine if you have a dozen orders per day. But it quickly becomes hard to manage as your order volume grows. If you have larger volume than that, you probably have an order database as well. And you want Checkout orders to automatically be copied into that database, rather than having to type them in by hand. This is where notifications come in.

As a merchant, you can specify a URL to which Google will post XML messages when significant events occur. These significant events are:

The new order notification contains XML for the order, including items, billing address, and shipping address. You can use this notification to copy the order data into your own order database. The other notifications can be used to keep order state in your database in sync with order state in Google's database.

Order Processing API

Implementing the Notification API eliminates the need for manually keeping your order database in sync with Google's. But you would still have to click a button on Google's website for every order you want to charge or cancel. If you already have an order management system, you probably want to charge Checkout orders automatically when your system marks them as ready for charging.

This is where the order processing API comes in. With this API, you can:

Merchant-Calculation Callback API

This is the final, and least used, optional component. You need it if you have complex shipping rules or tax rules, or if you accept certain types of coupons or gift certificates.

This API works by posting XML to a URL of your choice while the customer is on Google's Checkout page. For example, if the customer enters a gift certificate code, Google will post XML to your system and you are expected to reply with a result indicating whether the gift certificate code was valid, as well as its dollar value. You can also request that the customer's shipping address be sent to your system in the same manner, so you can calculate shipping cost and sales tax.

Because the merchant-calculated API is quite complex, it will be the subject of its own article.

Design Considerations for the .NET Sample Code

Google provides sample code in several different languages for integrating with Checkout. This sample code is meant to give merchants a running start when integrating their own systems with Checkout.

When writing the .NET sample code, I tried to take these factors into account:

Sample Code Overview

The code is open source and available with Subversion from https://google-checkout-dotnet-sample-code.googlecode.com/svn.

The heart of the code, but also the file you are the least likely to edit, is apiv2.cs. That file contains the autogenerated classes that compose and parse XML. The file was created from Google's Checkout XSD file using the tool xsd.exe, which is part of the .NET SDK.

As a quick recap, XSD stands for XML Schema Definition. XSD files describe the structure of XML documents. For example, Google's Checkout XSD file describes an element named <item> that is used for describing an individual order line in an order, among others. The XSD file tells us that the <item> element must contain subelements named <item-name> and <item-description>, and that these subelements are strings.

Most modern programming environments have tools that generate code based on XSD files. The generated code can compose and parse XML, so the developer only has to work with objects, not actual XML strings. For example, the generated code contains a class called Item with the string properties ItemName and ItemDescription.

The sample code project contains three folders, one for posting carts, one for the order processing API, and one for the merchant-calculation Callback API. The Notification API does not have its own folder because it turns out no extra classes are needed beyond the generated ones. We will see how this works later in this article.

Examples of How To Use the .NET Sample Code

After a lot of talk, it's finally time to try out the .NET sample code for Checkout. If you want to follow along at home, you need to first take these two steps:

  1. Download the sample code. You can either download the full source code using SVN from https://google-checkout-dotnet-sample-code.googlecode.com/svn, or you can get the compiled DLL file from http://code.google.com/apis/checkout/samplecode.html.
  2. Create a Sandbox merchant account. Sandbox is Google Checkout's test environment. It works like the Production environment, except that credit cards are not charged. The Sandbox registration process starts here: https://sandbox.google.com/sell.
Posting A Cart

First, the .NET code needs to know whether to hit Sandbox or Production, as well as which merchant account to add the order to. Add these keys to your web.config file:

<add key="GoogleEnvironment" value="Sandbox" />
<add key="GoogleMerchantID"  value="X" />
<add key="GoogleMerchantKey" value="Y" />

To find X and Y, log in to your Sandbox merchant account, click the Settings tab, and then click the Integration link; see Figure 5.

Figure 5
Figure 5: Finding the X and Y values

If you already have a web-based storefront, your shopping cart page is a good place to add a Google Checkout button. Drop the GCheckout.dll file into your web application's bin directory and add these page directives at the top of the cart ASPX page:

<%@ Import Namespace="GCheckout.Checkout" %>
<%@ Import Namespace="GCheckout.Util" %>
<%@ Register TagPrefix="cc1" Namespace="GCheckout.Checkout" Assembly="GCheckout" %>

Then you are ready to add the Checkout button itself:

<cc1:GCheckoutButton id="GCheckoutButton1" onclick="PostCartToGoogle" runat="server"/>

If you don't have a <form> tag on the page already, make sure you put one in around the CheckoutButton tag. Then you need to implement the method that will be called when the user clicks the Checkout button. This is the value of the GCheckoutButton tag's onclick attribute--PostCartToGoogle in the example above.

private void PostCartToGoogle(object sender, System.Web.UI.ImageClickEventArgs e) {
  CheckoutShoppingCartRequest Req = GCheckoutButton1.CreateRequest();
  Req.AddItem("Mars bar", "Packed with peanuts", 0.75m, 2);
  Req.AddFlatRateShippingMethod("SuperSaver", 2.50m);
  Req.AddFlatRateShippingMethod("Standard Ground", 5.00m);
  Req.AddStateTaxRule("CA", 0.0875, true);
  GCheckoutResponse Resp = Req.Send();
  Response.Redirect(Resp.RedirectUrl, true);
}

This code creates a CheckoutShoppingCartRequest object and adds a single order line (two Mars bars at 75 cents each) to it. Then two shipping options are added (SuperSaver for $2.50 and Standard Ground for $5.00) and a tax rule saying that California residents will be charged 8.75 percent sales tax. Finally the CheckoutShoppingCartRequest is sent to Google. Google logs the order and returns the URL to which the user should be redirected.

If you point your browser to your local cart page and click the Checkout button, you will see a page from Google's Sandbox environment (Figure 6.)

Figure 6
Figure 6: A page from the Google Sandbox environment

If you log in or create a new account, Google will show you the shipping options and add sales tax if your currently selected shipping address is in California (Figure 7). You will also see the Place Order button. Feel free to click it. This is the Sandbox environment, so your credit card won't be charged.

Figure 7
Figure 7: Shipping options and sales tax being added

This is the bare minimum Checkout integration. All you have to do to start selling is to create a Production merchant account (by going to http://checkout.google.com/sell), put that account's ID and key in web.config, and set GoogleEnvironment to Production in web.config. You can now accept real orders! If you want more of an industrial-strength integration, read on.

Notification API

Merchants integrate with this API to automatically transfer Google Checkout orders and order statuses into their existing order database. To do this in .NET, create an ASPX page that will accept the notifications from Google. Then tell Google the URL of that page by logging in to your merchant account and entering the URL into the API callback URL text field. Make sure the callback method is set to XML (Figure 8).

Figure 8
Figure 8: Making sure the callback method is set to XML

Now let's write the page that will receive the notifications from Google. Here is a good start:

<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="GCheckout" %>
<%@ Import Namespace="GCheckout.AutoGen" %>
<%@ Import Namespace="GCheckout.Util" %>
<script runat="server" language="c#">

  void Page_Load(Object sender, EventArgs e) {
    // Extract the XML from the request.
    Stream RequestStream = Request.InputStream;
    StreamReader RequestStreamReader = new StreamReader(RequestStream);
    string RequestXml = RequestStreamReader.ReadToEnd();
    RequestStream.Close();
    // Act on the XML.
    switch (EncodeHelper.GetTopElement(RequestXml)) {
      case "new-order-notification":
        NewOrderNotification N1 = (NewOrderNotification) EncodeHelper.Deserialize(RequestXml, typeof(NewOrderNotification));
        string OrderNumber1 = N1.googleordernumber;
        string ShipToName = N1.buyershippingaddress.contactname;
        string ShipToAddress1 = N1.buyershippingaddress.address1;
        string ShipToAddress2 = N1.buyershippingaddress.address2;
        string ShipToCity = N1.buyershippingaddress.city;
        string ShipToState = N1.buyershippingaddress.region;
        string ShipToZip = N1.buyershippingaddress.postalcode;
        foreach (Item ThisItem in N1.shoppingcart.items) {
          string Name = ThisItem.itemname;
          int Quantity = ThisItem.quantity;
          decimal Price = ThisItem.unitprice.Value;
        }
        break;
      default:
        break;
    }
  }

</script>
<?xml version="1.0" encoding="UTF-8"?>
<notification-acknowledgment xmlns="http://checkout.google.com/schema/2"/>

The Page_Load() method starts by reading the XML sent from Google. Notice that Google does not use SOAP, so you can't leverage the .NET framework for converting SOAP messages to method calls. Google uses HTTP POST to send XML to merchants, with the XML in the payload of the HTTP packet. So you have to open a stream to read the XML.

Once that has been done, there is a switch statement with a case for each type of notification. So far, only the new-order-notification has been implemented. When such a notification is received, a NewOrderNotification object is created. You can read useful data from this object, like order number and shipping address of the order. You can also loop over the individual order lines. After that, you have all the data needed to create an order record in your existing order database. That's all it takes to automatically transfer newly placed orders from Checkout to your existing system.

The new-order-notification is only one of the notifications Google sends to merchants. Here are case statements for the others, suitable for putting in the switch statement in the code above.

      case "risk-information-notification":
        RiskInformationNotification N2 = (RiskInformationNotification) EncodeHelper.Deserialize(RequestXml, typeof(RiskInformationNotification));
        // This notification tells us that Google has authorized the order and it has passed the fraud check.
        // Use the data below to determine if you want to accept the order, then start processing it.
        string OrderNumber2 = N2.googleordernumber;
        string AVS = N2.riskinformation.avsresponse;
        string CVN = N2.riskinformation.cvnresponse;
        bool SellerProtection = N2.riskinformation.eligibleforprotection;
        break;
      case "order-state-change-notification":
        OrderStateChangeNotification N3 = (OrderStateChangeNotification) EncodeHelper.Deserialize(RequestXml, typeof(OrderStateChangeNotification));
        // The order has changed either financial or fulfillment state in Google's system.
        string OrderNumber3 = N3.googleordernumber;
        string NewFinanceState = N3.newfinancialorderstate.ToString();
        string NewFulfillmentState = N3.newfulfillmentorderstate.ToString();
        string PrevFinanceState = N3.previousfinancialorderstate.ToString();
        string PrevFulfillmentState = N3.previousfulfillmentorderstate.ToString();
        break;
      case "charge-amount-notification":
        ChargeAmountNotification N4 = (ChargeAmountNotification) EncodeHelper.Deserialize(RequestXml, typeof(ChargeAmountNotification));
        // Google has successfully charged the customer's credit card.
        string OrderNumber4 = N4.googleordernumber;
        decimal ChargedAmount = N4.latestchargeamount.Value;
        break;
      case "refund-amount-notification":
        RefundAmountNotification N5 = (RefundAmountNotification) EncodeHelper.Deserialize(RequestXml, typeof(RefundAmountNotification));
        // Google has successfully refunded the customer's credit card.
        string OrderNumber5 = N5.googleordernumber;
        decimal RefundedAmount = N5.latestrefundamount.Value;
        break;
      case "chargeback-amount-notification":
        ChargebackAmountNotification N6 = (ChargebackAmountNotification) EncodeHelper.Deserialize(RequestXml, typeof(ChargebackAmountNotification));
        // A customer initiated a chargeback with his credit card company to get her money back.
        string OrderNumber6 = N6.googleordernumber;
        decimal ChargebackAmount = N6.latestchargebackamount.Value;
        break;

The most important of these notifications is the risk-information-notification. The new-order-notification tells you that a new order has been placed, but you may not want to start processing it yet because the customer's credit card has not been authorized. Once it has been authorized, you will get the risk-information-notification. Given the results of the AVS and CVV/CVN checks and the order's protection status, you should make a decision if you want to accept the order. If you don't accept it, you should cancel it and let the customer know why you did so. If you accept it, you should start processing it.

If AVS and CVV/CVN are unfamiliar terms, you can find good introductions here: http://en.wikipedia.org/wiki/Address_Verification_System and http://en.wikipedia.org/wiki/Card_Security_Code. For more information about the other notifications read by the code above, see Google's Checkout Dev Guide.

Order Processing API

You already have a pretty solid integration at this point. The next logical step would be to let your system tell Google when to charge orders that are ready to ship, so that you won't have to log in to Google, look up the order, and click the Charge button.

Make sure your app references GCheckout.dll and that you import the GCheckout, GCheckout.Util, and GCheckout.OrderProcessing namespaces. Then you can simply do this:

ChargeOrderRequest Req = new ChargeOrderRequest(X, Y, "Sandbox", 1234567890, "USD", 100.00m);
GCheckoutResponse R = X.Send();

Once you replace X and Y with your Merchant Id and Key, the code above will charge $100.00 for order number 1234567890. If it fails, you will either get an exception or R.IsGood will be false. If the latter, R.ErrorMessage will contain a human-readable error message.

There are nine other requests you can send to Google in the same way as you would a ChargeOrderRequest:

Tips and Tricks

I hope to have given you a flavor of what it is like integrating with Google Checkout using the .NET sample code. As you move from the examples above to a full integration with your existing web-based store, here are a few lessons from the field:

Final Notes

I believe Google Checkout is good for online shoppers, developers, and merchants. The existing sample code reduces the time it takes to integrate with Checkout, compared to starting from scratch. But that is just the beginning. I would encourage you to visit the websites below, ask questions, reply to the questions of others, discuss, and help improve the open source code. To be done with the day's work at 5 p.m., you should not reinvent the wheel.

Martin Omander works at Google where he helps large merchants integrate with Google Checkout.


Return to the Windows DevCenter.

Copyright © 2009 O'Reilly Media, Inc.