vizjerai-google-checkout 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +14 -0
- data/MIT-LICENSE.txt +23 -0
- data/README.txt +143 -0
- data/Rakefile +34 -0
- data/VERSION.yml +4 -0
- data/examples/google_notifications_controller.rb +159 -0
- data/lib/duck_punches/hpricot.rb +24 -0
- data/lib/google-checkout/cart.rb +304 -0
- data/lib/google-checkout/command.rb +255 -0
- data/lib/google-checkout/geography/area.rb +11 -0
- data/lib/google-checkout/geography/postal.rb +26 -0
- data/lib/google-checkout/geography/us_country.rb +24 -0
- data/lib/google-checkout/geography/us_state.rb +22 -0
- data/lib/google-checkout/geography/us_zip.rb +22 -0
- data/lib/google-checkout/geography/world.rb +12 -0
- data/lib/google-checkout/geography.rb +7 -0
- data/lib/google-checkout/merchant_calculation.rb +30 -0
- data/lib/google-checkout/notification.rb +352 -0
- data/lib/google-checkout/shipping/filters.rb +32 -0
- data/lib/google-checkout/shipping/flat_rate.rb +26 -0
- data/lib/google-checkout/shipping/merchant_calculated.rb +29 -0
- data/lib/google-checkout/shipping/method.rb +11 -0
- data/lib/google-checkout/shipping/pickup.rb +22 -0
- data/lib/google-checkout/shipping/restrictions.rb +32 -0
- data/lib/google-checkout/shipping.rb +8 -0
- data/lib/google-checkout.rb +65 -0
- data/spec/fixtures/google/checkout-shopping-cart.xml +22 -0
- data/spec/fixtures/google/commands/add-merchant-order-number.xml +5 -0
- data/spec/fixtures/google/commands/add-tracking-data.xml +8 -0
- data/spec/fixtures/google/commands/archive-order.xml +3 -0
- data/spec/fixtures/google/commands/authorize-order.xml +2 -0
- data/spec/fixtures/google/commands/cancel-order.xml +5 -0
- data/spec/fixtures/google/commands/charge-order.xml +4 -0
- data/spec/fixtures/google/commands/deliver-order.xml +9 -0
- data/spec/fixtures/google/commands/process-order.xml +2 -0
- data/spec/fixtures/google/commands/refund-order.xml +6 -0
- data/spec/fixtures/google/commands/send-buyer-message.xml +7 -0
- data/spec/fixtures/google/commands/unarchive-order.xml +2 -0
- data/spec/fixtures/google/merchant_calculations/shipping.xml +40 -0
- data/spec/fixtures/google/notifications/authorization-amount-notification.xml +10 -0
- data/spec/fixtures/google/notifications/charge-amount-notification.xml +8 -0
- data/spec/fixtures/google/notifications/chargeback-amount-notification.xml +8 -0
- data/spec/fixtures/google/notifications/new-order-notification.xml +94 -0
- data/spec/fixtures/google/notifications/order-state-change-notification.xml +11 -0
- data/spec/fixtures/google/notifications/refund-amount-notification.xml +8 -0
- data/spec/fixtures/google/notifications/risk-information-notification.xml +23 -0
- data/spec/fixtures/google/responses/checkout-redirect.xml +5 -0
- data/spec/fixtures/google/responses/error-charged.xml +5 -0
- data/spec/fixtures/google/responses/error.xml +5 -0
- data/spec/fixtures/google/responses/request-received.xml +3 -0
- data/spec/google-checkout/cart_spec.rb +110 -0
- data/spec/google-checkout/command_spec.rb +216 -0
- data/spec/google-checkout/geography/postal_spec.rb +26 -0
- data/spec/google-checkout/geography/us_country_spec.rb +26 -0
- data/spec/google-checkout/geography/us_state_spec.rb +11 -0
- data/spec/google-checkout/geography/us_zip_spec.rb +11 -0
- data/spec/google-checkout/geography/world_spec.rb +12 -0
- data/spec/google-checkout/merchant_calculation_spec.rb +17 -0
- data/spec/google-checkout/notification_spec.rb +253 -0
- data/spec/google-checkout/response_spec.rb +49 -0
- data/spec/google-checkout/shipping/flat_rate_spec.rb +46 -0
- data/spec/google-checkout/shipping/merchant_calculated_spec.rb +70 -0
- data/spec/google-checkout/shipping/pickup_spec.rb +22 -0
- data/spec/google-checkout_spec.rb +15 -0
- data/spec/spec_helper.rb +47 -0
- data/support/cacert.pem +7815 -0
- metadata +145 -0
@@ -0,0 +1,30 @@
|
|
1
|
+
module GoogleCheckout
|
2
|
+
class MerchantCalculation
|
3
|
+
|
4
|
+
attr_accessor :doc
|
5
|
+
|
6
|
+
def self.parse(raw_xml)
|
7
|
+
doc = Hpricot.XML(raw_xml)
|
8
|
+
return new(doc)
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(doc) # :nodoc:
|
12
|
+
@doc = doc
|
13
|
+
end
|
14
|
+
|
15
|
+
def address_id
|
16
|
+
@doc.at('anonymous-address').attributes['id']
|
17
|
+
end
|
18
|
+
|
19
|
+
def method_missing(method_name, *args)
|
20
|
+
element_name = method_name.to_s.gsub(/_/, '-')
|
21
|
+
if element = (@doc.at element_name)
|
22
|
+
if element.respond_to?(:inner_html)
|
23
|
+
return element.inner_html
|
24
|
+
end
|
25
|
+
end
|
26
|
+
super
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,352 @@
|
|
1
|
+
|
2
|
+
module GoogleCheckout
|
3
|
+
|
4
|
+
##
|
5
|
+
# Base notification class. Parses incoming XML and returns a class
|
6
|
+
# matching the kind of notification being received.
|
7
|
+
#
|
8
|
+
# This makes it easy to handle events in your code.
|
9
|
+
#
|
10
|
+
# notification = GoogleCheckout::Notification.parse(request.raw_post)
|
11
|
+
# case notification
|
12
|
+
# when GoogleCheckout::NewOrderNotification
|
13
|
+
# do_something_with_new_order
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# TODO Document field access and Hpricot object access.
|
17
|
+
#
|
18
|
+
# For the details, see http://code.google.com/apis/checkout/developer/index.html
|
19
|
+
|
20
|
+
class Notification
|
21
|
+
|
22
|
+
# The Hpricot XML document received from Google.
|
23
|
+
attr_accessor :doc
|
24
|
+
|
25
|
+
##
|
26
|
+
# The entry point for notifications.
|
27
|
+
#
|
28
|
+
# Returns a corresponding notification object based on
|
29
|
+
# the XML received.
|
30
|
+
|
31
|
+
def self.parse(raw_xml)
|
32
|
+
doc = Hpricot.XML(raw_xml)
|
33
|
+
|
34
|
+
# Convert +request-received+ to +request_received+,
|
35
|
+
# then to a +RequestReceived+ object of the proper class
|
36
|
+
# which will be created and returned.
|
37
|
+
const_name = ActiveSupport::Inflector.camelize(doc.root.name.gsub('-', '_'))
|
38
|
+
if GoogleCheckout.const_get(const_name)
|
39
|
+
return GoogleCheckout.const_get(const_name).new(doc)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def initialize(doc) # :nodoc:
|
44
|
+
@doc = doc
|
45
|
+
end
|
46
|
+
|
47
|
+
##
|
48
|
+
# Returns the financial-order-state (or new-financial-order-state).
|
49
|
+
#
|
50
|
+
# This is a shortcut since this state will be accessed frequently.
|
51
|
+
#
|
52
|
+
# The fulfillment-order-state (and variations) can be accessed
|
53
|
+
# with the more explicit syntax:
|
54
|
+
#
|
55
|
+
# notification.fulfillment_order_state
|
56
|
+
#
|
57
|
+
# The following is from http://code.google.com/apis/checkout/developer/index.html
|
58
|
+
#
|
59
|
+
# The <financial-order-state> tag identifies the financial status of an order. Valid values for this tag are:
|
60
|
+
#
|
61
|
+
# REVIEWING - Google Checkout is reviewing the order.
|
62
|
+
# CHARGEABLE - The order is ready to be charged.
|
63
|
+
# CHARGING - The order is being charged; you may not refund or cancel an
|
64
|
+
# order until is the charge is completed.
|
65
|
+
# CHARGED - The order has been successfully charged; if the order was
|
66
|
+
# only partially charged, the buyer's account page will
|
67
|
+
# reflect the partial charge.
|
68
|
+
# PAYMENT_DECLINED - The charge attempt failed.
|
69
|
+
# CANCELLED - The seller canceled the order; an order's financial state
|
70
|
+
# cannot be changed after the order is canceled.
|
71
|
+
# CANCELLED_BY_GOOGLE - Google canceled the order. Google may cancel
|
72
|
+
# orders due to a failed charge without a replacement credit
|
73
|
+
# card being provided within a set period of time or due to a
|
74
|
+
# failed risk check. If Google cancels an order, you will be
|
75
|
+
# notified of the reason the order was canceled in the <reason>
|
76
|
+
# tag of an <order-state-change-notification>.
|
77
|
+
#
|
78
|
+
# Please see the Order States section for more information about these states.
|
79
|
+
|
80
|
+
def state
|
81
|
+
if (@doc.at 'financial-order-state')
|
82
|
+
return (@doc/'financial-order-state').inner_html
|
83
|
+
elsif (@doc.at 'new-financial-order-state')
|
84
|
+
return (@doc/'new-financial-order-state').inner_html
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
##
|
89
|
+
# Returns the serial number from the root element.
|
90
|
+
|
91
|
+
def serial_number
|
92
|
+
doc.root['serial-number']
|
93
|
+
end
|
94
|
+
|
95
|
+
##
|
96
|
+
# Returns an XML string that can be sent back to Google to
|
97
|
+
# communicate successful receipt of the notification.
|
98
|
+
|
99
|
+
def acknowledgment_xml
|
100
|
+
xml = Builder::XmlMarkup.new
|
101
|
+
xml.instruct!
|
102
|
+
@xml = xml.tag!('notification-acknowledgment', {
|
103
|
+
:xmlns => "http://checkout.google.com/schema/2"
|
104
|
+
})
|
105
|
+
@xml
|
106
|
+
end
|
107
|
+
|
108
|
+
##
|
109
|
+
# Returns true if this is a GoogleCheckout::Error object.
|
110
|
+
|
111
|
+
def error?
|
112
|
+
self.class == GoogleCheckout::Error
|
113
|
+
end
|
114
|
+
|
115
|
+
##
|
116
|
+
# Take requests for an XML element and returns its value.
|
117
|
+
#
|
118
|
+
# notification.google_order_number
|
119
|
+
# => Returns value of '<google-order-number>'
|
120
|
+
#
|
121
|
+
# Because of how Hpricot#at works, it will even dig into subtags
|
122
|
+
# and return the value of the first matching tag. For example,
|
123
|
+
# there is an +email+ field in +buyer-shipping-address+ and also
|
124
|
+
# in +buyer-billing-address+, but only the first will be returned.
|
125
|
+
#
|
126
|
+
# If you want to get at a value explicitly, use +notification.doc+
|
127
|
+
# and search the Hpricot document manually.
|
128
|
+
|
129
|
+
def method_missing(method_name, *args)
|
130
|
+
element_name = method_name.to_s.gsub(/_/, '-')
|
131
|
+
if element = (@doc.at element_name)
|
132
|
+
if element.respond_to?(:inner_html)
|
133
|
+
return element.inner_html
|
134
|
+
end
|
135
|
+
end
|
136
|
+
super
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
class AuthorizationAmountNotification < Notification; end
|
142
|
+
|
143
|
+
class ChargeAmountNotification < Notification
|
144
|
+
|
145
|
+
def latest_charge_amount
|
146
|
+
(@doc/"latest-charge-amount").to_money
|
147
|
+
end
|
148
|
+
|
149
|
+
def total_charge_amount
|
150
|
+
(@doc/"total-charge-amount").to_money
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
|
155
|
+
class ChargebackAmountNotification < Notification; end
|
156
|
+
|
157
|
+
class NewOrderNotification < Notification
|
158
|
+
|
159
|
+
##
|
160
|
+
# Returns a Money object representing the total price of the order.
|
161
|
+
|
162
|
+
def order_total
|
163
|
+
(@doc/"order-total").to_money
|
164
|
+
end
|
165
|
+
|
166
|
+
##
|
167
|
+
# Returns a Money object representing the total tax added.
|
168
|
+
|
169
|
+
def total_tax
|
170
|
+
(@doc/"total-tax").to_money
|
171
|
+
end
|
172
|
+
|
173
|
+
##
|
174
|
+
# Returns true if the buyer wants to received marketing emails.
|
175
|
+
|
176
|
+
def email_allowed
|
177
|
+
(@doc/"buyer-marketing-preferences"/"email-allowed").to_boolean
|
178
|
+
end
|
179
|
+
|
180
|
+
##
|
181
|
+
# Returns billing name.
|
182
|
+
|
183
|
+
def billing_name
|
184
|
+
(@doc/"buyer-billing-address"/"contact-name").inner_html
|
185
|
+
end
|
186
|
+
|
187
|
+
##
|
188
|
+
# Returns billing email
|
189
|
+
|
190
|
+
def billing_email
|
191
|
+
(@doc/"buyer-billing-address"/"email").inner_html
|
192
|
+
end
|
193
|
+
|
194
|
+
##
|
195
|
+
# Returns billing address1
|
196
|
+
|
197
|
+
def billing_address1
|
198
|
+
(@doc/"buyer-billing-address"/"address1").inner_html
|
199
|
+
end
|
200
|
+
|
201
|
+
##
|
202
|
+
# Returns billing city
|
203
|
+
|
204
|
+
def billing_city
|
205
|
+
(@doc/"buyer-billing-address"/"city").inner_html
|
206
|
+
end
|
207
|
+
|
208
|
+
##
|
209
|
+
# Returns billing region
|
210
|
+
|
211
|
+
def billing_region
|
212
|
+
(@doc/"buyer-billing-address"/"region").inner_html
|
213
|
+
end
|
214
|
+
|
215
|
+
##
|
216
|
+
# Returns billing postal code
|
217
|
+
|
218
|
+
def billing_postal_code
|
219
|
+
(@doc/"buyer-billing-address"/"postal-code").inner_html
|
220
|
+
end
|
221
|
+
|
222
|
+
##
|
223
|
+
# Returns billing country code
|
224
|
+
|
225
|
+
def billing_country_code
|
226
|
+
(@doc/"buyer-billing-address"/"country-code").inner_html
|
227
|
+
end
|
228
|
+
|
229
|
+
##
|
230
|
+
# Returns billing phone
|
231
|
+
|
232
|
+
def billing_phone
|
233
|
+
(@doc/"buyer-billing-address"/"phone").inner_html
|
234
|
+
end
|
235
|
+
|
236
|
+
##
|
237
|
+
# Returns billing first name
|
238
|
+
|
239
|
+
def billing_first_name
|
240
|
+
(@doc/"buyer-billing-address"/"structured-name"/"first-name").inner_html
|
241
|
+
end
|
242
|
+
|
243
|
+
##
|
244
|
+
# Returns billing last name
|
245
|
+
|
246
|
+
def billing_last_name
|
247
|
+
(@doc/"buyer-billing-address"/"structured-name"/"last-name").inner_html
|
248
|
+
end
|
249
|
+
|
250
|
+
##
|
251
|
+
# Returns shipping contact name
|
252
|
+
|
253
|
+
def shipping_name
|
254
|
+
(@doc/"buyer-shipping-address"/"contact-name").inner_html
|
255
|
+
end
|
256
|
+
|
257
|
+
##
|
258
|
+
# Returns shipping email
|
259
|
+
|
260
|
+
def shipping_email
|
261
|
+
(@doc/"buyer-shipping-address"/"email").inner_html
|
262
|
+
end
|
263
|
+
|
264
|
+
##
|
265
|
+
# Returns shipping address1
|
266
|
+
|
267
|
+
def shipping_address1
|
268
|
+
(@doc/"buyer-shipping-address"/"address1").inner_html
|
269
|
+
end
|
270
|
+
|
271
|
+
##
|
272
|
+
# Returns shipping city
|
273
|
+
|
274
|
+
def shipping_city
|
275
|
+
(@doc/"buyer-shipping-address"/"city").inner_html
|
276
|
+
end
|
277
|
+
|
278
|
+
##
|
279
|
+
# Returns shipping region
|
280
|
+
|
281
|
+
def shipping_region
|
282
|
+
(@doc/"buyer-shipping-address"/"region").inner_html
|
283
|
+
end
|
284
|
+
|
285
|
+
##
|
286
|
+
# Returns shipping postal code
|
287
|
+
|
288
|
+
def shipping_postal_code
|
289
|
+
(@doc/"buyer-shipping-address"/"postal-code").inner_html
|
290
|
+
end
|
291
|
+
|
292
|
+
##
|
293
|
+
# Returns shipping country code
|
294
|
+
|
295
|
+
def shipping_country_code
|
296
|
+
(@doc/"buyer-shipping-address"/"country-code").inner_html
|
297
|
+
end
|
298
|
+
|
299
|
+
##
|
300
|
+
# Returns shipping phone
|
301
|
+
|
302
|
+
def shipping_phone
|
303
|
+
(@doc/"buyer-shipping-address"/"phone").inner_html
|
304
|
+
end
|
305
|
+
|
306
|
+
##
|
307
|
+
# Returns shipping first name
|
308
|
+
|
309
|
+
def shipping_first_name
|
310
|
+
(@doc/"buyer-shipping-address"/"structured-name"/"first-name").inner_html
|
311
|
+
end
|
312
|
+
|
313
|
+
##
|
314
|
+
# Returns shipping last name
|
315
|
+
|
316
|
+
def shipping_last_name
|
317
|
+
(@doc/"buyer-shipping-address"/"structured-name"/"last-name").inner_html
|
318
|
+
end
|
319
|
+
|
320
|
+
end
|
321
|
+
|
322
|
+
class OrderStateChangeNotification < Notification; end
|
323
|
+
|
324
|
+
class RefundAmountNotification < Notification; end
|
325
|
+
|
326
|
+
class RiskInformationNotification < Notification; end
|
327
|
+
|
328
|
+
class CheckoutRedirect < Notification
|
329
|
+
|
330
|
+
##
|
331
|
+
# Returns redirect-url with ampersands escaped, as specified by Google API docs.
|
332
|
+
|
333
|
+
def redirect_url
|
334
|
+
(@doc/"redirect-url").inner_html.gsub(/&/, '&')
|
335
|
+
end
|
336
|
+
|
337
|
+
end
|
338
|
+
|
339
|
+
class Error < Notification
|
340
|
+
|
341
|
+
##
|
342
|
+
# Alias for +error_message+
|
343
|
+
|
344
|
+
def message
|
345
|
+
(@doc/'error-message').inner_html
|
346
|
+
end
|
347
|
+
|
348
|
+
end
|
349
|
+
|
350
|
+
class RequestReceived < Notification; end
|
351
|
+
|
352
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module GoogleCheckout
|
2
|
+
module Shipping
|
3
|
+
module Filters
|
4
|
+
|
5
|
+
attr_accessor :address_filters
|
6
|
+
|
7
|
+
def address_filters?
|
8
|
+
@address_filters != {:allowed => [], :excluded => [], :allow_us_po_box => true}
|
9
|
+
end
|
10
|
+
|
11
|
+
def address_filters_xml
|
12
|
+
xml = Builder::XmlMarkup.new
|
13
|
+
xml.tag!('address-filters') do
|
14
|
+
xml.tag!('allowed-areas') do
|
15
|
+
@address_filters[:allowed].each do |area|
|
16
|
+
xml << area.to_xml
|
17
|
+
end
|
18
|
+
end unless @address_filters[:allowed].empty?
|
19
|
+
xml.tag!('excluded-areas') do
|
20
|
+
@address_filters[:excluded].each do |area|
|
21
|
+
xml << area.to_xml
|
22
|
+
end
|
23
|
+
end unless @address_filters[:excluded].empty?
|
24
|
+
xml.tag!('allow-us-po-box') do
|
25
|
+
xml.text! 'false'
|
26
|
+
end unless @address_filters[:allow_us_po_box]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module GoogleCheckout
|
2
|
+
module Shipping
|
3
|
+
class FlatRate < Method
|
4
|
+
|
5
|
+
include Restrictions
|
6
|
+
|
7
|
+
attr_accessor :name, :price, :currency
|
8
|
+
|
9
|
+
def initialize(name, price, currency = 'USD')
|
10
|
+
@name = name
|
11
|
+
@price = price
|
12
|
+
@currency = currency
|
13
|
+
@shipping_restrictions = {:allowed => [], :excluded => [], :allow_us_po_box => true}
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_xml
|
17
|
+
xml = Builder::XmlMarkup.new
|
18
|
+
xml.tag!('flat-rate-shipping', :name => name) do
|
19
|
+
xml.tag!('price', price, :currency => currency)
|
20
|
+
xml << shipping_restrictions_xml if shipping_restrictions?
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module GoogleCheckout
|
2
|
+
module Shipping
|
3
|
+
class MerchantCalculated < Method
|
4
|
+
|
5
|
+
include Restrictions
|
6
|
+
include Filters
|
7
|
+
|
8
|
+
attr_accessor :name, :price, :currency
|
9
|
+
|
10
|
+
def initialize(name, price, currency = 'USD')
|
11
|
+
@name = name
|
12
|
+
@price = price
|
13
|
+
@currency = currency
|
14
|
+
@shipping_restrictions = {:allowed => [], :excluded => [], :allow_us_po_box => true}
|
15
|
+
@address_filters = {:allowed => [], :excluded => [], :allow_us_po_box => true}
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_xml
|
19
|
+
xml = Builder::XmlMarkup.new
|
20
|
+
xml.tag!('merchant-calculated-shipping', :name => name) do
|
21
|
+
xml.tag!('price', price, :currency => currency)
|
22
|
+
xml << shipping_restrictions_xml if shipping_restrictions?
|
23
|
+
xml << address_filters_xml if address_filters?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module GoogleCheckout
|
2
|
+
module Shipping
|
3
|
+
class Pickup < Method
|
4
|
+
|
5
|
+
attr_accessor :name, :price, :currency
|
6
|
+
|
7
|
+
def initialize(name, price = '0.00', currency = 'USD')
|
8
|
+
@name = name
|
9
|
+
@price = price
|
10
|
+
@currency = currency
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_xml
|
14
|
+
xml = Builder::XmlMarkup.new
|
15
|
+
xml.tag!('pickup', :name => name) do
|
16
|
+
xml.tag!('price', price, :currency => currency)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module GoogleCheckout
|
2
|
+
module Shipping
|
3
|
+
module Restrictions
|
4
|
+
|
5
|
+
attr_accessor :shipping_restrictions
|
6
|
+
|
7
|
+
def shipping_restrictions?
|
8
|
+
@shipping_restrictions != {:allowed => [], :excluded => [], :allow_us_po_box => true}
|
9
|
+
end
|
10
|
+
|
11
|
+
def shipping_restrictions_xml
|
12
|
+
xml = Builder::XmlMarkup.new
|
13
|
+
xml.tag!('shipping-restrictions') do
|
14
|
+
xml.tag!('allowed-areas') do
|
15
|
+
@shipping_restrictions[:allowed].each do |area|
|
16
|
+
xml << area.to_xml
|
17
|
+
end
|
18
|
+
end unless @shipping_restrictions[:allowed].empty?
|
19
|
+
xml.tag!('excluded-areas') do
|
20
|
+
@shipping_restrictions[:excluded].each do |area|
|
21
|
+
xml << area.to_xml
|
22
|
+
end
|
23
|
+
end unless @shipping_restrictions[:excluded].empty?
|
24
|
+
xml.tag!('allow-us-po-box') do
|
25
|
+
xml.text! 'false'
|
26
|
+
end unless @shipping_restrictions[:allow_us_po_box]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
require 'google-checkout/shipping/method'
|
2
|
+
|
3
|
+
require 'google-checkout/shipping/restrictions'
|
4
|
+
require 'google-checkout/shipping/filters'
|
5
|
+
|
6
|
+
require 'google-checkout/shipping/pickup'
|
7
|
+
require 'google-checkout/shipping/flat_rate'
|
8
|
+
require 'google-checkout/shipping/merchant_calculated'
|
@@ -0,0 +1,65 @@
|
|
1
|
+
##
|
2
|
+
# Ref:
|
3
|
+
#
|
4
|
+
# https://sandbox.google.com/checkout/cws/v2/Merchant/MERCHANT_ID/merchantCheckout
|
5
|
+
# https://checkout.google.com/cws/v2/Merchant/MERCHANT_ID/merchantCheckout
|
6
|
+
|
7
|
+
$: << File.dirname(__FILE__)
|
8
|
+
$: << File.dirname(__FILE__) + "/vendor/ruby-hmac/lib"
|
9
|
+
|
10
|
+
require 'rubygems'
|
11
|
+
|
12
|
+
require 'hmac-sha1'
|
13
|
+
require 'base64'
|
14
|
+
require 'builder/xmlmarkup'
|
15
|
+
require 'hpricot'
|
16
|
+
require 'money'
|
17
|
+
require 'net/https'
|
18
|
+
require 'active_support'
|
19
|
+
|
20
|
+
require 'duck_punches/hpricot'
|
21
|
+
require 'google-checkout/notification'
|
22
|
+
require 'google-checkout/merchant_calculation'
|
23
|
+
require 'google-checkout/command'
|
24
|
+
require 'google-checkout/cart'
|
25
|
+
|
26
|
+
require 'google-checkout/shipping'
|
27
|
+
require 'google-checkout/geography'
|
28
|
+
|
29
|
+
##
|
30
|
+
# TODO
|
31
|
+
#
|
32
|
+
# * Analytics integration
|
33
|
+
# http://code.google.com/apis/checkout/developer/checkout_analytics_integration.html
|
34
|
+
|
35
|
+
module GoogleCheckout
|
36
|
+
|
37
|
+
#VERSION = '0.2.0'
|
38
|
+
|
39
|
+
@@live_system = true
|
40
|
+
|
41
|
+
##
|
42
|
+
# Submit commands to the Google Checkout test servers.
|
43
|
+
|
44
|
+
def self.use_sandbox
|
45
|
+
@@live_system = false
|
46
|
+
end
|
47
|
+
|
48
|
+
##
|
49
|
+
# The default.
|
50
|
+
|
51
|
+
def self.use_production
|
52
|
+
@@live_system = true
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.sandbox?
|
56
|
+
!@@live_system
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.production?
|
60
|
+
@@live_system
|
61
|
+
end
|
62
|
+
|
63
|
+
class APIError < Exception; end
|
64
|
+
|
65
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<checkout-shopping-cart xmlns="http://checkout.google.com/schema/2">
|
3
|
+
<shopping-cart>
|
4
|
+
<items>
|
5
|
+
<item>
|
6
|
+
<item-name>HelloWorld 2GB MP3 Player</item-name>
|
7
|
+
<item-description>HelloWorld, the simple MP3 player</item-description>
|
8
|
+
<unit-price currency="USD">159.99</unit-price>
|
9
|
+
<quantity>1</quantity>
|
10
|
+
</item>
|
11
|
+
</items>
|
12
|
+
</shopping-cart>
|
13
|
+
<checkout-flow-support>
|
14
|
+
<merchant-checkout-flow-support>
|
15
|
+
<shipping-methods>
|
16
|
+
<flat-rate-shipping name="SuperShip Ground">
|
17
|
+
<price currency="USD">9.99</price>
|
18
|
+
</flat-rate-shipping>
|
19
|
+
</shipping-methods>
|
20
|
+
</merchant-checkout-flow-support>
|
21
|
+
</checkout-flow-support>
|
22
|
+
</checkout-shopping-cart>
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<add-tracking-data xmlns="http://checkout.google.com/schema/2"
|
3
|
+
google-order-number="841171949013218">
|
4
|
+
<tracking-data>
|
5
|
+
<carrier>UPS</carrier>
|
6
|
+
<tracking-number>Z9842W69871281267</tracking-number>
|
7
|
+
</tracking-data>
|
8
|
+
</add-tracking-data>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<deliver-order xmlns="http://checkout.google.com/schema/2"
|
3
|
+
google-order-number="841171949013218">
|
4
|
+
<tracking-data>
|
5
|
+
<carrier>UPS</carrier>
|
6
|
+
<tracking-number>Z5498W45987123684</tracking-number>
|
7
|
+
</tracking-data>
|
8
|
+
<send-email>false</send-email>
|
9
|
+
</deliver-order>
|