def to_xml
      raise RuntimeError, "Empty cart" if self.empty?

      xml = Builder::XmlMarkup.new
      xml.instruct!
      @xml = xml.tag!('checkout-shopping-cart', :xmlns => "http://checkout.google.com/schema/2") {
        xml.tag!("shopping-cart") {
          xml.items {
            @contents.each { |item|
              xml.item {
                if item.key?(:item_id)
                  xml.tag!('merchant-item-id', item[:item_id])
                end
                xml.tag!('item-name') {
                  xml.text! item[:name].to_s
                }
                xml.tag!('item-description') {
                  xml.text! item[:description].to_s
                }
                xml.tag!('unit-price', :currency => (item[:currency] || 'USD')) {
                  xml.text! item[:price].to_s
                }
                xml.quantity {
                  xml.text! item[:quantity].to_s
                }
              }
            }
          }
          unless @merchant_private_data.empty?
            xml.tag!("merchant-private-data") {
              @merchant_private_data.each do |key, value|
                xml.tag!(key, value)
              end
            }
          end
        }
        xml.tag!('checkout-flow-support') {
          xml.tag!('merchant-checkout-flow-support') {
            xml.tag!('edit-cart-url', @edit_cart_url) if @edit_cart_url
            xml.tag!('continue-shopping-url', @continue_shopping_url) if @continue_shopping_url

            xml.tag!("request-buyer-phone-number", false)

            # TODO tax-tables
            xml.tag!("tax-tables") {
              xml.tag!("default-tax-table") {
                xml.tag!("tax-rules") {
                  xml.tag!("default-tax-rule") {
                    xml.tag!("shipping-taxed", false)
                    xml.tag!("rate", "0.00")
                    xml.tag!("tax-area") {
                      xml.tag!("world-area")
                    }
                  }
                }
              }
            }

            xml.tag!('shipping-methods') {
              if @shipping_methods
                @shipping_methods.each { |method|
                  xml.tag!("pickup", :name => method[:name]) {
                    xml.tag!('price', method[:price], :currency => method[:currency] || 'USD')
                  }
                }
              end
            }
            
            
          }
        }
      }
      @xml.dup
    end
def to_xml
      raise RuntimeError, "Empty cart" if self.empty?

      xml = Builder::XmlMarkup.new
      xml.instruct!
      @xml = xml.tag!('checkout-shopping-cart', :xmlns => "http://checkout.google.com/schema/2") {
        xml.tag!("shopping-cart") {
          xml.items {
            @contents.each { |item|
              xml.item {
                if item.key?(:item_id)
                  xml.tag!('merchant-item-id', item[:item_id])
                end
                xml.tag!('item-name') {
                  xml.text! item[:name].to_s
                }
                xml.tag!('item-description') {
                  xml.text! item[:description].to_s
                }
                xml.tag!('unit-price', :currency => (item[:currency] || 'USD')) {
                  xml.text! item[:price].to_s
                }
                xml.quantity {
                  xml.text! item[:quantity].to_s
                }
              }
            }
          }
          unless @merchant_private_data.empty?
            xml.tag!("merchant-private-data") {
              @merchant_private_data.each do |key, value|
                xml.tag!(key, value)
              end
            }
          end
        }
        xml.tag!('checkout-flow-support') {
          xml.tag!('merchant-checkout-flow-support') {
            xml.tag!('edit-cart-url', @edit_cart_url) if @edit_cart_url
            xml.tag!('continue-shopping-url', @continue_shopping_url) if @continue_shopping_url

            xml.tag!("request-buyer-phone-number", false)

            # TODO tax-tables
            xml.tag!("tax-tables") {
              xml.tag!("default-tax-table") {
                xml.tag!("tax-rules") {
                  xml.tag!("default-tax-rule") {
                    xml.tag!("shipping-taxed", false)
                    xml.tag!("rate", "0.00")
                    xml.tag!("tax-area") {
                      xml.tag!("world-area")
                    }
                  }
                }
              }
            }

            xml.tag!('shipping-methods') {
              if @shipping_methods
                @shipping_methods.each { |method|
                  xml.tag!("pickup", :name => method[:name]) {
                    xml.tag!('price', method[:price], :currency => method[:currency] || 'USD')
                  }
                }
              end
            }
            
            
          }
        }
      }
      @xml.dup
    end
This is the important method; it generatest the XML call.
 It's fairly lengthy, but trivial.  It follows the docs at
 http://code.google.com/apis/checkout/developer/index.html#checkout_api

 It returns the raw XML string, not encoded.