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'
ORDER_REPORT_API_URL =
'api/checkout/v2/reports/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.



67
68
69
70
71
72
# File 'lib/google4r/checkout/commands.rb', line 67

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



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

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.



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

def frontend
  @frontend
end

#google_order_numberObject

The google order number, required, String



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

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. ++



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
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/google4r/checkout/commands.rb', line 84

def send_to_google_checkout
  xml_response = (self.class == OrderReportCommand) ? false : true        
  # 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
    elsif self.class == OrderReportCommand then
      ORDER_REPORT_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
    if ( xml_response ) 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
    else
      # handle the CSV output of the order-report-list command
      return result.body
    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}"
  else
    raise "Unknown reponse code: #{result.code} - #{result.message}"
  end
end

#to_xmlObject

Class method to return the command’s XML representation.



159
160
161
162
# File 'lib/google4r/checkout/commands.rb', line 159

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