vizjerai-google-checkout 0.1.0 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +6 -7
- data/VERSION +1 -0
- data/lib/duck_punches/inflector.rb +13 -0
- data/lib/google-checkout.rb +3 -2
- data/lib/google-checkout/cart.rb +79 -2
- data/lib/google-checkout/notification.rb +16 -3
- data/spec/fixtures/google/checkout-shopping-cart.xml +26 -0
- data/spec/fixtures/google/notifications/cancelled-subscription-notification.xml +7 -0
- data/spec/google-checkout/cart_spec.rb +1 -1
- data/spec/google-checkout/notification_spec.rb +20 -1
- metadata +32 -23
- data/VERSION.yml +0 -4
data/Rakefile
CHANGED
@@ -20,15 +20,14 @@ end
|
|
20
20
|
begin
|
21
21
|
require 'jeweler'
|
22
22
|
Jeweler::Tasks.new do |s|
|
23
|
-
s.name = "google-checkout"
|
23
|
+
s.name = "vizjerai-google-checkout"
|
24
24
|
s.summary = "An experimental library for sending payment requests to Google Checkout."
|
25
|
-
s.email = "
|
26
|
-
s.homepage = "http://github.com/
|
25
|
+
s.email = "assarata@gmail.com"
|
26
|
+
s.homepage = "http://github.com/vizjerai/google-checkout/"
|
27
27
|
s.description = "An experimental library for sending payment requests to Google Checkout."
|
28
|
-
s.authors = ["Peter Elmore", "Geoffrey Grosenbach", "Matt Lins"]
|
28
|
+
s.authors = ["Peter Elmore", "Geoffrey Grosenbach", "Matt Lins", "Steel Fu", "Andrew Assarattanakul"]
|
29
29
|
s.files = FileList["[A-Z]*", "{lib,spec,support,examples}/**/*"]
|
30
|
-
s.add_dependency 'ruby-hmac'
|
31
30
|
end
|
32
31
|
rescue LoadError
|
33
|
-
puts "Jeweler not available. Install it with: sudo gem install
|
34
|
-
end
|
32
|
+
puts "Jeweler not available. Install it with: sudo gem install jeweler"
|
33
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.3
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module ActiveSupport
|
2
|
+
module Inflector
|
3
|
+
class << self
|
4
|
+
def camelize(lower_case_and_underscored_word, first_letter_in_uppercase = true)
|
5
|
+
if first_letter_in_uppercase
|
6
|
+
lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
|
7
|
+
else
|
8
|
+
lower_case_and_underscored_word.first.downcase + camelize(lower_case_and_underscored_word)[1..-1]
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/google-checkout.rb
CHANGED
@@ -8,16 +8,17 @@ $: << File.dirname(__FILE__)
|
|
8
8
|
$: << File.dirname(__FILE__) + "/vendor/ruby-hmac/lib"
|
9
9
|
|
10
10
|
require 'rubygems'
|
11
|
+
require 'active_support'
|
11
12
|
|
12
|
-
require '
|
13
|
+
require 'openssl'
|
13
14
|
require 'base64'
|
14
15
|
require 'builder/xmlmarkup'
|
15
16
|
require 'hpricot'
|
16
17
|
require 'money'
|
17
18
|
require 'net/https'
|
18
|
-
require 'active_support'
|
19
19
|
|
20
20
|
require 'duck_punches/hpricot'
|
21
|
+
require 'duck_punches/inflector'
|
21
22
|
require 'google-checkout/notification'
|
22
23
|
require 'google-checkout/merchant_calculation'
|
23
24
|
require 'google-checkout/command'
|
data/lib/google-checkout/cart.rb
CHANGED
@@ -121,6 +121,23 @@ module GoogleCheckout
|
|
121
121
|
# You may fill in some optional values as well:
|
122
122
|
# * quantity (defaults to 1)
|
123
123
|
# * currency (defaults to 'USD')
|
124
|
+
#
|
125
|
+
# * subscription
|
126
|
+
# ** type (defaults to 'google')
|
127
|
+
# ** period (defaults to 'MONTHLY')
|
128
|
+
# ** start_date
|
129
|
+
# ** no_charge_after
|
130
|
+
# ** payment_times
|
131
|
+
# ** max_charge
|
132
|
+
# ** name
|
133
|
+
# ** description
|
134
|
+
# ** price
|
135
|
+
# ** quantity
|
136
|
+
#
|
137
|
+
# * digital_content
|
138
|
+
# ** disposition
|
139
|
+
# ** description
|
140
|
+
|
124
141
|
def add_item(item)
|
125
142
|
@xml = nil
|
126
143
|
if item.respond_to? :to_google_product
|
@@ -173,6 +190,65 @@ module GoogleCheckout
|
|
173
190
|
xml.quantity {
|
174
191
|
xml.text! item[:quantity].to_s
|
175
192
|
}
|
193
|
+
|
194
|
+
# subscription item
|
195
|
+
if item.key?(:subscription)
|
196
|
+
sub = item[:subscription]
|
197
|
+
|
198
|
+
sub_opts = {}
|
199
|
+
sub_opts.merge!(:type => sub[:type].to_s) if sub[:type]
|
200
|
+
sub_opts.merge!(:period => sub[:period].to_s) if sub[:period]
|
201
|
+
sub_opts.merge!(:"start-date" => sub[:start_date].to_s) if sub[:start_date]
|
202
|
+
sub_opts.merge!(:"no-charge-after" => sub[:no_charge_after].to_s) if sub[:no_charge_after]
|
203
|
+
|
204
|
+
xml.subscription(sub_opts) {
|
205
|
+
xml.payments {
|
206
|
+
if sub.key?(:payment_times)
|
207
|
+
xml.tag!('subscription-payment', :times => sub[:payment_times].to_s) {
|
208
|
+
xml.tag!('maximum-charge', :currency => (item[:currency] || 'USD')) {
|
209
|
+
xml.text! sub[:max_charge].to_s
|
210
|
+
}
|
211
|
+
}
|
212
|
+
else
|
213
|
+
xml.tag!('subscription-payment') {
|
214
|
+
xml.tag!('maximum-charge', :currency => (item[:currency] || 'USD')) {
|
215
|
+
xml.text! sub[:max_charge].to_s
|
216
|
+
}
|
217
|
+
}
|
218
|
+
end
|
219
|
+
}
|
220
|
+
|
221
|
+
xml.tag!('recurrent-item') {
|
222
|
+
xml.tag!('item-name') {
|
223
|
+
xml.text! sub[:name].to_s
|
224
|
+
}
|
225
|
+
xml.tag!('item-description') {
|
226
|
+
xml.text! sub[:description].to_s
|
227
|
+
}
|
228
|
+
xml.tag!('unit-price', :currency => (item[:currency] || 'USD')) {
|
229
|
+
xml.text! sub[:price].to_s
|
230
|
+
}
|
231
|
+
xml.quantity {
|
232
|
+
xml.text! sub[:quantity].to_s
|
233
|
+
}
|
234
|
+
}
|
235
|
+
}
|
236
|
+
end
|
237
|
+
|
238
|
+
# digital delivery
|
239
|
+
if item.key?(:digital_content)
|
240
|
+
content = item[:digital_content]
|
241
|
+
|
242
|
+
xml.tag!('digital-content') {
|
243
|
+
xml.tag!('display-disposition') {
|
244
|
+
xml.text! content[:disposition]
|
245
|
+
}
|
246
|
+
xml.description {
|
247
|
+
xml.text! content[:description].to_s
|
248
|
+
} if content[:description]
|
249
|
+
}
|
250
|
+
end
|
251
|
+
|
176
252
|
xml.tag!('merchant-private-item-data') {
|
177
253
|
xml << item[:merchant_private_item_data]
|
178
254
|
} if item.key?(:merchant_private_item_data)
|
@@ -227,7 +303,8 @@ module GoogleCheckout
|
|
227
303
|
# Returns the signature for the cart XML.
|
228
304
|
def signature
|
229
305
|
@xml or to_xml
|
230
|
-
|
306
|
+
digest = OpenSSL::Digest::Digest.new('sha1')
|
307
|
+
OpenSSL::HMAC.digest(digest, @merchant_key, @xml)
|
231
308
|
end
|
232
309
|
|
233
310
|
# Returns HTML for a checkout form for buying all the items in the
|
@@ -290,7 +367,7 @@ module GoogleCheckout
|
|
290
367
|
|
291
368
|
# HACK Sandbox graphics are in the checkout subdirectory
|
292
369
|
subdir = ""
|
293
|
-
if GoogleCheckout.sandbox? && bname == "checkout.gif"
|
370
|
+
if GoogleCheckout.sandbox? && (bname == "checkout.gif" || bname == "buy.gif")
|
294
371
|
subdir = "checkout/"
|
295
372
|
end
|
296
373
|
|
@@ -100,7 +100,8 @@ module GoogleCheckout
|
|
100
100
|
xml = Builder::XmlMarkup.new
|
101
101
|
xml.instruct!
|
102
102
|
@xml = xml.tag!('notification-acknowledgment', {
|
103
|
-
:xmlns => "http://checkout.google.com/schema/2"
|
103
|
+
:xmlns => "http://checkout.google.com/schema/2",
|
104
|
+
'serial-number' => serial_number
|
104
105
|
})
|
105
106
|
@xml
|
106
107
|
end
|
@@ -152,7 +153,17 @@ module GoogleCheckout
|
|
152
153
|
|
153
154
|
end
|
154
155
|
|
155
|
-
class ChargebackAmountNotification < Notification
|
156
|
+
class ChargebackAmountNotification < Notification
|
157
|
+
|
158
|
+
def latest_chargeback_amount
|
159
|
+
(@doc/"latest-chargeback-amount").to_money
|
160
|
+
end
|
161
|
+
|
162
|
+
def total_chargeback_amount
|
163
|
+
(@doc/"total-chargeback-amount").to_money
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
156
167
|
|
157
168
|
class NewOrderNotification < Notification
|
158
169
|
|
@@ -325,6 +336,8 @@ module GoogleCheckout
|
|
325
336
|
|
326
337
|
class RiskInformationNotification < Notification; end
|
327
338
|
|
339
|
+
class CancelledSubscriptionNotification < Notification; end
|
340
|
+
|
328
341
|
class CheckoutRedirect < Notification
|
329
342
|
|
330
343
|
##
|
@@ -334,7 +347,7 @@ module GoogleCheckout
|
|
334
347
|
(@doc/"redirect-url").inner_html.gsub(/&/, '&')
|
335
348
|
end
|
336
349
|
|
337
|
-
end
|
350
|
+
end
|
338
351
|
|
339
352
|
class Error < Notification
|
340
353
|
|
@@ -8,6 +8,32 @@
|
|
8
8
|
<unit-price currency="USD">159.99</unit-price>
|
9
9
|
<quantity>1</quantity>
|
10
10
|
</item>
|
11
|
+
<item>
|
12
|
+
<item-name>Bronze-level site hosting membership</item-name>
|
13
|
+
<item-description>30GB of disk space.</item-description>
|
14
|
+
<quantity>1</quantity>
|
15
|
+
<unit-price currency="USD">0</unit-price>
|
16
|
+
<subscription type="google" period="MONTHLY"
|
17
|
+
start-date="2008-04-01T07:55:55.952-08:00"
|
18
|
+
no-charge-after="2009-03-31T07:55:55.952-08:00">
|
19
|
+
<payments>
|
20
|
+
<subscription-payment times="12">
|
21
|
+
<maximum-charge currency="USD">12.99</maximum-charge>
|
22
|
+
</subscription-payment>
|
23
|
+
</payments>
|
24
|
+
<recurrent-item>
|
25
|
+
<item-name>Usage of My Awesome Website for One Month</item-name>
|
26
|
+
<item-description>Your flat charge for accessing my website</item-description>
|
27
|
+
<quantity>1</quantity>
|
28
|
+
<unit-price currency="USD">12.00</unit-price>
|
29
|
+
<digital-content>
|
30
|
+
<display-disposition>OPTIMISTIC</display-disposition>
|
31
|
+
<url>http://mywebsite.example.com</url>
|
32
|
+
<description>Head over to the website linked below for pie!</description>
|
33
|
+
</digital-content>
|
34
|
+
</recurrent-item>
|
35
|
+
</subscription>
|
36
|
+
</item>
|
11
37
|
</items>
|
12
38
|
</shopping-cart>
|
13
39
|
<checkout-flow-support>
|
@@ -0,0 +1,7 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<cancelled-subscription-notification xmlns="http://checkout.google.com/schema/2" serial-number="bea6bc1b-e1e2-44fe-80ff-0180e33a2614">
|
3
|
+
<item-ids />
|
4
|
+
<google-order-number>841171949013218</google-order-number>
|
5
|
+
<reason>Customer request to cancel</reason>
|
6
|
+
<timestamp>2009-10-15T23:51:04.662Z</timestamp>
|
7
|
+
</cancelled-subscription-notification>
|
@@ -22,7 +22,7 @@ describe GoogleCheckout, "Cart (generic)" do
|
|
22
22
|
end
|
23
23
|
|
24
24
|
it "should generate proper sandbox buy button_url" do
|
25
|
-
@cart.button_url.should match(%r{http://sandbox\.google\.com/buttons/buy\.gif})
|
25
|
+
@cart.button_url.should match(%r{http://sandbox\.google\.com/checkout/buttons/buy\.gif})
|
26
26
|
end
|
27
27
|
|
28
28
|
it "should generate proper sandbox checkout button_url" do
|
@@ -43,7 +43,7 @@ describe GoogleCheckout, "New Order Notification" do
|
|
43
43
|
it "should create Money object from order total" do
|
44
44
|
@notification.order_total.should be_kind_of(Money)
|
45
45
|
@notification.order_total.cents.should == 19098
|
46
|
-
@notification.order_total.currency.should == 'USD'
|
46
|
+
@notification.order_total.currency.iso_code.should == 'USD'
|
47
47
|
end
|
48
48
|
|
49
49
|
it "should throw error when accessing non-existent value" do
|
@@ -235,6 +235,12 @@ describe GoogleCheckout, "Chargeback Amount Notification" do
|
|
235
235
|
@notification.should be_kind_of(GoogleCheckout::ChargebackAmountNotification)
|
236
236
|
end
|
237
237
|
|
238
|
+
it "parses chargeback amounts as money objects" do
|
239
|
+
@notification.latest_chargeback_amount.cents.should == 22606
|
240
|
+
@notification.total_chargeback_amount.cents.should == 22606
|
241
|
+
@notification.latest_chargeback_amount.currency.iso_code.should == 'USD'
|
242
|
+
end
|
243
|
+
|
238
244
|
end
|
239
245
|
|
240
246
|
describe GoogleCheckout, "Refund Amount Notification" do
|
@@ -251,3 +257,16 @@ describe GoogleCheckout, "Refund Amount Notification" do
|
|
251
257
|
|
252
258
|
end
|
253
259
|
|
260
|
+
describe GoogleCheckout, "Cancelled Order Notification" do
|
261
|
+
|
262
|
+
before(:each) do
|
263
|
+
@notification = GoogleCheckout::Notification.parse(read_xml_fixture('notifications/cancelled-subscription-notification'))
|
264
|
+
end
|
265
|
+
|
266
|
+
it_should_behave_like "basic notification"
|
267
|
+
|
268
|
+
it "should identify type of notification" do
|
269
|
+
@notification.should be_kind_of(GoogleCheckout::CancelledSubscriptionNotification)
|
270
|
+
end
|
271
|
+
|
272
|
+
end
|
metadata
CHANGED
@@ -1,31 +1,30 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vizjerai-google-checkout
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 3
|
10
|
+
version: 0.1.3
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- Peter Elmore
|
8
14
|
- Geoffrey Grosenbach
|
9
15
|
- Matt Lins
|
16
|
+
- Steel Fu
|
17
|
+
- Andrew Assarattanakul
|
10
18
|
autorequire:
|
11
19
|
bindir: bin
|
12
20
|
cert_chain: []
|
13
21
|
|
14
|
-
date:
|
22
|
+
date: 2011-02-11 00:00:00 -06:00
|
15
23
|
default_executable:
|
16
|
-
dependencies:
|
17
|
-
|
18
|
-
name: ruby-hmac
|
19
|
-
type: :runtime
|
20
|
-
version_requirement:
|
21
|
-
version_requirements: !ruby/object:Gem::Requirement
|
22
|
-
requirements:
|
23
|
-
- - ">="
|
24
|
-
- !ruby/object:Gem::Version
|
25
|
-
version: "0"
|
26
|
-
version:
|
24
|
+
dependencies: []
|
25
|
+
|
27
26
|
description: An experimental library for sending payment requests to Google Checkout.
|
28
|
-
email:
|
27
|
+
email: assarata@gmail.com
|
29
28
|
executables: []
|
30
29
|
|
31
30
|
extensions: []
|
@@ -37,9 +36,10 @@ files:
|
|
37
36
|
- MIT-LICENSE.txt
|
38
37
|
- README.txt
|
39
38
|
- Rakefile
|
40
|
-
- VERSION
|
39
|
+
- VERSION
|
41
40
|
- examples/google_notifications_controller.rb
|
42
41
|
- lib/duck_punches/hpricot.rb
|
42
|
+
- lib/duck_punches/inflector.rb
|
43
43
|
- lib/google-checkout.rb
|
44
44
|
- lib/google-checkout/cart.rb
|
45
45
|
- lib/google-checkout/command.rb
|
@@ -73,6 +73,7 @@ files:
|
|
73
73
|
- spec/fixtures/google/commands/unarchive-order.xml
|
74
74
|
- spec/fixtures/google/merchant_calculations/shipping.xml
|
75
75
|
- spec/fixtures/google/notifications/authorization-amount-notification.xml
|
76
|
+
- spec/fixtures/google/notifications/cancelled-subscription-notification.xml
|
76
77
|
- spec/fixtures/google/notifications/charge-amount-notification.xml
|
77
78
|
- spec/fixtures/google/notifications/chargeback-amount-notification.xml
|
78
79
|
- spec/fixtures/google/notifications/new-order-notification.xml
|
@@ -100,32 +101,41 @@ files:
|
|
100
101
|
- spec/spec_helper.rb
|
101
102
|
- support/cacert.pem
|
102
103
|
has_rdoc: true
|
103
|
-
homepage: http://github.com/
|
104
|
+
homepage: http://github.com/vizjerai/google-checkout/
|
105
|
+
licenses: []
|
106
|
+
|
104
107
|
post_install_message:
|
105
|
-
rdoc_options:
|
106
|
-
|
108
|
+
rdoc_options: []
|
109
|
+
|
107
110
|
require_paths:
|
108
111
|
- lib
|
109
112
|
required_ruby_version: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
110
114
|
requirements:
|
111
115
|
- - ">="
|
112
116
|
- !ruby/object:Gem::Version
|
117
|
+
hash: 3
|
118
|
+
segments:
|
119
|
+
- 0
|
113
120
|
version: "0"
|
114
|
-
version:
|
115
121
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
122
|
+
none: false
|
116
123
|
requirements:
|
117
124
|
- - ">="
|
118
125
|
- !ruby/object:Gem::Version
|
126
|
+
hash: 3
|
127
|
+
segments:
|
128
|
+
- 0
|
119
129
|
version: "0"
|
120
|
-
version:
|
121
130
|
requirements: []
|
122
131
|
|
123
132
|
rubyforge_project:
|
124
|
-
rubygems_version: 1.2
|
133
|
+
rubygems_version: 1.5.2
|
125
134
|
signing_key:
|
126
|
-
specification_version:
|
135
|
+
specification_version: 3
|
127
136
|
summary: An experimental library for sending payment requests to Google Checkout.
|
128
137
|
test_files:
|
138
|
+
- examples/google_notifications_controller.rb
|
129
139
|
- spec/google-checkout/cart_spec.rb
|
130
140
|
- spec/google-checkout/command_spec.rb
|
131
141
|
- spec/google-checkout/geography/postal_spec.rb
|
@@ -141,4 +151,3 @@ test_files:
|
|
141
151
|
- spec/google-checkout/shipping/pickup_spec.rb
|
142
152
|
- spec/google-checkout_spec.rb
|
143
153
|
- spec/spec_helper.rb
|
144
|
-
- examples/google_notifications_controller.rb
|
data/VERSION.yml
DELETED