google4r-checkout 0.1.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +16 -2
- data/README +1 -19
- data/lib/google4r/checkout/commands.rb +208 -23
- data/lib/google4r/checkout/frontend.rb +62 -2
- data/lib/google4r/checkout/notifications.rb +302 -11
- data/lib/google4r/checkout/shared.rb +3 -3
- data/lib/google4r/checkout/xml_generation.rb +429 -225
- data/test/unit/add_merchant_order_number_command_test.rb +210 -0
- data/test/unit/add_tracking_data_command_test.rb +225 -0
- data/test/unit/archive_order_command_test.rb +198 -0
- data/test/unit/authorization_amount_notification_test.rb +207 -0
- data/test/unit/authorize_order_command_test.rb +198 -0
- data/test/unit/cancel_order_command_test.rb +83 -0
- data/test/unit/charge_amount_notification_test.rb +64 -0
- data/test/unit/charge_order_command_test.rb +77 -0
- data/test/unit/chargeback_amount_notification_test.rb +195 -0
- data/test/unit/checkout_command_xml_generator_test.rb +12 -4
- data/test/unit/deliver_order_command_test.rb +70 -0
- data/test/unit/frontend_test.rb +14 -1
- data/test/unit/notification_handler_test.rb +28 -8
- data/test/unit/order_state_change_notification_test.rb +1 -2
- data/test/unit/refund_amount_notification_test.rb +195 -0
- data/test/unit/refund_order_command_test.rb +258 -0
- data/test/unit/risk_information_notification_test.rb +98 -0
- data/test/unit/send_buyer_message_command_test.rb +219 -0
- data/test/unit/unarchive_order_command_test.rb +198 -0
- metadata +17 -2
data/CHANGES
CHANGED
@@ -1,9 +1,23 @@
|
|
1
1
|
= google4r-checkout Changelog
|
2
2
|
|
3
|
-
==
|
3
|
+
== 1.0.0 (2007-08-04)
|
4
4
|
|
5
|
-
|
5
|
+
* Added refund-amount-notification
|
6
|
+
* Added chargeback-amount-notification
|
7
|
+
* Added authorization-amount-notification
|
8
|
+
* Added refund command
|
9
|
+
* Added authorize command
|
10
|
+
* Added add-merchant-number command
|
11
|
+
* Added add-tracking-data command
|
12
|
+
* Added send-buyer-message command
|
13
|
+
* Added archive-order command
|
14
|
+
* Added unarchive-order command
|
15
|
+
* Refactored to_xml in the Command class
|
16
|
+
* Added CommandXmlGenerator base class
|
17
|
+
* Added ChargeOrderCommand, DeliverOrderCommand, CancelOrderCommand, ChargeAmountNotification and RiskInfoNotification (all contributed by Dan Dukeson).
|
18
|
+
* Attributes are not retrieved via XPaths with "tag/@attribute" any more but with REXML's Element#attributes. This should fix problems with Ruby 1.8.6.
|
6
19
|
|
20
|
+
== 0.1.0 (2007-05-12)
|
7
21
|
* Added property "shipping_taxed" to TaxRule (contributed by Dan Dukeson).
|
8
22
|
* Added XML generation for the tax tables in the shopping cart (contributed by Dan Dukeson).
|
9
23
|
* Added Area subclasses WorldArea and PostalArea (contributed by Dan Dukeson).
|
data/README
CHANGED
@@ -8,16 +8,10 @@ google4r itself is distributed under an MIT style license.
|
|
8
8
|
|
9
9
|
However, the library includes the cacert.pem:http://curl.haxx.se/ca/cacert.pem file from the Mozilla project. This file is distributed under the MPL:http://www.mozilla.org/MPL/.
|
10
10
|
|
11
|
-
==
|
11
|
+
== More Information
|
12
12
|
|
13
13
|
You can find more information on the Google Checkout API here:http://code.google.com/apis/checkout/developer/index.html. Note that the API documentation assumes an understanding of the Google Checkout XML API.
|
14
14
|
|
15
|
-
Google4R also contains a partial implementation of the level 2 of the Google Checkout API:
|
16
|
-
|
17
|
-
* The <checkout-cart-command> tag and all of its subtags that are not related to the merchant calculation API can be generated.
|
18
|
-
* The <new-order-notification> tag and all of its subtags which are not related to the merchant calculation API can be parsed.
|
19
|
-
* The <order-state-change-notification> tag can be parsed.
|
20
|
-
|
21
15
|
== Google Checkout Tests
|
22
16
|
|
23
17
|
You have to place a file called 'frontend_configuration.rb' in the directory'test' with the configuration for the Google4R::Checkout::Frontend class to use for running the tests.
|
@@ -38,18 +32,6 @@ The file should contain content similar to:
|
|
38
32
|
:use_sandbox => true
|
39
33
|
}
|
40
34
|
|
41
|
-
== TODO
|
42
|
-
|
43
|
-
Notifications:
|
44
|
-
|
45
|
-
* <risk-information-notification>
|
46
|
-
* <charge-amount-notification>
|
47
|
-
* <refund-amount-notification>
|
48
|
-
* <chargeback-amount-notification>
|
49
|
-
* <authorization-amount-notification>
|
50
|
-
|
51
|
-
All of the Order Processing API.
|
52
|
-
|
53
35
|
== Dependencies
|
54
36
|
|
55
37
|
The unit tests use Mocha so you have to install the gem "mocha" to run the tests. You will also need the money gem library.
|
@@ -55,6 +55,12 @@ module Google4R #:nodoc:
|
|
55
55
|
# The Frontent class that was used to create this CheckoutCommand and whose
|
56
56
|
# configuration will be used.
|
57
57
|
attr_reader :frontend
|
58
|
+
|
59
|
+
# The tag name of the command
|
60
|
+
attr_reader :command_tag_name
|
61
|
+
|
62
|
+
# The google order number, required, String
|
63
|
+
attr_accessor :google_order_number
|
58
64
|
|
59
65
|
# Initialize the frontend attribute with the value of the frontend parameter.
|
60
66
|
def initialize(frontend)
|
@@ -100,22 +106,25 @@ module Google4R #:nodoc:
|
|
100
106
|
|
101
107
|
case xml_doc.root.name
|
102
108
|
when 'checkout-redirect'
|
103
|
-
serial_number = xml_doc.elements['/checkout-redirect
|
109
|
+
serial_number = xml_doc.elements['/checkout-redirect'].attributes['serial-number']
|
104
110
|
redirect_url = xml_doc.elements['/checkout-redirect/redirect-url/text()'].value
|
105
111
|
return CheckoutRedirectResponse.new(serial_number, redirect_url)
|
112
|
+
when 'request-received'
|
113
|
+
serial_number = xml_doc.elements['/request-received'].attributes['serial-number']
|
114
|
+
return serial_number
|
106
115
|
else
|
107
116
|
raise "Unknown response:\n--\n#{xml_doc.to_s}\n--"
|
108
117
|
end
|
109
118
|
when Net::HTTPClientError then
|
110
119
|
xml_doc = REXML::Document.new(result.body)
|
111
120
|
|
112
|
-
if xml_doc.elements['/error
|
121
|
+
if xml_doc.elements['/error'].attributes['serial-number'].nil? or xml_doc.elements['/error/error-message/text()'].nil? then
|
113
122
|
raise "Invalid response from Google:\n---\n#{result.body}\n---"
|
114
123
|
end
|
115
124
|
|
116
125
|
hash =
|
117
126
|
{
|
118
|
-
:serial_number => xml_doc.elements['/error
|
127
|
+
:serial_number => xml_doc.elements['/error'].attributes['serial-number'],
|
119
128
|
:message => xml_doc.elements['/error/error-message/text()'].value
|
120
129
|
}
|
121
130
|
|
@@ -127,30 +136,33 @@ module Google4R #:nodoc:
|
|
127
136
|
end
|
128
137
|
end
|
129
138
|
|
130
|
-
#
|
131
|
-
#
|
132
|
-
# Raises a NotImplementedError by default, override to remove this.
|
139
|
+
# Class method to return the command's XML representation.
|
133
140
|
def to_xml
|
134
|
-
|
141
|
+
if self.class == Command then
|
142
|
+
raise NotImplementedError, "Command#to_xml has to be used in a subclass."
|
143
|
+
else
|
144
|
+
generator_class = Google4R::Command.get_const("#{self.class}XmlGenerator")
|
145
|
+
return generator_class.new(self).generate
|
146
|
+
end
|
135
147
|
end
|
136
148
|
|
137
149
|
protected
|
138
150
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
151
|
+
# Class method to return the OpenSSL::X509::Store instance for the
|
152
|
+
# CA certificates.
|
153
|
+
#--
|
154
|
+
# TODO: Is OpenSSL::X509::Store thread safe when reading only? This method most certainly is *not*. It must become so.
|
155
|
+
#++
|
156
|
+
def self.x509_store
|
157
|
+
return @@x509_store if defined?(@@x509_store)
|
158
|
+
|
159
|
+
cacert_path = File.expand_path(File.dirname(__FILE__) + '/../../../var/cacert.pem')
|
160
|
+
|
161
|
+
@@x509_store = OpenSSL::X509::Store.new
|
162
|
+
@@x509_store.add_file(cacert_path)
|
163
|
+
|
164
|
+
return @@x509_store
|
165
|
+
end
|
154
166
|
end
|
155
167
|
|
156
168
|
# The CheckoutCommand represents a <checkout-shopping-cart> command sent
|
@@ -207,7 +219,6 @@ module Google4R #:nodoc:
|
|
207
219
|
# to create CheckoutCommand objects.
|
208
220
|
def initialize(frontend)
|
209
221
|
super(frontend)
|
210
|
-
|
211
222
|
@shopping_cart = ShoppingCart.new(self)
|
212
223
|
@tax_tables = frontend.tax_table_factory.effective_tax_tables_at(Time.new)
|
213
224
|
@shipping_methods = Array.new
|
@@ -256,5 +267,179 @@ module Google4R #:nodoc:
|
|
256
267
|
@redirect_url = redirect_url
|
257
268
|
end
|
258
269
|
end
|
270
|
+
|
271
|
+
#
|
272
|
+
# The ChargeOrderCommand instructs Google Checkout to charge the buyer for a
|
273
|
+
# particular order.
|
274
|
+
#
|
275
|
+
class ChargeOrderCommand < Command
|
276
|
+
# The amount to charge, optional, Money
|
277
|
+
attr_accessor :amount
|
278
|
+
|
279
|
+
# frontend, required
|
280
|
+
def initialize(frontend)
|
281
|
+
super(frontend)
|
282
|
+
end
|
283
|
+
|
284
|
+
# Generates the XML for this ChargeOrderCommand
|
285
|
+
def to_xml
|
286
|
+
ChargeOrderCommandXmlGenerator.new(self).generate
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
# The RefundOrderCommand instructs Google Checkout to refund an order
|
291
|
+
class RefundOrderCommand < Command
|
292
|
+
# The amount to refund, optional, Money
|
293
|
+
attr_accessor :amount
|
294
|
+
|
295
|
+
# The reason that the order is to be refunded, String of maximum 140 characters, required
|
296
|
+
attr_accessor :reason
|
297
|
+
|
298
|
+
# A comment related to the refunded order, String of maximum 140 characters, optional
|
299
|
+
attr_accessor :comment
|
300
|
+
|
301
|
+
def initialize(frontend)
|
302
|
+
super(frontend)
|
303
|
+
end
|
304
|
+
|
305
|
+
def to_xml
|
306
|
+
RefundOrderCommandXmlGenerator.new(self).generate
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
# The CancelOrderCommand instructs Google Checkout to cancel an order
|
311
|
+
class CancelOrderCommand < Command
|
312
|
+
# The reason that the order is to be cancelled, String of maximum 140 characters, required
|
313
|
+
attr_accessor :reason
|
314
|
+
|
315
|
+
# A comment related to the cancelled order, String of maximum 140 characters, optional
|
316
|
+
attr_accessor :comment
|
317
|
+
|
318
|
+
def initialize(frontend)
|
319
|
+
super(frontend)
|
320
|
+
end
|
321
|
+
|
322
|
+
def to_xml
|
323
|
+
CancelOrderCommandXmlGenerator.new(self).generate
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
# The AuthorizeOrderCommand instructs Google Checkout to explicitly reauthorize
|
328
|
+
# a customer's credit card for the uncharged balance of an order to verify that
|
329
|
+
# funds for the order are available
|
330
|
+
class AuthorizeOrderCommand < Command
|
331
|
+
def initialize(frontend)
|
332
|
+
super(frontend)
|
333
|
+
end
|
334
|
+
|
335
|
+
def to_xml
|
336
|
+
AuthorizeOrderCommandXmlGenerator.new(self).generate
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
# The ProcessOrderCommand instructs Google Checkout to to update
|
341
|
+
# an order's fulfillment state from NEW to PROCESSING
|
342
|
+
class ProcessOrderCommand < Command
|
343
|
+
def initialize(frontend)
|
344
|
+
super(frontend)
|
345
|
+
end
|
346
|
+
|
347
|
+
def to_xml
|
348
|
+
ProcessOrderCommandXmlGenerator.new(self).generate
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
# The AddMerchantOrderCommand instructs Google Checkout to associate a
|
353
|
+
# merchant-assigned order number with an order
|
354
|
+
class AddMerchantOrderNumberCommand < Command
|
355
|
+
# The merchant-assigned order number associated with an order
|
356
|
+
attr_accessor :merchant_order_number
|
357
|
+
|
358
|
+
def initialize(frontend)
|
359
|
+
super(frontend)
|
360
|
+
end
|
361
|
+
|
362
|
+
def to_xml
|
363
|
+
AddMerchantOrderNumberCommandXmlGenerator.new(self).generate
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
# The DeliverOrderCommand indicates that Google should update an order's fulfillment order state to DELIVERED
|
368
|
+
class DeliverOrderCommand < Command
|
369
|
+
# if google checkout should email buyer to ssay order is dispatched
|
370
|
+
attr_accessor :send_email
|
371
|
+
|
372
|
+
# The name of the company responsible for shipping the item. Valid values
|
373
|
+
# for this tag are DHL, FedEx, UPS, USPS and Other.
|
374
|
+
attr_accessor :carrier
|
375
|
+
|
376
|
+
# The shipper's tracking number that is associated with an order
|
377
|
+
attr_accessor :tracking_number
|
378
|
+
|
379
|
+
def initialize(frontend)
|
380
|
+
super(frontend)
|
381
|
+
end
|
382
|
+
|
383
|
+
def to_xml
|
384
|
+
DeliverOrderCommandXmlGenerator.new(self).generate
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
388
|
+
# The AddTrackingDataCommand instructs Google Checkout to associate a shipper's tracking number with an order.
|
389
|
+
class AddTrackingDataCommand < Command
|
390
|
+
# The name of the company responsible for shipping the item. Valid values
|
391
|
+
# for this tag are DHL, FedEx, UPS, USPS and Other.
|
392
|
+
attr_accessor :carrier
|
393
|
+
|
394
|
+
# The shipper's tracking number that is associated with an order
|
395
|
+
attr_accessor :tracking_number
|
396
|
+
|
397
|
+
def initialize(frontend)
|
398
|
+
super(frontend)
|
399
|
+
end
|
400
|
+
|
401
|
+
def to_xml
|
402
|
+
AddTrackingDataCommandXmlGenerator.new(self).generate
|
403
|
+
end
|
404
|
+
end
|
405
|
+
|
406
|
+
# The SendBuyerMessageCommand instructs Google Checkout to place a message in the customer's Google Checkout account.
|
407
|
+
class SendBuyerMessageCommand < Command
|
408
|
+
# The message to the customer
|
409
|
+
attr_accessor :message
|
410
|
+
|
411
|
+
# if google checkout should email buyer to ssay order is dispatched
|
412
|
+
attr_accessor :send_email
|
413
|
+
|
414
|
+
def initialize(frontend)
|
415
|
+
super(frontend)
|
416
|
+
end
|
417
|
+
|
418
|
+
def to_xml
|
419
|
+
SendBuyerMessageCommandXmlGenerator.new(self).generate
|
420
|
+
end
|
421
|
+
end
|
422
|
+
|
423
|
+
# The ArchiveOrderCommand instructs Google Checkout to remove an order from your Merchant Center Inbox.
|
424
|
+
class ArchiveOrderCommand < Command
|
425
|
+
def initialize(frontend)
|
426
|
+
super(frontend)
|
427
|
+
end
|
428
|
+
|
429
|
+
def to_xml
|
430
|
+
ArchiveOrderCommandXmlGenerator.new(self).generate
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
# The UnarchiveOrderCommand instructs Google Checkout to return a previously archived order to your Merchant Center Inbox.
|
435
|
+
class UnarchiveOrderCommand < Command
|
436
|
+
def initialize(frontend)
|
437
|
+
super(frontend)
|
438
|
+
end
|
439
|
+
|
440
|
+
def to_xml
|
441
|
+
UnarchiveOrderCommandXmlGenerator.new(self).generate
|
442
|
+
end
|
443
|
+
end
|
259
444
|
end
|
260
445
|
end
|
@@ -70,7 +70,7 @@ module Google4R #:nodoc:
|
|
70
70
|
# frontend = Google4R::Checkout::Frontend.new(configuration)
|
71
71
|
# frontend.tax_table_factory = TaxTableFactory.new
|
72
72
|
#
|
73
|
-
# checkout_command =
|
73
|
+
# checkout_command = frontend.create_checkout_command
|
74
74
|
# # ...
|
75
75
|
# handler = frontend.create_notification_handler
|
76
76
|
class Frontend
|
@@ -91,6 +91,18 @@ module Google4R #:nodoc:
|
|
91
91
|
|
92
92
|
@configuration = configuration.dup.freeze
|
93
93
|
end
|
94
|
+
|
95
|
+
# Factory method to create a new DeliverOrderCommand object. Use this method to create
|
96
|
+
# your DeliverOrderCommand instances.
|
97
|
+
def create_deliver_order_command
|
98
|
+
return DeliverOrderCommand.new(self)
|
99
|
+
end
|
100
|
+
|
101
|
+
# Factory method to create a new ChargeOrderCommand object. Use this method to create
|
102
|
+
# your ChargeOrderCommand instances.
|
103
|
+
def create_charge_order_command
|
104
|
+
return ChargeOrderCommand.new(self)
|
105
|
+
end
|
94
106
|
|
95
107
|
# Factory method that creates a new CheckoutCommand object. Use this method to create
|
96
108
|
# your CheckoutCommand instances.
|
@@ -103,6 +115,54 @@ module Google4R #:nodoc:
|
|
103
115
|
def create_notification_handler
|
104
116
|
return NotificationHandler.new(self)
|
105
117
|
end
|
118
|
+
|
119
|
+
# Factory method to create a new CancelOrderCommand object. Use this method to create
|
120
|
+
# your CancelOrderCommand instances.
|
121
|
+
def create_cancel_order_command
|
122
|
+
return CancelOrderCommand.new(self)
|
123
|
+
end
|
124
|
+
|
125
|
+
# Factory method to create a new RefundOrderCommand object. Use this method to create
|
126
|
+
# your RefundOrderCommand instances.
|
127
|
+
def create_refund_order_command
|
128
|
+
return RefundOrderCommand.new(self)
|
129
|
+
end
|
130
|
+
|
131
|
+
# Factory method to create a new SendBuyerMessageCommand object. Use this method to create
|
132
|
+
# your SendBuyerMessageCommand instances.
|
133
|
+
def create_send_buyer_message_command
|
134
|
+
return SendBuyerMessageCommand.new(self)
|
135
|
+
end
|
136
|
+
|
137
|
+
# Factory method to create a new AuthorizeOrderCommand object. Use this method to create
|
138
|
+
# your AuthorizeOrderCommand instances.
|
139
|
+
def create_authorize_order_command
|
140
|
+
return AuthorizeOrderCommand.new(self)
|
141
|
+
end
|
142
|
+
|
143
|
+
# Factory method to create a new AddMerchantOrderNumberCommand object. Use this method to create
|
144
|
+
# your AddMerchantOrderNumberCommand instances.
|
145
|
+
def create_add_merchant_order_number_command
|
146
|
+
return AddMerchantOrderNumberCommand.new(self)
|
147
|
+
end
|
148
|
+
|
149
|
+
# Factory method to create a new AddTrackingDataCommand object. Use this method to create
|
150
|
+
# your AddTrackingDataCommand instances.
|
151
|
+
def create_add_tracking_data_command
|
152
|
+
return AddTrackingDataCommand.new(self)
|
153
|
+
end
|
154
|
+
|
155
|
+
# Factory method to create a new ArchiveOrderCommand object. Use this method to create
|
156
|
+
# your ArchiveOrderCommand instances.
|
157
|
+
def create_archive_order_command
|
158
|
+
return ArchiveOrderCommand.new(self)
|
159
|
+
end
|
160
|
+
|
161
|
+
# Factory method to create a new UnarchiveOrderCommand object. Use this method to create
|
162
|
+
# your UnarchiveOrderCommand instances.
|
163
|
+
def create_unarchive_order_command
|
164
|
+
return UnarchiveOrderCommand.new(self)
|
165
|
+
end
|
106
166
|
end
|
107
167
|
end
|
108
|
-
end
|
168
|
+
end
|
@@ -107,6 +107,16 @@ module Google4R #:nodoc:
|
|
107
107
|
NewOrderNotification.create_from_element(root, frontend)
|
108
108
|
when 'order-state-change-notification' then
|
109
109
|
OrderStateChangeNotification.create_from_element(root, frontend)
|
110
|
+
when 'risk-information-notification' then
|
111
|
+
RiskInformationNotification.create_from_element(root, frontend)
|
112
|
+
when 'charge-amount-notification' then
|
113
|
+
ChargeAmountNotification.create_from_element(root, frontend)
|
114
|
+
when 'refund-amount-notification' then
|
115
|
+
RefundAmountNotification.create_from_element(root, frontend)
|
116
|
+
when 'chargeback-amount-notification' then
|
117
|
+
ChargebackAmountNotification.create_from_element(root, frontend)
|
118
|
+
when 'authorization-amount-notification' then
|
119
|
+
AuthorizationAmountNotification.create_from_element(root, frontend)
|
110
120
|
else
|
111
121
|
raise UnknownNotificationType, "Unknown notification type: #{root.name}"
|
112
122
|
end
|
@@ -185,7 +195,7 @@ module Google4R #:nodoc:
|
|
185
195
|
result = NewOrderNotification.new(frontend)
|
186
196
|
|
187
197
|
result.timestamp = Time.parse(element.elements['timestamp'].text)
|
188
|
-
result.serial_number = element.
|
198
|
+
result.serial_number = element.attributes['serial-number']
|
189
199
|
result.google_order_number = element.elements['google-order-number'].text
|
190
200
|
result.buyer_billing_address = Address.create_from_element(element.elements['buyer-billing-address'])
|
191
201
|
result.buyer_shipping_address = Address.create_from_element(element.elements['buyer-shipping-address'])
|
@@ -197,7 +207,7 @@ module Google4R #:nodoc:
|
|
197
207
|
result.shopping_cart = ShoppingCart.create_from_element(element.elements['shopping-cart'], result)
|
198
208
|
|
199
209
|
amount = element.elements['order-total'].text.to_s.gsub(/[^0-9]/, '').to_i rescue nil
|
200
|
-
currency = element.elements['order-total
|
210
|
+
currency = element.elements['order-total'].attributes['currency'] rescue nil
|
201
211
|
result.order_total = Money.new(amount, currency)
|
202
212
|
|
203
213
|
return result
|
@@ -250,7 +260,7 @@ module Google4R #:nodoc:
|
|
250
260
|
@frontend = frontend
|
251
261
|
end
|
252
262
|
|
253
|
-
# Factory
|
263
|
+
# Factory method that creates a new OrderStateChangeNotification from an REXML::Element instance.
|
254
264
|
# Use this to create instances of OrderStateChangeNotification.
|
255
265
|
#
|
256
266
|
# Raises NoMethodError and RuntimeError exceptions if the given element misses required
|
@@ -259,8 +269,7 @@ module Google4R #:nodoc:
|
|
259
269
|
result = OrderStateChangeNotification.new(frontend)
|
260
270
|
|
261
271
|
result.timestamp = Time.parse(element.elements['timestamp'].text)
|
262
|
-
|
263
|
-
result.serial_number = element.elements['@serial-number'].value
|
272
|
+
result.serial_number = element.attributes['serial-number']
|
264
273
|
result.google_order_number = element.elements['google-order-number'].text
|
265
274
|
result.new_financial_order_state = element.elements['new-financial-order-state'].text
|
266
275
|
result.previous_financial_order_state = element.elements['previous-financial-order-state'].text
|
@@ -272,6 +281,288 @@ module Google4R #:nodoc:
|
|
272
281
|
end
|
273
282
|
end
|
274
283
|
|
284
|
+
# Google Checkout sends <charge-amount-notification> messages to the web service when the
|
285
|
+
# to confirm that the charge was successfully executed.
|
286
|
+
class ChargeAmountNotification
|
287
|
+
|
288
|
+
# The serial number of the notification (String).
|
289
|
+
attr_accessor :serial_number
|
290
|
+
|
291
|
+
# The order number in Google's database (String).
|
292
|
+
attr_accessor :google_order_number
|
293
|
+
|
294
|
+
# The timestamp of the notification
|
295
|
+
attr_accessor :timestamp
|
296
|
+
|
297
|
+
# The amount most recently charged for an order (Money)
|
298
|
+
attr_accessor :latest_charge_amount
|
299
|
+
|
300
|
+
# The total amount charged for an order (Money)
|
301
|
+
attr_accessor :total_charge_amount
|
302
|
+
|
303
|
+
# The Frontend instance for this Notification
|
304
|
+
attr_accessor :frontend
|
305
|
+
|
306
|
+
# Initializes the ChargeAmountNotification instance with the given Frontend instance.
|
307
|
+
def initialize(frontend)
|
308
|
+
@frontend = frontend
|
309
|
+
end
|
310
|
+
|
311
|
+
# Factory method that creates a new ChargeAmountNotification from an REXML::Element instance.
|
312
|
+
# Use this to create instances of ChargeAmountNotification.
|
313
|
+
#
|
314
|
+
# Raises NoMethodError and RuntimeError exceptions if the given element misses required
|
315
|
+
# elements.
|
316
|
+
def self.create_from_element(element, frontend)
|
317
|
+
charge = ChargeAmountNotification.new(frontend)
|
318
|
+
|
319
|
+
charge.serial_number = element.attributes['serial-number']
|
320
|
+
charge.google_order_number = element.elements['google-order-number'].text
|
321
|
+
|
322
|
+
currency = element.elements['latest-charge-amount'].attributes['currency']
|
323
|
+
amount = element.elements['latest-charge-amount'].text.to_f*100.round
|
324
|
+
charge.latest_charge_amount = Money.new(amount, currency)
|
325
|
+
|
326
|
+
currency = element.elements['total-charge-amount'].attributes['currency']
|
327
|
+
amount = element.elements['total-charge-amount'].text.to_f*100.round
|
328
|
+
charge.total_charge_amount = Money.new(amount, currency)
|
329
|
+
|
330
|
+
charge.timestamp = Time.parse(element.elements['timestamp'].text)
|
331
|
+
|
332
|
+
return charge
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
# Google Checkout sends a <refund-amount-notification> after successfully executing
|
337
|
+
# a <refund-order> order processing command. See the Google Checkout documentation for more details:
|
338
|
+
# http://code.google.com/apis/checkout/developer/index.html#refund_amount_notification
|
339
|
+
class RefundAmountNotification
|
340
|
+
# The serial number of the notification (String).
|
341
|
+
attr_accessor :serial_number
|
342
|
+
|
343
|
+
# The order number in Google's database (String).
|
344
|
+
attr_accessor :google_order_number
|
345
|
+
|
346
|
+
# The timestamp of the notification
|
347
|
+
attr_accessor :timestamp
|
348
|
+
|
349
|
+
# The amount most recently refunded for an order (Money)
|
350
|
+
attr_accessor :latest_refund_amount
|
351
|
+
|
352
|
+
# The total amount refunded for an order (Money)
|
353
|
+
attr_accessor :total_refund_amount
|
354
|
+
|
355
|
+
# The Frontend instance for this Notification
|
356
|
+
attr_accessor :frontend
|
357
|
+
|
358
|
+
# Initializes the RefundAmountNotification instance with the given Frontend instance.
|
359
|
+
def initialize(frontend)
|
360
|
+
@frontend = frontend
|
361
|
+
end
|
362
|
+
|
363
|
+
# Factory method that creates a new RefundAmountNotification from an REXML::Element instance.
|
364
|
+
# Use this to create instances of RefundAmountNotification.
|
365
|
+
#
|
366
|
+
# Raises NoMethodError and RuntimeError exceptions if the given element misses required
|
367
|
+
# elements.
|
368
|
+
def self.create_from_element(element, frontend)
|
369
|
+
refund = RefundAmountNotification.new(frontend)
|
370
|
+
|
371
|
+
refund.serial_number = element.attributes['serial-number']
|
372
|
+
refund.google_order_number = element.elements['google-order-number'].text
|
373
|
+
|
374
|
+
currency = element.elements['latest-refund-amount'].attributes['currency']
|
375
|
+
amount = element.elements['latest-refund-amount'].text.to_f*100.round
|
376
|
+
refund.latest_refund_amount = Money.new(amount, currency)
|
377
|
+
|
378
|
+
currency = element.elements['total-refund-amount'].attributes['currency']
|
379
|
+
amount = element.elements['total-refund-amount'].text.to_f*100.round
|
380
|
+
refund.total_refund_amount = Money.new(amount, currency)
|
381
|
+
|
382
|
+
refund.timestamp = Time.parse(element.elements['timestamp'].text)
|
383
|
+
|
384
|
+
return refund
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
388
|
+
# Google Checkout sends a <chargeback-amount-notification> when a customer initiates a
|
389
|
+
# chargeback against the order and Google approves the chargeback.
|
390
|
+
# See the Google Checkout documentation for more details:
|
391
|
+
# http://code.google.com/apis/checkout/developer/index.html#chargeback_amount_notification
|
392
|
+
class ChargebackAmountNotification
|
393
|
+
# The serial number of the notification (String).
|
394
|
+
attr_accessor :serial_number
|
395
|
+
|
396
|
+
# The order number in Google's database (String).
|
397
|
+
attr_accessor :google_order_number
|
398
|
+
|
399
|
+
# The timestamp of the notification
|
400
|
+
attr_accessor :timestamp
|
401
|
+
|
402
|
+
# The amount most recently charged back for an order (Money)
|
403
|
+
attr_accessor :latest_chargeback_amount
|
404
|
+
|
405
|
+
# The total amount charged back for an order (Money)
|
406
|
+
attr_accessor :total_chargeback_amount
|
407
|
+
|
408
|
+
# The Frontend instance for this Notification
|
409
|
+
attr_accessor :frontend
|
410
|
+
|
411
|
+
# Initializes the ChargebackAmountNotification instance with the given Frontend instance.
|
412
|
+
def initialize(frontend)
|
413
|
+
@frontend = frontend
|
414
|
+
end
|
415
|
+
|
416
|
+
# Factory method that creates a new ChargebackAmountNotification from an REXML::Element instance.
|
417
|
+
# Use this to create instances of ChargebackAmountNotification.
|
418
|
+
#
|
419
|
+
# Raises NoMethodError and RuntimeError exceptions if the given element misses required
|
420
|
+
# elements.
|
421
|
+
def self.create_from_element(element, frontend)
|
422
|
+
chargeback = ChargebackAmountNotification.new(frontend)
|
423
|
+
|
424
|
+
chargeback.serial_number = element.attributes['serial-number']
|
425
|
+
chargeback.google_order_number = element.elements['google-order-number'].text
|
426
|
+
|
427
|
+
currency = element.elements['latest-chargeback-amount'].attributes['currency']
|
428
|
+
amount = element.elements['latest-chargeback-amount'].text.to_f*100.round
|
429
|
+
chargeback.latest_chargeback_amount = Money.new(amount, currency)
|
430
|
+
|
431
|
+
currency = element.elements['total-chargeback-amount'].attributes['currency']
|
432
|
+
amount = element.elements['total-chargeback-amount'].text.to_f*100.round
|
433
|
+
chargeback.total_chargeback_amount = Money.new(amount, currency)
|
434
|
+
|
435
|
+
chargeback.timestamp = Time.parse(element.elements['timestamp'].text)
|
436
|
+
|
437
|
+
return chargeback
|
438
|
+
end
|
439
|
+
end
|
440
|
+
|
441
|
+
# Google Checkout sends an <authorization-amount-notification> in response to a successful
|
442
|
+
# request for an explicit credit card reauthorization.
|
443
|
+
# See the Google Checkout documentation for more details:
|
444
|
+
# http://code.google.com/apis/checkout/developer/index.html#authorization_amount_notification
|
445
|
+
class AuthorizationAmountNotification
|
446
|
+
# The serial number of the notification (String).
|
447
|
+
attr_accessor :serial_number
|
448
|
+
|
449
|
+
# The order number in Google's database (String).
|
450
|
+
attr_accessor :google_order_number
|
451
|
+
|
452
|
+
# The timestamp of the notification
|
453
|
+
attr_accessor :timestamp
|
454
|
+
|
455
|
+
# The amount that is reauthorized to be charged to the customer's credit card (Money)
|
456
|
+
attr_accessor :authorization_amount
|
457
|
+
|
458
|
+
# The time that a credit card authorization for an order expires.
|
459
|
+
attr_accessor :authorization_expiration_date
|
460
|
+
|
461
|
+
# The address verification response (String)
|
462
|
+
attr_accessor :avs_response
|
463
|
+
|
464
|
+
# Credit verification value for the order (String)
|
465
|
+
attr_accessor :cvn_response
|
466
|
+
|
467
|
+
# The Frontend instance for this Notification
|
468
|
+
attr_accessor :frontend
|
469
|
+
|
470
|
+
# Initializes the AuthorizationAmountNotification instance with the given Frontend instance.
|
471
|
+
def initialize(frontend)
|
472
|
+
@frontend = frontend
|
473
|
+
end
|
474
|
+
|
475
|
+
# Factory method that creates a new AuthorizationAmountNotification from an REXML::Element instance.
|
476
|
+
# Use this to create instances of AuthorizationAmountNotification.
|
477
|
+
#
|
478
|
+
# Raises NoMethodError and RuntimeError exceptions if the given element misses required
|
479
|
+
# elements.
|
480
|
+
def self.create_from_element(element, frontend)
|
481
|
+
authorization = AuthorizationAmountNotification.new(frontend)
|
482
|
+
|
483
|
+
authorization.serial_number = element.attributes['serial-number']
|
484
|
+
authorization.google_order_number = element.elements['google-order-number'].text
|
485
|
+
|
486
|
+
currency = element.elements['authorization-amount'].attributes['currency']
|
487
|
+
amount = element.elements['authorization-amount'].text.to_f*100.round
|
488
|
+
authorization.authorization_amount = Money.new(amount, currency)
|
489
|
+
|
490
|
+
authorization.authorization_expiration_date = Time.parse(element.elements['authorization-expiration-date'].text)
|
491
|
+
|
492
|
+
authorization.avs_response = element.elements['avs-response'].text
|
493
|
+
authorization.cvn_response = element.elements['cvn-response'].text
|
494
|
+
|
495
|
+
authorization.timestamp = Time.parse(element.elements['timestamp'].text)
|
496
|
+
|
497
|
+
return authorization
|
498
|
+
end
|
499
|
+
end
|
500
|
+
|
501
|
+
# Google Checkout sends out <risk-information-notification> messages for fraud detection
|
502
|
+
# related information. See the Google Checkout documentation for more details:
|
503
|
+
# http://code.google.com/apis/checkout/developer/index.html#risk_information_notification
|
504
|
+
class RiskInformationNotification
|
505
|
+
# The serial number of the notification (String).
|
506
|
+
attr_accessor :serial_number
|
507
|
+
|
508
|
+
# The order number in Google's database (String).
|
509
|
+
attr_accessor :google_order_number
|
510
|
+
|
511
|
+
# Is the order eligible for Google Checkout's payment guarantee policy (boolean).
|
512
|
+
attr_accessor :eligible_for_protection
|
513
|
+
|
514
|
+
# The buyer's billing address (Address).
|
515
|
+
attr_accessor :buyer_billing_address
|
516
|
+
|
517
|
+
# The address verification response (String)
|
518
|
+
attr_accessor :avs_response
|
519
|
+
|
520
|
+
# Credit verification value for the order (String)
|
521
|
+
attr_accessor :cvn_response
|
522
|
+
|
523
|
+
# The last 4 digits of the credit card used to pay for the order (integer)
|
524
|
+
attr_accessor :partial_card_number
|
525
|
+
|
526
|
+
# The buyer's IP address (String)
|
527
|
+
attr_accessor :ip_address
|
528
|
+
|
529
|
+
# The age of the buyer's google checkout account in days
|
530
|
+
attr_accessor :buyer_account_age
|
531
|
+
|
532
|
+
# The timestamp of the notification
|
533
|
+
attr_accessor :timestamp
|
534
|
+
|
535
|
+
# The Frontend instance for this Notification
|
536
|
+
attr_accessor :frontend
|
537
|
+
|
538
|
+
# Initializes the RiskInformationNotification instance with the given Frontend instance.
|
539
|
+
def initialize(frontend)
|
540
|
+
@frontend = frontend
|
541
|
+
end
|
542
|
+
|
543
|
+
# Factory method that creates a new RiskInformationNotification from an REXML::Element instance.
|
544
|
+
# Use this to create instances of RiskInformationNotification
|
545
|
+
#
|
546
|
+
# Raises NoMethodError and RuntimeError exceptions if the given element misses required
|
547
|
+
# elements.
|
548
|
+
def self.create_from_element(element, frontend)
|
549
|
+
risk = RiskInformationNotification.new(frontend)
|
550
|
+
|
551
|
+
risk.serial_number = element.attributes['serial-number']
|
552
|
+
risk.timestamp = Time.parse(element.elements['timestamp'].text)
|
553
|
+
risk.partial_card_number = element.elements['risk-information/partial-cc-number'].text
|
554
|
+
risk.ip_address = element.elements['risk-information/ip-address'].text
|
555
|
+
risk.google_order_number = element.elements['google-order-number'].text
|
556
|
+
risk.eligible_for_protection = element.elements['risk-information/eligible-for-protection'].text == 'true'
|
557
|
+
risk.cvn_response = element.elements['risk-information/cvn-response'].text
|
558
|
+
risk.buyer_billing_address = Address.create_from_element(element.elements['risk-information/billing-address'])
|
559
|
+
risk.buyer_account_age = element.elements['risk-information/buyer-account-age'].text.to_i
|
560
|
+
risk.avs_response = element.elements['risk-information/avs-response'].text
|
561
|
+
|
562
|
+
return risk
|
563
|
+
end
|
564
|
+
end
|
565
|
+
|
275
566
|
# Container for the valid financial order states as defined in the
|
276
567
|
# Google Checkout API.
|
277
568
|
module FinancialOrderState
|
@@ -351,7 +642,7 @@ module Google4R #:nodoc:
|
|
351
642
|
|
352
643
|
# The marketing preferences of a customer.
|
353
644
|
class MarketingPreferences
|
354
|
-
# Boolean, true
|
645
|
+
# Boolean, true if the customer wants to receive emails.
|
355
646
|
attr_accessor :email_allowed
|
356
647
|
|
357
648
|
# Creates a new MarketingPreferences object from a given REXML::Element instance.
|
@@ -404,11 +695,11 @@ module Google4R #:nodoc:
|
|
404
695
|
result.code = element.elements['code'].text
|
405
696
|
|
406
697
|
amount = element.elements['calculated-amount'].text.to_s.gsub(/[^0-9]/, '').to_i rescue nil
|
407
|
-
currency = element.elements['calculated-amount
|
698
|
+
currency = element.elements['calculated-amount'].attributes['currency'] rescue nil
|
408
699
|
result.calculated_amount = Money.new(amount, currency) unless amount.nil?
|
409
700
|
|
410
701
|
amount = element.elements['applied-amount'].text.to_s.gsub(/[^0-9]/, '').to_i
|
411
|
-
currency = element.elements['applied-amount
|
702
|
+
currency = element.elements['applied-amount'].attributes['currency']
|
412
703
|
result.applied_amount = Money.new(amount, currency)
|
413
704
|
|
414
705
|
result.message = element.elements['message'].text rescue nil
|
@@ -454,7 +745,7 @@ module Google4R #:nodoc:
|
|
454
745
|
result.name = element.elements['shipping-name'].text
|
455
746
|
|
456
747
|
amount = element.elements['shipping-cost'].text.to_s.gsub(/[^0-9]/, '').to_i
|
457
|
-
currency = element.elements['shipping-cost
|
748
|
+
currency = element.elements['shipping-cost'].attributes['currency']
|
458
749
|
result.cost = Money.new(amount, currency)
|
459
750
|
|
460
751
|
return result
|
@@ -486,7 +777,7 @@ module Google4R #:nodoc:
|
|
486
777
|
result = OrderAdjustment.new
|
487
778
|
|
488
779
|
amount = element.elements['total-tax'].text.to_s.gsub(/[^0-9]/, '').to_i rescue nil
|
489
|
-
currency = element.elements['total-tax
|
780
|
+
currency = element.elements['total-tax'].attributes['currency'] rescue nil
|
490
781
|
result.total_tax = Money.new(amount, currency) unless amount.nil?
|
491
782
|
|
492
783
|
shipping_element = element.elements["shipping/*"]
|
@@ -498,7 +789,7 @@ module Google4R #:nodoc:
|
|
498
789
|
result.merchant_calculation_successful = (element.elements['merchant-calculation-successful'].text.downcase == 'true') rescue nil
|
499
790
|
|
500
791
|
amount = element.elements['adjustment-total'].text.to_s.gsub(/[^0-9]/, '').to_i rescue nil
|
501
|
-
currency = element.elements['adjustment-total
|
792
|
+
currency = element.elements['adjustment-total'].attributes['currency'] rescue nil
|
502
793
|
result.adjustment_total = Money.new(amount, currency) unless amount.nil?
|
503
794
|
|
504
795
|
return result
|