topfunky-google-checkout 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/History.txt +14 -0
  2. data/MIT-LICENSE.txt +23 -0
  3. data/Manifest.txt +40 -0
  4. data/README.txt +139 -0
  5. data/Rakefile +21 -0
  6. data/examples/google_notifications_controller.rb +159 -0
  7. data/lib/duck_punches/hpricot.rb +24 -0
  8. data/lib/google-checkout.rb +61 -0
  9. data/lib/google-checkout/cart.rb +349 -0
  10. data/lib/google-checkout/command.rb +191 -0
  11. data/lib/google-checkout/notification.rb +212 -0
  12. data/spec/fixtures/google/checkout-shopping-cart.xml +22 -0
  13. data/spec/fixtures/google/commands/add-merchant-order-number.xml +5 -0
  14. data/spec/fixtures/google/commands/add-tracking-data.xml +8 -0
  15. data/spec/fixtures/google/commands/archive-order.xml +3 -0
  16. data/spec/fixtures/google/commands/authorize-order.xml +2 -0
  17. data/spec/fixtures/google/commands/cancel-order.xml +5 -0
  18. data/spec/fixtures/google/commands/charge-order.xml +4 -0
  19. data/spec/fixtures/google/commands/deliver-order.xml +9 -0
  20. data/spec/fixtures/google/commands/process-order.xml +2 -0
  21. data/spec/fixtures/google/commands/refund-order.xml +6 -0
  22. data/spec/fixtures/google/commands/send-buyer-message.xml +7 -0
  23. data/spec/fixtures/google/commands/unarchive-order.xml +2 -0
  24. data/spec/fixtures/google/notifications/authorization-amount-notification.xml +10 -0
  25. data/spec/fixtures/google/notifications/charge-amount-notification.xml +8 -0
  26. data/spec/fixtures/google/notifications/chargeback-amount-notification.xml +8 -0
  27. data/spec/fixtures/google/notifications/new-order-notification.xml +85 -0
  28. data/spec/fixtures/google/notifications/order-state-change-notification.xml +11 -0
  29. data/spec/fixtures/google/notifications/refund-amount-notification.xml +8 -0
  30. data/spec/fixtures/google/notifications/risk-information-notification.xml +23 -0
  31. data/spec/fixtures/google/responses/checkout-redirect.xml +5 -0
  32. data/spec/fixtures/google/responses/error.xml +5 -0
  33. data/spec/fixtures/google/responses/request-received.xml +3 -0
  34. data/spec/google-checkout/cart_spec.rb +101 -0
  35. data/spec/google-checkout/command_spec.rb +131 -0
  36. data/spec/google-checkout/notification_spec.rb +175 -0
  37. data/spec/google-checkout/response_spec.rb +49 -0
  38. data/spec/google-checkout_spec.rb +15 -0
  39. data/spec/spec_helper.rb +47 -0
  40. data/support/cacert.pem +7815 -0
  41. metadata +114 -0
