Class: GoogleCheckout::Cart
- Includes:
- GoogleCheckout
- Defined in:
- lib/google-checkout/cart.rb
Overview
This class represents a cart for Google Checkout. After initializing it with a merchant_id
and merchant_key
, you add items via add_item, and can then get xml via to_xml, or html code for a form that provides a checkout button via checkout_button.
Example:
item = {
:name => 'A Quarter',
:description => 'One shiny quarter.',
:price => 0.25
}
@cart = GoogleCheckout::Cart.new(merchant_id, merchant_key, item)
@cart.add_item(:name => "Pancakes",
:description => "Flapjacks by mail."
:price => 0.50,
:quantity => 10,
"merchant-item-id" => '2938292839')
Then in your view:
Checkout here! <%= @cart.checkout_button %>
This object is also useful for getting back a url to the image for a Google Checkout button. You can use this image in forms that submit back to your own server for further processing via Google Checkout’s level 2 XML API.
Constant Summary collapse
- SANDBOX_CHECKOUT_URL =
"https://sandbox.google.com/checkout/cws/v2/Merchant/%s/checkout"
- PRODUCTION_CHECKOUT_URL =
"https://checkout.google.com/cws/v2/Merchant/%s/checkout"
- DefaultButtonOpts =
The default options for drawing in the button that are filled in when checkout_button or button_url is called.
{ :size => :medium, :style => 'white', :variant => 'text', :loc => 'en_US', :buy_or_checkout => nil, }
Constants included from GoogleCheckout
Constants inherited from Command
GoogleCheckout::Command::PRODUCTION_REQUEST_URL, GoogleCheckout::Command::SANDBOX_REQUEST_URL
Instance Attribute Summary collapse
-
#continue_shopping_url ⇒ Object
Returns the value of attribute continue_shopping_url.
-
#edit_cart_url ⇒ Object
Returns the value of attribute edit_cart_url.
-
#merchant_calculations_url ⇒ Object
Returns the value of attribute merchant_calculations_url.
-
#merchant_private_data ⇒ Object
You can provide extra data that will be sent to Google and returned with the NewOrderNotification.
-
#shipping_methods ⇒ Object
Returns the value of attribute shipping_methods.
Attributes inherited from Command
#currency, #merchant_id, #merchant_key
Instance Method Summary collapse
-
#add_item(item) ⇒ Object
This method puts items in the cart.
-
#button_url(opts = {}) ⇒ Object
Given a set of options for the button, button_url returns the URL for the button image.
-
#checkout_button(button_opts = {}) ⇒ Object
Returns HTML for a checkout form for buying all the items in the cart.
- #empty? ⇒ Boolean
-
#initialize(merchant_id, merchant_key, *items) ⇒ Cart
constructor
You need to supply, as strings, the
merchant_id
andmerchant_key
used to identify your store to Google. -
#signature ⇒ Object
Returns the signature for the cart XML.
-
#size ⇒ Object
Number of items in the cart.
- #submit_domain ⇒ Object
-
#submit_url ⇒ Object
The Google Checkout form submission url.
-
#to_xml ⇒ Object
This is the important method; it generatest the XML call.
Methods included from GoogleCheckout
production?, sandbox?, use_production, use_sandbox
Methods inherited from Command
Constructor Details
#initialize(merchant_id, merchant_key, *items) ⇒ Cart
You need to supply, as strings, the merchant_id
and merchant_key
used to identify your store to Google. You may optionally supply one or more items to put inside the cart.
87 88 89 90 91 92 93 |
# File 'lib/google-checkout/cart.rb', line 87 def initialize(merchant_id, merchant_key, *items) super(merchant_id, merchant_key) @contents = [] @merchant_private_data = {} @shipping_methods = [] items.each { |i| add_item i } end |
Instance Attribute Details
#continue_shopping_url ⇒ Object
Returns the value of attribute continue_shopping_url.
68 69 70 |
# File 'lib/google-checkout/cart.rb', line 68 def continue_shopping_url @continue_shopping_url end |
#edit_cart_url ⇒ Object
Returns the value of attribute edit_cart_url.
67 68 69 |
# File 'lib/google-checkout/cart.rb', line 67 def edit_cart_url @edit_cart_url end |
#merchant_calculations_url ⇒ Object
Returns the value of attribute merchant_calculations_url.
70 71 72 |
# File 'lib/google-checkout/cart.rb', line 70 def merchant_calculations_url @merchant_calculations_url end |
#merchant_private_data ⇒ Object
You can provide extra data that will be sent to Google and returned with the NewOrderNotification.
This should be a Hash and will be turned into XML with proper escapes.
Beware using symbols as values. They may be set as sub-keys instead of values, so use a String or other datatype.
65 66 67 |
# File 'lib/google-checkout/cart.rb', line 65 def merchant_private_data @merchant_private_data end |
#shipping_methods ⇒ Object
Returns the value of attribute shipping_methods.
72 73 74 |
# File 'lib/google-checkout/cart.rb', line 72 def shipping_methods @shipping_methods end |
Instance Method Details
#add_item(item) ⇒ Object
This method puts items in the cart. item
may be a hash, or have a method named to_google_product
that returns a hash with the required values.
-
name
-
description (a brief description as it will appear on the bill)
-
price
You may fill in some optional values as well:
-
quantity (defaults to 1)
-
currency (defaults to ‘USD’)
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/google-checkout/cart.rb', line 124 def add_item(item) @xml = nil if item.respond_to? :to_google_product item = item.to_google_product end # We need to check that the necessary keys are in the hash, # Otherwise the error will happen in the middle of to_xml, # and the bug will be harder to track. missing_keys = [ :name, :description, :price ].select { |key| !item.include? key } unless missing_keys.empty? raise ArgumentError, "Required keys missing: #{missing_keys.inspect}" end @contents << { :quantity => 1, :currency => 'USD' }.merge(item) item end |
#button_url(opts = {}) ⇒ Object
Given a set of options for the button, button_url returns the URL for the button image. The options are the same as those specified on checkout.google.com/seller/checkout_buttons.html , with a couple of extra options for convenience. Rather than specifying the width and height manually, you may specify :size to be one of :small, :medium, or :large, and that you may set :buy_or_checkout to :buy_now or :checkout to get a ‘Buy Now’ button versus a ‘Checkout’ button. If you don’t specify :buy_or_checkout, the Cart will try to guess based on if the cart has more than one item in it. Whatever you don’t pass will be filled in with the defaults from DefaultButtonOpts.
http://checkout.google.com//checkout.gif
http://sandbox.google.com/checkout//checkout.gif
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 |
# File 'lib/google-checkout/cart.rb', line 280 def (opts = {}) opts = DefaultButtonOpts.merge opts opts[:buy_or_checkout] ||= @contents.size > 1 ? :checkout : :buy_now opts.merge! ButtonSizes[opts[:buy_or_checkout]][opts[:size]] bname = opts[:buy_or_checkout] == :buy_now ? 'buy.gif' : 'checkout.gif' opts.delete :size opts.delete :buy_or_checkout opts[:merchant_id] = @merchant_id path = opts.map { |k,v| "#{k}=#{v}" }.join('&') # HACK Sandbox graphics are in the checkout subdirectory subdir = "" if GoogleCheckout.sandbox? && bname == "checkout.gif" subdir = "checkout/" end protocol = opts[:https] ? 'https' : 'http' # TODO Use /checkout/buttons/checkout.gif if in sandbox. "#{protocol}://#{submit_domain}/#{ subdir }buttons/#{bname}?#{path}" end |
#checkout_button(button_opts = {}) ⇒ Object
Returns HTML for a checkout form for buying all the items in the cart.
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 |
# File 'lib/google-checkout/cart.rb', line 235 def ( = {}) @xml or to_xml burl = () html = Builder::XmlMarkup.new(:indent => 2) html.form({ :action => submit_url, :style => 'border: 0;', :id => 'BB_BuyButtonForm', :method => 'post', :name => 'BB_BuyButtonForm' }) do html.input({ :name => 'cart', :type => 'hidden', :value => Base64.encode64(@xml).gsub("\n", '') }) html.input({ :name => 'signature', :type => 'hidden', :value => Base64.encode64(signature).gsub("\n", '') }) html.input({ :alt => 'Google Checkout', :style => "width: auto;", :src => (), :type => 'image' }) end end |
#empty? ⇒ Boolean
95 96 97 |
# File 'lib/google-checkout/cart.rb', line 95 def empty? @contents.empty? end |
#signature ⇒ Object
Returns the signature for the cart XML.
228 229 230 231 |
# File 'lib/google-checkout/cart.rb', line 228 def signature @xml or to_xml HMAC::SHA1.digest(@merchant_key, @xml) end |
#size ⇒ Object
Number of items in the cart.
100 101 102 |
# File 'lib/google-checkout/cart.rb', line 100 def size @contents.size end |
#submit_domain ⇒ Object
104 105 106 |
# File 'lib/google-checkout/cart.rb', line 104 def submit_domain (GoogleCheckout.production? ? 'checkout' : 'sandbox') + ".google.com" end |
#submit_url ⇒ Object
The Google Checkout form submission url.
111 112 113 |
# File 'lib/google-checkout/cart.rb', line 111 def submit_url GoogleCheckout.sandbox? ? (SANDBOX_CHECKOUT_URL % @merchant_id) : (PRODUCTION_CHECKOUT_URL % @merchant_id) end |
#to_xml ⇒ Object
This is the important method; it generatest the XML call. It’s fairly lengthy, but trivial. It follows the docs at code.google.com/apis/checkout/developer/index.html#checkout_api
It returns the raw XML string, not encoded.
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/google-checkout/cart.rb', line 151 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 } xml.tag!('merchant-private-item-data') { xml << item[:merchant_private_item_data] } if item.key?(:merchant_private_item_data) } } } 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) xml.tag!('merchant-calculations') { xml.tag!('merchant-calculations-url') { xml.text! @merchant_calculations_url } } if @merchant_calculations_url # 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') { @shipping_methods.each do |shipping_method| xml << shipping_method.to_xml end } } } } @xml.dup end |