Class: Google4R::Checkout::Command

Inherits:
Object
  • Object
show all
Defined in:
lib/google4r/checkout/commands.rb

Overview

Abstract super class for all commands that are to be sent to Google. Provides the base functionality for signing and encoding the cart.

Constant Summary collapse

SANDBOX_URL_PREFIX =

The URL to use for requests to the sandboxed API. The merchant id is to be put in via String#%.

'https://sandbox.google.com/checkout/'
PRODUCTION_URL_PREFIX =

The URL to use for real requests to the Google Checkout API. The merchant id is to be put in via String#%.

'https://checkout.google.com/'
CHECKOUT_API_URL =
'api/checkout/v2/merchantCheckout/Merchant/%s'
ORDER_PROCESSING_API_URL =
'api/checkout/v2/request/Merchant/%s'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(frontend) ⇒ Command

Initialize the frontend attribute with the value of the frontend parameter.



64
65
66
67
68
69
# File 'lib/google4r/checkout/commands.rb', line 64

def initialize(frontend)
  if self.instance_of?(Command) || self.instance_of?(ItemsCommand)
    raise 'Cannot instantiate abstract class ' + self.class.to_s
  end
  @frontend = frontend
end

Instance Attribute Details

#command_tag_nameObject (readonly)

The tag name of the command



58
59
60
# File 'lib/google4r/checkout/commands.rb', line 58

def command_tag_name
  @command_tag_name
end

#frontendObject (readonly)

The Frontent class that was used to create this CheckoutCommand and whose configuration will be used.



55
56
57
# File 'lib/google4r/checkout/commands.rb', line 55

def frontend
  @frontend
end

#google_order_numberObject

The google order number, required, String



61
62
63
# File 'lib/google4r/checkout/commands.rb', line 61

def google_order_number
  @google_order_number
end

Instance Method Details

#send_to_google_checkoutObject

Sends the cart's XML to GoogleCheckout via HTTPs with Basic Auth.

Raises an OpenSSL::SSL::SSLError when the SSL certificate verification failed.

Raises a GoogleCheckoutError when Google returns an error.

Raises a RuntimeException on unknown responses.

TODO: The send-and-expect-response part should be adaptable to other commands and responses. ++



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/google4r/checkout/commands.rb', line 81

def send_to_google_checkout
  # Create HTTP(S) POST command and set up Basic Authentication.
  url_str = 
    if frontend.configuration[:use_sandbox] then
      SANDBOX_URL_PREFIX
    else
      PRODUCTION_URL_PREFIX
    end
  url_str += 
    if self.class == CheckoutCommand then
      CHECKOUT_API_URL
    else
      ORDER_PROCESSING_API_URL
    end
  url_str = url_str % frontend.configuration[:merchant_id]
  url = URI.parse(url_str)
  
  request = Net::HTTP::Post.new(url.path)
  request.basic_auth(frontend.configuration[:merchant_id], frontend.configuration[:merchant_key])

  # Set up the HTTP connection object and the SSL layer.
  https = Net::HTTP.new(url.host, url.port)
  https.use_ssl = true
  https.cert_store = self.class.x509_store
  https.verify_mode = OpenSSL::SSL::VERIFY_PEER
  https.verify_depth = 5

  # Send the request to Google.
  result = https.request(request, self.to_xml)
  
  case result
  when Net::HTTPSuccess then
    xml_doc = REXML::Document.new(result.body)
    
    case xml_doc.root.name
    when 'checkout-redirect'
      serial_number = xml_doc.elements['/checkout-redirect'].attributes['serial-number']
      redirect_url = xml_doc.elements['/checkout-redirect/redirect-url/text()'].value
      return CheckoutRedirectResponse.new(serial_number, redirect_url)
    when 'request-received'
      serial_number = xml_doc.elements['/request-received'].attributes['serial-number']
      return serial_number
    else
      raise "Unknown response:\n--\n#{xml_doc.to_s}\n--"
    end
  when Net::HTTPClientError then
    xml_doc = REXML::Document.new(result.body)
    
    if xml_doc.elements['/error'].attributes['serial-number'].nil? or xml_doc.elements['/error/error-message/text()'].nil? then
      raise "Invalid response from Google:\n---\n#{result.body}\n---"
    end
    
    hash = 
      {
        :serial_number => xml_doc.elements['/error'].attributes['serial-number'],
        :message       => xml_doc.elements['/error/error-message/text()'].value
      }
    
    raise GoogleCheckoutError.new(hash)
  when Net::HTTPRedirection, Net::HTTPServerError, Net::HTTPInformation then
    raise "Unexpected reponse code (#{result.class}): #{result.code} - #{result.message}\n#{result.body}"
  else
    raise "Unknown reponse code: #{result.code} - #{result.message}\n#{result.body}"
  end
end

#to_xmlObject

Class method to return the command's XML representation.



148
149
150
151
# File 'lib/google4r/checkout/commands.rb', line 148

def to_xml
  generator_class = Google4R::Command.get_const("#{self.class}XmlGenerator")
  return generator_class.new(self).generate
end