stripe 1.7.0 → 1.7.1

Sign up to get free protection for your applications and to get access to all the features.
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