@@ -0,0 +1,212 @@
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 = 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
+ end
181
+
182
+ class OrderStateChangeNotification < Notification; end
183
+
184
+ class RefundAmountNotification < Notification; end
185
+
186
+ class RiskInformationNotification < Notification; end
187
+
188
+ class CheckoutRedirect < Notification
189
+
190
+ ##
191
+ # Returns redirect-url with ampersands escaped, as specified by Google API docs.
192
+
193
+ def redirect_url
194
+ (@doc/"redirect-url").inner_html.gsub(/&amp;/, '&')
195
+ end
196
+
197
+ end
198
+
199
+ class Error < Notification
200
+
201
+ ##
202
+ # Alias for +error_message+
203
+
204
+ def message
205
+ (@doc/'error-message').inner_html
206
+ end
207
+
208
+ end
209
+
210
+ class RequestReceived < Notification; end
211
+
212
+ 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,5 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <add-merchant-order-number xmlns="http://checkout.google.com/schema/2"
3
+ google-order-number="841171949013218">
4
+ <merchant-order-number>P6502-53-7861SBJD</merchant-order-number>
5
+ </add-merchant-order-number>
@@ -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,3 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <archive-order xmlns="http://checkout.google.com/schema/2"
3
+ google-order-number="841171949013218" />
@@ -0,0 +1,2 @@
1
+ <authorize-order xmlns="http://checkout.google.com/schema/2"
2
+ google-order-number="6014423719"/>
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <cancel-order xmlns="http://checkout.google.com/schema/2" google-order-number="841171949013218">
3
+ <reason>Buyer cancelled the order.</reason>
4
+ <comment>Buyer ordered another item.</comment>
5
+ </cancel-order>
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <charge-order xmlns="http://checkout.google.com/schema/2" google-order-number="6014423719">
3
+ <amount currency="USD">335.55</amount>
4
+ </charge-order>
@@ -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>
@@ -0,0 +1,2 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <process-order xmlns="http://checkout.google.com/schema/2" google-order-number="841171949013218"/>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <refund-order xmlns="http://checkout.google.com/schema/2" google-order-number="6014423719">
3
+ <amount currency="USD">15.00</amount>
4
+ <comment>Discount for inconvenience; ship replacement item</comment>
5
+ <reason>Damaged Merchandise</reason>
6
+ </refund-order>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <send-buyer-message xmlns="http://checkout.google.com/schema/2"
3
+ google-order-number="841171949013218">
4
+ <message>Due to high volume, your order will ship
5
+ next week. Thank you for your patience.</message>
6
+ <send-email>true</send-email>
7
+ </send-buyer-message>
@@ -0,0 +1,2 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <unarchive-order xmlns="http://checkout.google.com/schema/2" google-order-number="841171949013218" />
@@ -0,0 +1,10 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <authorization-amount-notification xmlns="http://checkout.google.com/schema/2"
3
+ serial-number="bea6bc1b-e1e2-44fe-80ff-0180e33a2614">
4
+ <google-order-number>841171949013218</google-order-number>
5
+ <authorization-amount currency="USD">226.06</authorization-amount>
6
+ <authorization-expiration-date>2006-03-18T20:25:31</authorization-expiration-date>
7
+ <avs-response>Y</avs-response>
8
+ <cvn-response>Y</cvn-response>
9
+ <timestamp>2006-03-18T20:25:31</timestamp>
10
+ </authorization-amount-notification>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <charge-amount-notification xmlns="http://checkout.google.com/schema/2"
3
+ serial-number="bea6bc1b-e1e2-44fe-80ff-0180e33a2614">
4
+ <google-order-number>841171949013218</google-order-number>
5
+ <latest-charge-amount currency="USD">226.06</latest-charge-amount>
6
+ <total-charge-amount currency="USD">226.06</total-charge-amount>
7
+ <timestamp>2006-03-18T18:25:31</timestamp>
8
+ </charge-amount-notification>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <chargeback-amount-notification xmlns="http://checkout.google.com/schema/2"
3
+ serial-number="bea6bc1b-e1e2-44fe-80ff-0180e33a2614">
4
+ <google-order-number>841171949013218</google-order-number>
5
+ <latest-chargeback-amount currency="USD">226.06</latest-chargeback-amount>
6
+ <total-chargeback-amount currency="USD">226.06</total-chargeback-amount>
7
+ <timestamp>2006-03-18T20:25:31</timestamp>
8
+ </chargeback-amount-notification>
@@ -0,0 +1,85 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <new-order-notification xmlns="http://checkout.google.com/schema/2"
3
+ serial-number="bea6bc1b-e1e2-44fe-80ff-0180e33a2614">
4
+ <google-order-number>841171949013218</google-order-number>
5
+ <buyer-shipping-address>
6
+
7
+ <contact-name>John Smith</contact-name>
8
+ <email>johnsmith@example.com</email>
9
+ <address1>10 Example Road</address1>
10
+ <city>Sampleville</city>
11
+ <region>CA</region>
12
+ <postal-code>94141</postal-code>
13
+ <country-code>US</country-code>
14
+ </buyer-shipping-address>
15
+ <buyer-billing-address>
16
+ <contact-name>Bill Hu</contact-name>
17
+ <email>billhu@example.com</email>
18
+ <address1>99 Credit Lane</address1>
19
+ <city>Mountain View</city>
20
+ <region>CA</region>
21
+ <postal-code>94043</postal-code>
22
+ <country-code>US</country-code>
23
+ </buyer-billing-address>
24
+ <buyer-id>294873009217523</buyer-id>
25
+ <fulfillment-order-state>NEW</fulfillment-order-state>
26
+ <financial-order-state>REVIEWING</financial-order-state>
27
+
28
+ <shopping-cart>
29
+ <cart-expiration>
30
+ <good-until-date>2007-12-31T23:59:59-05:00</good-until-date>
31
+ </cart-expiration>
32
+ <items>
33
+ <item>
34
+ <merchant-item-id>GGLAA1453</merchant-item-id>
35
+ <item-name>Dry Food Pack</item-name>
36
+ <item-description>One pack of nutritious dried food for emergencies.</item-description>
37
+ <quantity>1</quantity>
38
+ <tax-table-selector>food</tax-table-selector>
39
+ <unit-price currency="USD">4.99</unit-price>
40
+ </item>
41
+ <item>
42
+ <merchant-item-id>MGS2GBMP3</merchant-item-id>
43
+ <item-name>Megasound 2GB MP3 Player</item-name>
44
+ <item-description>This portable MP3 player stores 500 songs.</item-description>
45
+ <quantity>1</quantity>
46
+ <unit-price currency="USD">179.99</unit-price>
47
+ <merchant-private-item-data>
48
+ <merchant-product-id>1234567890</merchant-product-id>
49
+ </merchant-private-item-data>
50
+ </item>
51
+ </items>
52
+ <merchant-private-data>
53
+ <peepcode-order-number>1234-5678-9012</peepcode-order-number>
54
+ </merchant-private-data>
55
+ </shopping-cart>
56
+ <order-adjustment>
57
+ <merchant-calculation-successful>true</merchant-calculation-successful>
58
+ <merchant-codes>
59
+ <coupon-adjustment>
60
+ <applied-amount currency="USD">5.00</applied-amount>
61
+ <code>FirstVisitCoupon</code>
62
+ <calculated-amount currency="USD">5.00</calculated-amount>
63
+ <message>You saved $5.00 for your first visit!</message>
64
+ </coupon-adjustment>
65
+ <gift-certificate-adjustment>
66
+ <applied-amount currency="USD">10.00</applied-amount>
67
+ <code>GiftCert12345</code>
68
+ <calculated-amount currency="USD">10.00</calculated-amount>
69
+ <message>You saved $10.00 with this gift certificate!</message>
70
+ </gift-certificate-adjustment>
71
+ </merchant-codes>
72
+ <total-tax currency="USD">0.0</total-tax>
73
+ <shipping>
74
+ <merchant-calculated-shipping-adjustment>
75
+ <shipping-name>SuperShip</shipping-name>
76
+ <shipping-cost currency="USD">9.95</shipping-cost>
77
+ </merchant-calculated-shipping-adjustment>
78
+ </shipping>
79
+ </order-adjustment>
80
+ <order-total currency="USD">190.98</order-total>
81
+ <buyer-marketing-preferences>
82
+ <email-allowed>false</email-allowed>
83
+ </buyer-marketing-preferences>
84
+ <timestamp>2006-05-03T17:32:11</timestamp>
85
+ </new-order-notification>
@@ -0,0 +1,11 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <order-state-change-notification xmlns="http://checkout.google.com/schema/2"
3
+ serial-number="bea6bc1b-e1e2-44fe-80ff-0180e33a2614">
4
+ <google-order-number>841171949013218</google-order-number>
5
+ <new-financial-order-state>CHARGING</new-financial-order-state>
6
+ <new-fulfillment-order-state>NEW</new-fulfillment-order-state>
7
+ <previous-financial-order-state>CHARGEABLE</previous-financial-order-state>
8
+ <previous-fulfillment-order-state>NEW</previous-fulfillment-order-state>
9
+ <reason>The reason goes here, if there is one.</reason>
10
+ <timestamp>2006-05-03T17:32:11</timestamp>
11
+ </order-state-change-notification>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <refund-amount-notification xmlns="http://checkout.google.com/schema/2"
3
+ serial-number="bea6bc1b-e1e2-44fe-80ff-0180e33a2614">
4
+ <google-order-number>841171949013218</google-order-number>
5
+ <latest-refund-amount currency="USD">226.06</latest-refund-amount>
6
+ <total-refund-amount currency="USD">226.06</total-refund-amount>
7
+ <timestamp>2006-03-18T20:25:31</timestamp>
8
+ </refund-amount-notification>