stripe 1.7.0 → 1.7.1

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.
Files changed (48) hide show
  1. data/.gitignore +2 -0
  2. data/.travis.yml +8 -0
  3. data/CONTRIBUTORS +3 -0
  4. data/Gemfile +2 -0
  5. data/Gemfile.lock +34 -0
  6. data/History.txt +68 -0
  7. data/LICENSE +21 -0
  8. data/README.rdoc +28 -0
  9. data/Rakefile +9 -0
  10. data/VERSION +1 -0
  11. data/gemfiles/default-with-activesupport.gemfile +3 -0
  12. data/gemfiles/default-with-activesupport.gemfile.lock +39 -0
  13. data/gemfiles/json.gemfile +4 -0
  14. data/gemfiles/json.gemfile.lock +41 -0
  15. data/gemfiles/yajl.gemfile +4 -0
  16. data/gemfiles/yajl.gemfile.lock +41 -0
  17. data/lib/stripe.rb +62 -500
  18. data/lib/stripe/account.rb +4 -0
  19. data/lib/stripe/api_operations/create.rb +16 -0
  20. data/lib/stripe/api_operations/delete.rb +11 -0
  21. data/lib/stripe/api_operations/list.rb +16 -0
  22. data/lib/stripe/api_operations/update.rb +15 -0
  23. data/lib/stripe/api_resource.rb +33 -0
  24. data/lib/stripe/charge.rb +29 -0
  25. data/lib/stripe/coupon.rb +7 -0
  26. data/lib/stripe/customer.rb +51 -0
  27. data/lib/stripe/errors/api_connection_error.rb +4 -0
  28. data/lib/stripe/errors/api_error.rb +4 -0
  29. data/lib/stripe/errors/authentication_error.rb +4 -0
  30. data/lib/stripe/errors/card_error.rb +11 -0
  31. data/lib/stripe/errors/invalid_request_error.rb +10 -0
  32. data/lib/stripe/errors/stripe_error.rb +20 -0
  33. data/lib/stripe/event.rb +5 -0
  34. data/lib/stripe/invoice.rb +16 -0
  35. data/lib/stripe/invoice_item.rb +8 -0
  36. data/lib/stripe/json.rb +21 -0
  37. data/lib/stripe/plan.rb +8 -0
  38. data/lib/stripe/singleton_api_resource.rb +20 -0
  39. data/lib/stripe/stripe_object.rb +150 -0
  40. data/lib/stripe/token.rb +5 -0
  41. data/lib/stripe/transfer.rb +16 -0
  42. data/lib/stripe/util.rb +103 -0
  43. data/lib/stripe/version.rb +1 -1
  44. data/stripe.gemspec +28 -0
  45. data/test/test_helper.rb +175 -0
  46. data/test/test_stripe.rb +472 -0
  47. data/test/test_stripe_with_active_support.rb +3 -0
  48. metadata +54 -7
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ /stripe-*.gem
2
+ .rvmrc
data/.travis.yml ADDED
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.3
5
+ gemfile:
6
+ - gemfiles/default-with-activesupport.gemfile
7
+ - gemfiles/json.gemfile
8
+ - gemfiles/yajl.gemfile
data/CONTRIBUTORS ADDED
@@ -0,0 +1,3 @@
1
+ Greg Brockman <gdb@gregbrockman.com>
2
+ Ross Boucher <rboucher@gmail.com>
3
+ Bradley Grzesiak <brad@bendyworks.com>
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "https://rubygems.org"
2
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,34 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ stripe (1.7.1)
5
+ multi_json (~> 1.1)
6
+ rest-client (~> 1.4)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ metaclass (0.0.1)
12
+ mime-types (1.19)
13
+ mocha (0.11.3)
14
+ metaclass (~> 0.0.1)
15
+ multi_json (1.3.6)
16
+ rake (0.9.2.2)
17
+ rest-client (1.6.7)
18
+ mime-types (>= 1.16)
19
+ shoulda (3.0.1)
20
+ shoulda-context (~> 1.0.0)
21
+ shoulda-matchers (~> 1.0.0)
22
+ shoulda-context (1.0.0)
23
+ shoulda-matchers (1.0.0)
24
+ test-unit (2.4.8)
25
+
26
+ PLATFORMS
27
+ ruby
28
+
29
+ DEPENDENCIES
30
+ mocha
31
+ rake
32
+ shoulda
33
+ stripe!
34
+ test-unit
data/History.txt ADDED
@@ -0,0 +1,68 @@
1
+ === 1.7.1 2012-08-15
2
+
3
+ * Add new Account API resource
4
+
5
+ === 1.7.0 2012-05-17
6
+
7
+ * 3 major enhancements:
8
+ * Switch from vendored stripe-json to multi_json for all JSON
9
+ parsing and rendering. This should not impact programmatic usage
10
+ of the library, but may cause small rendering differences from,
11
+ e.g., StripeObject#inspect (github issue #22)
12
+ * Add new delete_discount method to Customer objects
13
+ * Add new Transfer API resource
14
+
15
+ * 2 minor enhancements:
16
+ * Switch from HTTP Basic auth to Bearer auth (Note: Stripe will
17
+ support Basic auth for the indefinite future, but recommends
18
+ Bearer auth when possible going forward)
19
+ * Numerous test suite improvements
20
+
21
+ === 1.6.3 2012-03-22
22
+
23
+ * 1 bugfix:
24
+ * Encode GET query strings ourselves instead of using rest-client to
25
+ work around a bug
26
+
27
+ === 1.6.2 2012-02-24
28
+
29
+ * 1 bugfix:
30
+ * Correct argument handling in StripeObject#as_json
31
+
32
+ === 1.6.1 2012-02-22
33
+
34
+ * 1 bugfix:
35
+ * Fix StripeObject#inspect when ActiveSupport 3.0 is loaded
36
+
37
+ === 1.6.0 2012-02-01
38
+ * A whole bunch of releases between 1.5.0 and 1.6.0, but few changes, mainly the addition of:
39
+ - plans
40
+ - coupons
41
+ - events
42
+ - tokens
43
+ * 1.6.0 also contains a new inspect/to_string implementation
44
+
45
+ === 1.5.0 2011-05-09
46
+
47
+ * 1 major enhancement:
48
+ * Update for new RESTful API
49
+
50
+ === 1.3.4 2011-01-07
51
+
52
+ * 1 major enhancement:
53
+ * Rename to Stripe
54
+
55
+ === 1.2 2010-06-06
56
+
57
+ * 1 major enhancement:
58
+ * Support for the set_customer_subscription and delete_customer API methods
59
+
60
+ === 1.1 2010-03-14
61
+
62
+ * 1 major enhancement:
63
+ * Support for recurring billing
64
+
65
+ === 1.0 2010-01-05
66
+
67
+ * 1 major enhancement:
68
+ * Initial release
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2011- Stripe, Inc. (https://stripe.com)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,28 @@
1
+ = Stripe Ruby bindings
2
+
3
+ == Installation
4
+
5
+ You don't need this source code unless you want to modify the gem. If
6
+ you just want to use the Stripe Ruby bindings, you should run:
7
+
8
+ sudo gem install --source https://code.stripe.com stripe
9
+
10
+ If you want to build the gem from source:
11
+
12
+ sudo gem build stripe.gemspec
13
+
14
+ == Requirements
15
+
16
+ * Ruby 1.8.7 or above. (Ruby 1.8.6 may work if you load
17
+ ActiveSupport.)
18
+ * rest-client, multi_json
19
+
20
+ == Mirrors
21
+
22
+ The stripe gem is mirrored on Rubygems, so you should be able to
23
+ install it via <tt>gem install stripe</tt> if desired. We recommend using
24
+ the https://code.stripe.com mirror so all code is fetched over SSL.
25
+
26
+ == Development
27
+
28
+ Test cases can be run with: `bundle exec rake test`
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ task :default => [:test]
2
+
3
+ task :test do
4
+ ret = true
5
+ Dir["test/**/*.rb"].each do |f|
6
+ ret = ret && ruby(f, '')
7
+ end
8
+ exit(ret)
9
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.7.1
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+ gemspec :path => File.join(File.dirname(__FILE__), "..")
3
+ gem "activesupport"
@@ -0,0 +1,39 @@
1
+ PATH
2
+ remote: /home/evan/src/stripe-ruby
3
+ specs:
4
+ stripe (1.7.0)
5
+ multi_json (~> 1.1)
6
+ rest-client (~> 1.4)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ activesupport (3.2.3)
12
+ i18n (~> 0.6)
13
+ multi_json (~> 1.0)
14
+ i18n (0.6.0)
15
+ metaclass (0.0.1)
16
+ mime-types (1.18)
17
+ mocha (0.11.4)
18
+ metaclass (~> 0.0.1)
19
+ multi_json (1.3.4)
20
+ rake (0.9.2.2)
21
+ rest-client (1.6.7)
22
+ mime-types (>= 1.16)
23
+ shoulda (3.0.1)
24
+ shoulda-context (~> 1.0.0)
25
+ shoulda-matchers (~> 1.0.0)
26
+ shoulda-context (1.0.0)
27
+ shoulda-matchers (1.0.0)
28
+ test-unit (2.4.8)
29
+
30
+ PLATFORMS
31
+ ruby
32
+
33
+ DEPENDENCIES
34
+ activesupport
35
+ mocha
36
+ rake
37
+ shoulda
38
+ stripe!
39
+ test-unit
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+ gemspec :path => File.join(File.dirname(__FILE__), "..")
3
+ gem "json"
4
+ gem "activesupport"
@@ -0,0 +1,41 @@
1
+ PATH
2
+ remote: /home/evan/src/stripe-ruby
3
+ specs:
4
+ stripe (1.7.0)
5
+ multi_json (~> 1.1)
6
+ rest-client (~> 1.4)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ activesupport (3.2.3)
12
+ i18n (~> 0.6)
13
+ multi_json (~> 1.0)
14
+ i18n (0.6.0)
15
+ json (1.7.0)
16
+ metaclass (0.0.1)
17
+ mime-types (1.18)
18
+ mocha (0.11.3)
19
+ metaclass (~> 0.0.1)
20
+ multi_json (1.3.4)
21
+ rake (0.9.2.2)
22
+ rest-client (1.6.7)
23
+ mime-types (>= 1.16)
24
+ shoulda (3.0.1)
25
+ shoulda-context (~> 1.0.0)
26
+ shoulda-matchers (~> 1.0.0)
27
+ shoulda-context (1.0.0)
28
+ shoulda-matchers (1.0.0)
29
+ test-unit (2.4.8)
30
+
31
+ PLATFORMS
32
+ ruby
33
+
34
+ DEPENDENCIES
35
+ activesupport
36
+ json
37
+ mocha
38
+ rake
39
+ shoulda
40
+ stripe!
41
+ test-unit
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+ gemspec :path => File.join(File.dirname(__FILE__), "..")
3
+ gem "yajl-ruby"
4
+ gem "activesupport"
@@ -0,0 +1,41 @@
1
+ PATH
2
+ remote: /home/evan/src/stripe-ruby
3
+ specs:
4
+ stripe (1.7.0)
5
+ multi_json (~> 1.1)
6
+ rest-client (~> 1.4)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ activesupport (3.2.3)
12
+ i18n (~> 0.6)
13
+ multi_json (~> 1.0)
14
+ i18n (0.6.0)
15
+ metaclass (0.0.1)
16
+ mime-types (1.18)
17
+ mocha (0.11.3)
18
+ metaclass (~> 0.0.1)
19
+ multi_json (1.3.4)
20
+ rake (0.9.2.2)
21
+ rest-client (1.6.7)
22
+ mime-types (>= 1.16)
23
+ shoulda (3.0.1)
24
+ shoulda-context (~> 1.0.0)
25
+ shoulda-matchers (~> 1.0.0)
26
+ shoulda-context (1.0.0)
27
+ shoulda-matchers (1.0.0)
28
+ test-unit (2.4.8)
29
+ yajl-ruby (1.1.0)
30
+
31
+ PLATFORMS
32
+ ruby
33
+
34
+ DEPENDENCIES
35
+ activesupport
36
+ mocha
37
+ rake
38
+ shoulda
39
+ stripe!
40
+ test-unit
41
+ yajl-ruby
data/lib/stripe.rb CHANGED
@@ -2,7 +2,6 @@
2
2
  # API spec at http://stripe.com/api/spec
3
3
  require 'cgi'
4
4
  require 'set'
5
-
6
5
  require 'rubygems'
7
6
  require 'openssl'
8
7
 
@@ -10,7 +9,39 @@ gem 'rest-client', '~> 1.4'
10
9
  require 'rest_client'
11
10
  require 'multi_json'
12
11
 
13
- require File.join(File.dirname(__FILE__), 'stripe/version')
12
+ # Version
13
+ require 'stripe/version'
14
+
15
+ # API operations
16
+ require 'stripe/api_operations/create'
17
+ require 'stripe/api_operations/update'
18
+ require 'stripe/api_operations/delete'
19
+ require 'stripe/api_operations/list'
20
+
21
+ # Resources
22
+ require 'stripe/util'
23
+ require 'stripe/json'
24
+ require 'stripe/stripe_object'
25
+ require 'stripe/api_resource'
26
+ require 'stripe/singleton_api_resource'
27
+ require 'stripe/account'
28
+ require 'stripe/customer'
29
+ require 'stripe/invoice'
30
+ require 'stripe/invoice_item'
31
+ require 'stripe/charge'
32
+ require 'stripe/plan'
33
+ require 'stripe/coupon'
34
+ require 'stripe/token'
35
+ require 'stripe/event'
36
+ require 'stripe/transfer'
37
+
38
+ # Errors
39
+ require 'stripe/errors/stripe_error'
40
+ require 'stripe/errors/api_error'
41
+ require 'stripe/errors/api_connection_error'
42
+ require 'stripe/errors/card_error'
43
+ require 'stripe/errors/invalid_request_error'
44
+ require 'stripe/errors/authentication_error'
14
45
 
15
46
  module Stripe
16
47
  @@ssl_bundle_path = File.join(File.dirname(__FILE__), 'data/ca-certificates.crt')
@@ -18,513 +49,33 @@ module Stripe
18
49
  @@api_base = 'https://api.stripe.com/v1'
19
50
  @@verify_ssl_certs = true
20
51
 
21
- module Util
22
- def self.objects_to_ids(h)
23
- case h
24
- when APIResource
25
- h.id
26
- when Hash
27
- res = {}
28
- h.each { |k, v| res[k] = objects_to_ids(v) unless v.nil? }
29
- res
30
- when Array
31
- h.map { |v| objects_to_ids(v) }
32
- else
33
- h
34
- end
35
- end
36
-
37
- def self.convert_to_stripe_object(resp, api_key)
38
- types = {
39
- 'charge' => Charge,
40
- 'customer' => Customer,
41
- 'invoiceitem' => InvoiceItem,
42
- 'invoice' => Invoice,
43
- 'plan' => Plan,
44
- 'coupon' => Coupon,
45
- 'event' => Event,
46
- 'transfer' => Transfer
47
- }
48
- case resp
49
- when Array
50
- resp.map { |i| convert_to_stripe_object(i, api_key) }
51
- when Hash
52
- # Try converting to a known object class. If none available, fall back to generic APIResource
53
- if klass_name = resp[:object]
54
- klass = types[klass_name]
55
- end
56
- klass ||= StripeObject
57
- klass.construct_from(resp, api_key)
58
- else
59
- resp
60
- end
61
- end
62
-
63
- def self.file_readable(file)
64
- begin
65
- File.open(file) { |f| }
66
- rescue
67
- false
68
- else
69
- true
70
- end
71
- end
72
-
73
- def self.symbolize_names(object)
74
- case object
75
- when Hash
76
- new = {}
77
- object.each do |key, value|
78
- key = (key.to_sym rescue key) || key
79
- new[key] = symbolize_names(value)
80
- end
81
- new
82
- when Array
83
- object.map { |value| symbolize_names(value) }
84
- else
85
- object
86
- end
87
- end
88
-
89
- def self.encode_key(key)
90
- URI.escape(key.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
91
- end
92
-
93
- def self.flatten_params(params, parent_key = nil)
94
- result = []
95
- params.each do |key, value|
96
- calculated_key = parent_key ? "#{parent_key}[#{encode_key(key)}]" : encode_key(key)
97
- if value.is_a? Hash
98
- result += flatten_params(value, calculated_key)
99
- elsif value.is_a? Array
100
- result += flatten_params_array(value, calculated_key)
101
- else
102
- result << [calculated_key, value]
103
- end
104
- end
105
- result
106
- end
107
-
108
- def self.flatten_params_array value, calculated_key
109
- result = []
110
- value.each do |elem|
111
- if elem.is_a? Hash
112
- result += flatten_params(elem, calculated_key)
113
- elsif elem.is_a? Array
114
- result += flatten_params_array(elem, calculated_key)
115
- else
116
- result << ["#{calculated_key}[]", elem]
117
- end
118
- end
119
- result
120
- end
52
+ def self.api_url(url='')
53
+ @@api_base + url
121
54
  end
122
55
 
123
- module JSON
124
- if MultiJson.respond_to?(:dump)
125
- def self.dump(*args)
126
- MultiJson.dump(*args)
127
- end
128
- def self.load(*args)
129
- MultiJson.load(*args)
130
- end
131
- else
132
- def self.dump(*args)
133
- MultiJson.encode(*args)
134
- end
135
- def self.load(*args)
136
- MultiJson.decode(*args)
137
- end
138
- end
56
+ def self.api_key=(api_key)
57
+ @@api_key = api_key
139
58
  end
140
59
 
141
- module APIOperations
142
- module Create
143
- module ClassMethods
144
- def create(params={}, api_key=nil)
145
- response, api_key = Stripe.request(:post, self.url, api_key, params)
146
- Util.convert_to_stripe_object(response, api_key)
147
- end
148
- end
149
- def self.included(base)
150
- base.extend(ClassMethods)
151
- end
152
- end
153
-
154
- module Update
155
- def save
156
- if @unsaved_values.length > 0
157
- values = {}
158
- @unsaved_values.each { |k| values[k] = @values[k] }
159
- response, api_key = Stripe.request(:post, url, @api_key, values)
160
- refresh_from(response, api_key)
161
- end
162
- self
163
- end
164
- end
165
-
166
- module Delete
167
- def delete
168
- response, api_key = Stripe.request(:delete, url, @api_key)
169
- refresh_from(response, api_key)
170
- self
171
- end
172
- end
173
-
174
- module List
175
- module ClassMethods
176
- def all(filters={}, api_key=nil)
177
- response, api_key = Stripe.request(:get, url, api_key, filters)
178
- Util.convert_to_stripe_object(response, api_key)
179
- end
180
- end
181
-
182
- def self.included(base)
183
- base.extend(ClassMethods)
184
- end
185
- end
60
+ def self.api_key
61
+ @@api_key
186
62
  end
187
63
 
188
- class StripeObject
189
- include Enumerable
190
-
191
- attr_accessor :api_key
192
- @@permanent_attributes = Set.new([:api_key])
193
-
194
- # The default :id method is deprecated and isn't useful to us
195
- if method_defined?(:id)
196
- undef :id
197
- end
198
-
199
- def initialize(id=nil, api_key=nil)
200
- @api_key = api_key
201
- @values = {}
202
- # This really belongs in APIResource, but not putting it there allows us
203
- # to have a unified inspect method
204
- @unsaved_values = Set.new
205
- @transient_values = Set.new
206
- self.id = id if id
207
- end
208
-
209
- def self.construct_from(values, api_key=nil)
210
- obj = self.new(values[:id], api_key)
211
- obj.refresh_from(values, api_key)
212
- obj
213
- end
214
-
215
- def to_s(*args); Stripe::JSON.dump(@values, :pretty => true); end
216
-
217
- def inspect()
218
- id_string = (self.respond_to?(:id) && !self.id.nil?) ? " id=#{self.id}" : ""
219
- "#<#{self.class}:0x#{self.object_id.to_s(16)}#{id_string}> JSON: " + Stripe::JSON.dump(@values, :pretty => true)
220
- end
221
-
222
- def refresh_from(values, api_key, partial=false)
223
- @api_key = api_key
224
-
225
- removed = partial ? Set.new : Set.new(@values.keys - values.keys)
226
- added = Set.new(values.keys - @values.keys)
227
- # Wipe old state before setting new. This is useful for e.g. updating a
228
- # customer, where there is no persistent card parameter. Mark those values
229
- # which don't persist as transient
230
-
231
- instance_eval do
232
- remove_accessors(removed)
233
- add_accessors(added)
234
- end
235
- removed.each do |k|
236
- @values.delete(k)
237
- @transient_values.add(k)
238
- @unsaved_values.delete(k)
239
- end
240
- values.each do |k, v|
241
- @values[k] = Util.convert_to_stripe_object(v, api_key)
242
- @transient_values.delete(k)
243
- @unsaved_values.delete(k)
244
- end
245
- end
246
-
247
- def [](k)
248
- k = k.to_sym if k.kind_of?(String)
249
- @values[k]
250
- end
251
- def []=(k, v)
252
- send(:"#{k}=", v)
253
- end
254
- def keys; @values.keys; end
255
- def values; @values.values; end
256
- def to_json(*a); Stripe::JSON.dump(@values); end
257
- def as_json(*a); @values.as_json(*a); end
258
- def to_hash; @values; end
259
- def each(&blk); @values.each(&blk); end
260
-
261
- protected
262
-
263
- def metaclass
264
- class << self; self; end
265
- end
266
-
267
- def remove_accessors(keys)
268
- metaclass.instance_eval do
269
- keys.each do |k|
270
- next if @@permanent_attributes.include?(k)
271
- k_eq = :"#{k}="
272
- remove_method(k) if method_defined?(k)
273
- remove_method(k_eq) if method_defined?(k_eq)
274
- end
275
- end
276
- end
277
-
278
- def add_accessors(keys)
279
- metaclass.instance_eval do
280
- keys.each do |k|
281
- next if @@permanent_attributes.include?(k)
282
- k_eq = :"#{k}="
283
- define_method(k) { @values[k] }
284
- define_method(k_eq) do |v|
285
- @values[k] = v
286
- @unsaved_values.add(k)
287
- end
288
- end
289
- end
290
- end
291
-
292
- def method_missing(name, *args)
293
- # TODO: only allow setting in updateable classes.
294
- if name.to_s.end_with?('=')
295
- attr = name.to_s[0...-1].to_sym
296
- @values[attr] = args[0]
297
- @unsaved_values.add(attr)
298
- add_accessors([attr])
299
- return
300
- else
301
- return @values[name] if @values.has_key?(name)
302
- end
303
-
304
- begin
305
- super
306
- rescue NoMethodError => e
307
- if @transient_values.include?(name)
308
- raise NoMethodError.new(e.message + ". HINT: The '#{name}' attribute was set in the past, however. It was then wiped when refreshing the object with the result returned by Stripe's API, probably as a result of a save(). The attributes currently available on this object are: #{@values.keys.join(', ')}")
309
- else
310
- raise
311
- end
312
- end
313
- end
64
+ def self.api_base=(api_base)
65
+ @@api_base = api_base
314
66
  end
315
67
 
316
- class APIResource < StripeObject
317
- def self.url
318
- if self == APIResource
319
- raise NotImplementedError.new("APIResource is an abstract class. You should perform actions on its subclasses (Charge, Customer, etc.)")
320
- end
321
- shortname = self.name.split('::')[-1]
322
- "/#{CGI.escape(shortname.downcase)}s"
323
- end
324
- def url
325
- id = self['id']
326
- raise InvalidRequestError.new("Could not determine which URL to request: #{self.class} instance has invalid ID: #{id.inspect}", 'id') unless id
327
- "#{self.class.url}/#{CGI.escape(id)}"
328
- end
329
-
330
- def refresh
331
- response, api_key = Stripe.request(:get, url, @api_key)
332
- refresh_from(response, api_key)
333
- self
334
- end
335
-
336
- def self.retrieve(id, api_key=nil)
337
- instance = self.new(id, api_key)
338
- instance.refresh
339
- instance
340
- end
341
-
342
- protected
343
- end
344
-
345
- class Customer < APIResource
346
- include Stripe::APIOperations::Create
347
- include Stripe::APIOperations::Delete
348
- include Stripe::APIOperations::Update
349
- include Stripe::APIOperations::List
350
-
351
- def add_invoice_item(params)
352
- InvoiceItem.create(params.merge(:customer => id), @api_key)
353
- end
354
-
355
- def invoices
356
- Invoice.all({ :customer => id }, @api_key)
357
- end
358
-
359
- def invoice_items
360
- InvoiceItem.all({ :customer => id }, @api_key)
361
- end
362
-
363
- def charges
364
- Charge.all({ :customer => id }, @api_key)
365
- end
366
-
367
- def cancel_subscription(params={})
368
- response, api_key = Stripe.request(:delete, subscription_url, @api_key, params)
369
- refresh_from({ :subscription => response }, api_key, true)
370
- subscription
371
- end
372
-
373
- def update_subscription(params)
374
- response, api_key = Stripe.request(:post, subscription_url, @api_key, params)
375
- refresh_from({ :subscription => response }, api_key, true)
376
- subscription
377
- end
378
-
379
- def delete_discount
380
- Stripe.request(:delete, discount_url, @api_key)
381
- refresh_from({ :discount => nil }, api_key, true)
382
- end
383
-
384
- private
385
-
386
- def discount_url
387
- url + '/discount'
388
- end
389
-
390
- def subscription_url
391
- url + '/subscription'
392
- end
393
- end
394
-
395
- class Invoice < APIResource
396
- include Stripe::APIOperations::List
397
-
398
- def self.upcoming(params)
399
- response, api_key = Stripe.request(:get, upcoming_url, @api_key, params)
400
- Util.convert_to_stripe_object(response, api_key)
401
- end
402
-
403
- private
404
-
405
- def self.upcoming_url
406
- url + '/upcoming'
407
- end
408
- end
409
-
410
- class InvoiceItem < APIResource
411
- include Stripe::APIOperations::List
412
- include Stripe::APIOperations::Create
413
- include Stripe::APIOperations::Delete
414
- include Stripe::APIOperations::Update
415
- end
416
-
417
- class Charge < APIResource
418
- include Stripe::APIOperations::List
419
- include Stripe::APIOperations::Create
420
- include Stripe::APIOperations::Update
421
-
422
- def refund(params={})
423
- response, api_key = Stripe.request(:post, refund_url, @api_key, params)
424
- refresh_from(response, api_key)
425
- self
426
- end
427
-
428
- def capture(params={})
429
- response, api_key = Stripe.request(:post, capture_url, @api_key, params)
430
- refresh_from(response, api_key)
431
- self
432
- end
433
-
434
- private
435
-
436
- def refund_url
437
- url + '/refund'
438
- end
439
-
440
- def capture_url
441
- url + '/capture'
442
- end
443
- end
444
-
445
- class Plan < APIResource
446
- include Stripe::APIOperations::Create
447
- include Stripe::APIOperations::Delete
448
- include Stripe::APIOperations::List
449
- include Stripe::APIOperations::Update
450
- end
451
-
452
- class Coupon < APIResource
453
- include Stripe::APIOperations::Create
454
- include Stripe::APIOperations::Delete
455
- include Stripe::APIOperations::List
456
- end
457
-
458
- class Token < APIResource
459
- include Stripe::APIOperations::Create
460
- end
461
-
462
- class Event < APIResource
463
- include Stripe::APIOperations::List
464
- end
465
-
466
- class Transfer < APIResource
467
- include Stripe::APIOperations::List
468
-
469
- def transactions(params={})
470
- response, api_key = Stripe.request(:get, transactions_url, @api_key, params)
471
- Util.convert_to_stripe_object(response, api_key)
472
- end
473
-
474
- private
475
-
476
- def transactions_url
477
- url + '/transactions'
478
- end
479
- end
480
-
481
- class StripeError < StandardError
482
- attr_reader :message
483
- attr_reader :http_status
484
- attr_reader :http_body
485
- attr_reader :json_body
486
-
487
- def initialize(message=nil, http_status=nil, http_body=nil, json_body=nil)
488
- @message = message
489
- @http_status = http_status
490
- @http_body = http_body
491
- @json_body = json_body
492
- end
493
-
494
- def to_s
495
- status_string = @http_status.nil? ? "" : "(Status #{@http_status}) "
496
- "#{status_string}#{@message}"
497
- end
68
+ def self.api_base
69
+ @@api_base
498
70
  end
499
71
 
500
- class APIError < StripeError; end
501
- class APIConnectionError < StripeError; end
502
- class CardError < StripeError
503
- attr_reader :param, :code
504
-
505
- def initialize(message, param, code, http_status=nil, http_body=nil, json_body=nil)
506
- super(message, http_status, http_body, json_body)
507
- @param = param
508
- @code = code
509
- end
72
+ def self.verify_ssl_certs=(verify)
73
+ @@verify_ssl_certs = verify
510
74
  end
511
- class InvalidRequestError < StripeError
512
- attr_accessor :param
513
75
 
514
- def initialize(message, param, http_status=nil, http_body=nil, json_body=nil)
515
- super(message, http_status, http_body, json_body)
516
- @param = param
517
- end
76
+ def self.verify_ssl_certs
77
+ @@verify_ssl_certs
518
78
  end
519
- class AuthenticationError < StripeError; end
520
-
521
- def self.api_url(url=''); @@api_base + url; end
522
- def self.api_key=(api_key); @@api_key = api_key; end
523
- def self.api_key; @@api_key; end
524
- def self.api_base=(api_base); @@api_base = api_base; end
525
- def self.api_base; @@api_base; end
526
- def self.verify_ssl_certs=(verify); @@verify_ssl_certs = verify; end
527
- def self.verify_ssl_certs; @@verify_ssl_certs; end
528
79
 
529
80
  def self.request(method, url, api_key, params=nil, headers={})
530
81
  api_key ||= @@api_key
@@ -658,10 +209,21 @@ module Stripe
658
209
  end
659
210
  end
660
211
 
661
- def self.invalid_request_error(error, rcode, rbody, error_obj); InvalidRequestError.new(error[:message], error[:param], rcode, rbody, error_obj); end
662
- def self.authentication_error(error, rcode, rbody, error_obj); AuthenticationError.new(error[:message], rcode, rbody, error_obj); end
663
- def self.card_error(error, rcode, rbody, error_obj); CardError.new(error[:message], error[:param], error[:code], rcode, rbody, error_obj); end
664
- def self.api_error(error, rcode, rbody, error_obj); APIError.new(error[:message], rcode, rbody, error_obj); end
212
+ def self.invalid_request_error(error, rcode, rbody, error_obj)
213
+ InvalidRequestError.new(error[:message], error[:param], rcode, rbody, error_obj)
214
+ end
215
+
216
+ def self.authentication_error(error, rcode, rbody, error_obj)
217
+ AuthenticationError.new(error[:message], rcode, rbody, error_obj)
218
+ end
219
+
220
+ def self.card_error(error, rcode, rbody, error_obj)
221
+ CardError.new(error[:message], error[:param], error[:code], rcode, rbody, error_obj)
222
+ end
223
+
224
+ def self.api_error(error, rcode, rbody, error_obj)
225
+ APIError.new(error[:message], rcode, rbody, error_obj)
226
+ end
665
227
 
666
228
  def self.handle_restclient_error(e)
667
229
  case e