stripe 1.18.0 → 1.30.0

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 (81) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.travis.yml +11 -1
  4. data/History.txt +98 -0
  5. data/README.rdoc +19 -10
  6. data/VERSION +1 -1
  7. data/lib/stripe/account.rb +46 -4
  8. data/lib/stripe/api_operations/create.rb +3 -10
  9. data/lib/stripe/api_operations/delete.rb +4 -4
  10. data/lib/stripe/api_operations/list.rb +17 -9
  11. data/lib/stripe/api_operations/request.rb +41 -0
  12. data/lib/stripe/api_operations/update.rb +41 -40
  13. data/lib/stripe/api_resource.rb +7 -4
  14. data/lib/stripe/application_fee.rb +3 -4
  15. data/lib/stripe/application_fee_refund.rb +1 -1
  16. data/lib/stripe/balance_transaction.rb +1 -1
  17. data/lib/stripe/bank_account.rb +19 -0
  18. data/lib/stripe/bitcoin_receiver.rb +12 -2
  19. data/lib/stripe/bitcoin_transaction.rb +5 -0
  20. data/lib/stripe/card.rb +6 -4
  21. data/lib/stripe/charge.rb +14 -22
  22. data/lib/stripe/coupon.rb +2 -2
  23. data/lib/stripe/customer.rb +24 -26
  24. data/lib/stripe/dispute.rb +16 -0
  25. data/lib/stripe/errors/card_error.rb +3 -2
  26. data/lib/stripe/errors/invalid_request_error.rb +3 -2
  27. data/lib/stripe/errors/rate_limit_error.rb +4 -0
  28. data/lib/stripe/errors/stripe_error.rb +8 -2
  29. data/lib/stripe/event.rb +1 -1
  30. data/lib/stripe/file_upload.rb +12 -22
  31. data/lib/stripe/invoice.rb +8 -8
  32. data/lib/stripe/invoice_item.rb +2 -2
  33. data/lib/stripe/list_object.rb +77 -13
  34. data/lib/stripe/order.rb +19 -0
  35. data/lib/stripe/plan.rb +2 -2
  36. data/lib/stripe/product.rb +16 -0
  37. data/lib/stripe/recipient.rb +2 -2
  38. data/lib/stripe/refund.rb +2 -9
  39. data/lib/stripe/reversal.rb +14 -0
  40. data/lib/stripe/singleton_api_resource.rb +2 -2
  41. data/lib/stripe/sku.rb +8 -0
  42. data/lib/stripe/stripe_object.rb +232 -46
  43. data/lib/stripe/subscription.rb +3 -3
  44. data/lib/stripe/token.rb +1 -1
  45. data/lib/stripe/transfer.rb +3 -3
  46. data/lib/stripe/util.rb +64 -21
  47. data/lib/stripe/version.rb +1 -1
  48. data/lib/stripe.rb +102 -67
  49. data/stripe.gemspec +0 -2
  50. data/test/stripe/account_test.rb +135 -6
  51. data/test/stripe/api_resource_test.rb +326 -42
  52. data/test/stripe/application_fee_refund_test.rb +6 -6
  53. data/test/stripe/application_fee_test.rb +3 -3
  54. data/test/stripe/balance_test.rb +11 -0
  55. data/test/stripe/bitcoin_receiver_test.rb +30 -7
  56. data/test/stripe/bitcoin_transaction_test.rb +29 -0
  57. data/test/stripe/charge_refund_test.rb +55 -0
  58. data/test/stripe/charge_test.rb +32 -13
  59. data/test/stripe/coupon_test.rb +3 -3
  60. data/test/stripe/customer_card_test.rb +20 -14
  61. data/test/stripe/customer_test.rb +15 -15
  62. data/test/stripe/dispute_test.rb +45 -0
  63. data/test/stripe/file_upload_test.rb +17 -6
  64. data/test/stripe/invoice_test.rb +18 -4
  65. data/test/stripe/list_object_test.rb +126 -2
  66. data/test/stripe/metadata_test.rb +28 -13
  67. data/test/stripe/order_test.rb +52 -0
  68. data/test/stripe/product_test.rb +41 -0
  69. data/test/stripe/recipient_card_test.rb +9 -9
  70. data/test/stripe/refund_test.rb +23 -15
  71. data/test/stripe/reversal_test.rb +47 -0
  72. data/test/stripe/sku_test.rb +24 -0
  73. data/test/stripe/stripe_object_test.rb +67 -6
  74. data/test/stripe/subscription_test.rb +13 -13
  75. data/test/stripe/transfer_test.rb +4 -4
  76. data/test/stripe/util_test.rb +45 -29
  77. data/test/stripe_test.rb +16 -0
  78. data/test/test_data.rb +273 -66
  79. metadata +47 -76
  80. data/lib/stripe/certificate_blacklist.rb +0 -55
  81. data/test/stripe/certificate_blacklist_test.rb +0 -18
@@ -2,25 +2,16 @@ module Stripe
2
2
  class StripeObject
3
3
  include Enumerable
4
4
 
5
- attr_accessor :api_key
6
- @@permanent_attributes = Set.new([:api_key, :id])
5
+ @@permanent_attributes = Set.new([:id])
7
6
 
8
7
  # The default :id method is deprecated and isn't useful to us
9
8
  if method_defined?(:id)
10
9
  undef :id
11
10
  end
12
11
 
13
- def initialize(id=nil, api_key=nil)
14
- # parameter overloading!
15
- if id.kind_of?(Hash)
16
- @retrieve_options = id.dup
17
- @retrieve_options.delete(:id)
18
- id = id[:id]
19
- else
20
- @retrieve_options = {}
21
- end
22
-
23
- @api_key = api_key
12
+ def initialize(id=nil, opts={})
13
+ id, @retrieve_params = Util.normalize_id(id)
14
+ @opts = Util.normalize_opts(opts)
24
15
  @values = {}
25
16
  # This really belongs in APIResource, but not putting it there allows us
26
17
  # to have a unified inspect method
@@ -29,8 +20,25 @@ module Stripe
29
20
  @values[:id] = id if id
30
21
  end
31
22
 
32
- def self.construct_from(values, api_key=nil)
33
- self.new(values[:id], api_key).refresh_from(values, api_key)
23
+ def self.construct_from(values, opts={})
24
+ values = Stripe::Util.symbolize_names(values)
25
+
26
+ # work around protected #initialize_from for now
27
+ self.new(values[:id]).send(:initialize_from, values, opts)
28
+ end
29
+
30
+ # Determines the equality of two Stripe objects. Stripe objects are
31
+ # considered to be equal if they have the same set of values and each one
32
+ # of those values is the same.
33
+ def ==(other)
34
+ @values == other.instance_variable_get(:@values)
35
+ end
36
+
37
+ # Indicates whether or not the resource has been deleted on the server.
38
+ # Note that some, but not all, resources can indicate whether they have
39
+ # been deleted.
40
+ def deleted?
41
+ @values.fetch(:deleted, false)
34
42
  end
35
43
 
36
44
  def to_s(*args)
@@ -42,32 +50,36 @@ module Stripe
42
50
  "#<#{self.class}:0x#{self.object_id.to_s(16)}#{id_string}> JSON: " + JSON.pretty_generate(@values)
43
51
  end
44
52
 
45
- def refresh_from(values, api_key, partial=false)
46
- @api_key = api_key
47
-
48
- @previous_metadata = values[:metadata]
49
- removed = partial ? Set.new : Set.new(@values.keys - values.keys)
50
- added = Set.new(values.keys - @values.keys)
51
- # Wipe old state before setting new. This is useful for e.g. updating a
52
- # customer, where there is no persistent card parameter. Mark those values
53
- # which don't persist as transient
53
+ # Re-initializes the object based on a hash of values (usually one that's
54
+ # come back from an API call). Adds or removes value accessors as necessary
55
+ # and updates the state of internal data.
56
+ #
57
+ # Please don't use this method. If you're trying to do mass assignment, try
58
+ # #initialize_from instead.
59
+ def refresh_from(values, opts, partial=false)
60
+ initialize_from(values, opts, partial)
61
+ end
62
+ extend Gem::Deprecate
63
+ deprecate :refresh_from, "#update_attributes", 2016, 01
54
64
 
55
- instance_eval do
56
- remove_accessors(removed)
57
- add_accessors(added)
58
- end
59
- removed.each do |k|
60
- @values.delete(k)
61
- @transient_values.add(k)
62
- @unsaved_values.delete(k)
63
- end
65
+ # Mass assigns attributes on the model.
66
+ #
67
+ # This is a version of +update_attributes+ that takes some extra options
68
+ # for internal use.
69
+ #
70
+ # ==== Attributes
71
+ #
72
+ # * +values+ - Hash of values to use to update the current attributes of
73
+ # the object.
74
+ #
75
+ # ==== Options
76
+ #
77
+ # * +:opts+ Options for StripeObject like an API key.
78
+ def update_attributes(values, opts = {})
64
79
  values.each do |k, v|
65
- @values[k] = Util.convert_to_stripe_object(v, api_key)
66
- @transient_values.delete(k)
67
- @unsaved_values.delete(k)
80
+ @values[k] = Util.convert_to_stripe_object(v, opts)
81
+ @unsaved_values.add(k)
68
82
  end
69
-
70
- return self
71
83
  end
72
84
 
73
85
  def [](k)
@@ -95,8 +107,17 @@ module Stripe
95
107
  end
96
108
 
97
109
  def to_hash
110
+ maybe_to_hash = lambda do |value|
111
+ value.respond_to?(:to_hash) ? value.to_hash : value
112
+ end
113
+
98
114
  @values.inject({}) do |acc, (key, value)|
99
- acc[key] = value.respond_to?(:to_hash) ? value.to_hash : value
115
+ acc[key] = case value
116
+ when Array
117
+ value.map(&maybe_to_hash)
118
+ else
119
+ maybe_to_hash.call(value)
120
+ end
100
121
  acc
101
122
  end
102
123
  end
@@ -106,12 +127,12 @@ module Stripe
106
127
  end
107
128
 
108
129
  def _dump(level)
109
- Marshal.dump([@values, @api_key])
130
+ Marshal.dump([@values, @opts])
110
131
  end
111
132
 
112
133
  def self._load(args)
113
- values, api_key = Marshal.load(args)
114
- construct_from(values, api_key)
134
+ values, opts = Marshal.load(args)
135
+ construct_from(values, opts)
115
136
  end
116
137
 
117
138
  if RUBY_VERSION < '1.9.2'
@@ -120,15 +141,96 @@ module Stripe
120
141
  end
121
142
  end
122
143
 
144
+ def serialize_nested_object(key)
145
+ new_value = @values[key]
146
+ if new_value.is_a?(APIResource)
147
+ return {}
148
+ end
149
+
150
+ if @unsaved_values.include?(key)
151
+ # the object has been reassigned
152
+ # e.g. as object.key = {foo => bar}
153
+ update = new_value
154
+ new_keys = update.keys.map(&:to_sym)
155
+
156
+ # remove keys at the server, but not known locally
157
+ if @original_values[key]
158
+ keys_to_unset = @original_values[key].keys - new_keys
159
+ keys_to_unset.each {|key| update[key] = ''}
160
+ end
161
+
162
+ update
163
+ else
164
+ # can be serialized normally
165
+ self.class.serialize_params(new_value)
166
+ end
167
+ end
168
+
169
+ def self.serialize_params(obj, original_value=nil)
170
+ case obj
171
+ when nil
172
+ ''
173
+ when StripeObject
174
+ unsaved_keys = obj.instance_variable_get(:@unsaved_values)
175
+ obj_values = obj.instance_variable_get(:@values)
176
+ update_hash = {}
177
+
178
+ unsaved_keys.each do |k|
179
+ update_hash[k] = serialize_params(obj_values[k])
180
+ end
181
+
182
+ obj_values.each do |k, v|
183
+ if v.is_a?(StripeObject) || v.is_a?(Hash)
184
+ update_hash[k] = obj.serialize_nested_object(k)
185
+ elsif v.is_a?(Array)
186
+ original_value = obj.instance_variable_get(:@original_values)[k]
187
+ if original_value && original_value.length > v.length
188
+ # url params provide no mechanism for deleting an item in an array,
189
+ # just overwriting the whole array or adding new items. So let's not
190
+ # allow deleting without a full overwrite until we have a solution.
191
+ raise ArgumentError.new(
192
+ "You cannot delete an item from an array, you must instead set a new array"
193
+ )
194
+ end
195
+ update_hash[k] = serialize_params(v, original_value)
196
+ end
197
+ end
198
+
199
+ update_hash
200
+ when Array
201
+ update_hash = {}
202
+ obj.each_with_index do |value, index|
203
+ update = serialize_params(value)
204
+ if update != {} && (!original_value || update != original_value[index])
205
+ update_hash[index] = update
206
+ end
207
+ end
208
+
209
+ if update_hash == {}
210
+ nil
211
+ else
212
+ update_hash
213
+ end
214
+ else
215
+ obj
216
+ end
217
+ end
218
+
123
219
  protected
124
220
 
125
221
  def metaclass
126
222
  class << self; self; end
127
223
  end
128
224
 
225
+ def protected_fields
226
+ []
227
+ end
228
+
129
229
  def remove_accessors(keys)
230
+ f = protected_fields
130
231
  metaclass.instance_eval do
131
232
  keys.each do |k|
233
+ next if f.include?(k)
132
234
  next if @@permanent_attributes.include?(k)
133
235
  k_eq = :"#{k}="
134
236
  remove_method(k) if method_defined?(k)
@@ -137,22 +239,29 @@ module Stripe
137
239
  end
138
240
  end
139
241
 
140
- def add_accessors(keys)
242
+ def add_accessors(keys, values)
243
+ f = protected_fields
141
244
  metaclass.instance_eval do
142
245
  keys.each do |k|
246
+ next if f.include?(k)
143
247
  next if @@permanent_attributes.include?(k)
144
248
  k_eq = :"#{k}="
145
249
  define_method(k) { @values[k] }
146
250
  define_method(k_eq) do |v|
147
251
  if v == ""
148
252
  raise ArgumentError.new(
149
- "You cannot set #{k} to an empty string." +
150
- "We interpret empty strings as nil in requests." +
253
+ "You cannot set #{k} to an empty string." \
254
+ "We interpret empty strings as nil in requests." \
151
255
  "You may set #{self}.#{k} = nil to delete the property.")
152
256
  end
153
257
  @values[k] = v
154
258
  @unsaved_values.add(k)
155
259
  end
260
+
261
+ if [FalseClass, TrueClass].include?(values[k].class)
262
+ k_bool = :"#{k}?"
263
+ define_method(k_bool) { @values[k] }
264
+ end
156
265
  end
157
266
  end
158
267
  end
@@ -161,7 +270,10 @@ module Stripe
161
270
  # TODO: only allow setting in updateable classes.
162
271
  if name.to_s.end_with?('=')
163
272
  attr = name.to_s[0...-1].to_sym
164
- add_accessors([attr])
273
+
274
+ # the second argument is only required when adding boolean accessors
275
+ add_accessors([attr], {})
276
+
165
277
  begin
166
278
  mth = method(name)
167
279
  rescue NameError
@@ -186,5 +298,79 @@ module Stripe
186
298
  def respond_to_missing?(symbol, include_private = false)
187
299
  @values && @values.has_key?(symbol) || super
188
300
  end
301
+
302
+ # Re-initializes the object based on a hash of values (usually one that's
303
+ # come back from an API call). Adds or removes value accessors as necessary
304
+ # and updates the state of internal data.
305
+ #
306
+ # Protected on purpose! Please do not expose.
307
+ #
308
+ # ==== Options
309
+ #
310
+ # * +:values:+ Hash used to update accessors and values.
311
+ # * +:opts:+ Options for StripeObject like an API key.
312
+ # * +:partial:+ Indicates that the re-initialization should not attempt to
313
+ # remove accessors.
314
+ def initialize_from(values, opts, partial=false)
315
+ @opts = Util.normalize_opts(opts)
316
+ @original_values = Marshal.load(Marshal.dump(values)) # deep copy
317
+
318
+ removed = partial ? Set.new : Set.new(@values.keys - values.keys)
319
+ added = Set.new(values.keys - @values.keys)
320
+
321
+ # Wipe old state before setting new. This is useful for e.g. updating a
322
+ # customer, where there is no persistent card parameter. Mark those values
323
+ # which don't persist as transient
324
+
325
+ instance_eval do
326
+ remove_accessors(removed)
327
+ add_accessors(added, values)
328
+ end
329
+
330
+ removed.each do |k|
331
+ @values.delete(k)
332
+ @transient_values.add(k)
333
+ @unsaved_values.delete(k)
334
+ end
335
+
336
+ update_attributes(values, :opts => opts)
337
+ values.each do |k, _|
338
+ @transient_values.delete(k)
339
+ @unsaved_values.delete(k)
340
+ end
341
+
342
+ self
343
+ end
344
+
345
+ # Mass assigns attributes on the model.
346
+ #
347
+ # This is a version of +update_attributes+ that takes some extra options
348
+ # for internal use.
349
+ #
350
+ # ==== Options
351
+ #
352
+ # * +:opts:+ Options for StripeObject like an API key.
353
+ # * +:raise_error:+ Set to false to suppress ArgumentErrors on keys that
354
+ # don't exist.
355
+ def update_attributes_with_options(values, options={})
356
+ # `opts` are StripeObject options
357
+ opts = options.fetch(:opts, {})
358
+ raise_error = options.fetch(:raise_error, true)
359
+
360
+ values.each do |k, v|
361
+ if !@@permanent_attributes.include?(k) && !self.respond_to?(:"#{k}=")
362
+ if raise_error
363
+ raise ArgumentError,
364
+ "#{k} is not an attribute that can be assigned on this object"
365
+ else
366
+ next
367
+ end
368
+ end
369
+
370
+ @values[k] = Util.convert_to_stripe_object(v, opts)
371
+ @unsaved_values.add(k)
372
+ end
373
+ self
374
+ end
189
375
  end
190
376
  end
@@ -7,13 +7,13 @@ module Stripe
7
7
  "#{Customer.url}/#{CGI.escape(customer)}/subscriptions/#{CGI.escape(id)}"
8
8
  end
9
9
 
10
- def self.retrieve(id, api_key=nil)
10
+ def self.retrieve(id, opts=nil)
11
11
  raise NotImplementedError.new("Subscriptions cannot be retrieved without a customer ID. Retrieve a subscription using customer.subscriptions.retrieve('subscription_id')")
12
12
  end
13
13
 
14
14
  def delete_discount
15
- Stripe.request(:delete, discount_url, @api_key)
16
- refresh_from({ :discount => nil }, api_key, true)
15
+ response, opts = request(:delete, discount_url)
16
+ initialize_from({ :discount => nil }, opts, true)
17
17
  end
18
18
 
19
19
  private
data/lib/stripe/token.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Stripe
2
2
  class Token < APIResource
3
- include Stripe::APIOperations::Create
3
+ extend Stripe::APIOperations::Create
4
4
  end
5
5
  end
@@ -1,12 +1,12 @@
1
1
  module Stripe
2
2
  class Transfer < APIResource
3
- include Stripe::APIOperations::List
4
- include Stripe::APIOperations::Create
3
+ extend Stripe::APIOperations::List
4
+ extend Stripe::APIOperations::Create
5
5
  include Stripe::APIOperations::Update
6
6
 
7
7
  def cancel
8
8
  response, api_key = Stripe.request(:post, cancel_url, @api_key)
9
- refresh_from(response, api_key)
9
+ initialize_from(response, api_key)
10
10
  end
11
11
 
12
12
  def cancel_url
data/lib/stripe/util.rb CHANGED
@@ -1,3 +1,5 @@
1
+ require "cgi"
2
+
1
3
  module Stripe
2
4
  module Util
3
5
  def self.objects_to_ids(h)
@@ -21,9 +23,11 @@ module Stripe
21
23
  'list' => ListObject,
22
24
 
23
25
  # business objects
26
+ 'account' => Account,
24
27
  'application_fee' => ApplicationFee,
25
28
  'balance' => Balance,
26
29
  'balance_transaction' => BalanceTransaction,
30
+ 'bank_account' => BankAccount,
27
31
  'card' => Card,
28
32
  'charge' => Charge,
29
33
  'coupon' => Coupon,
@@ -37,19 +41,25 @@ module Stripe
37
41
  'refund' => Refund,
38
42
  'subscription' => Subscription,
39
43
  'file_upload' => FileUpload,
44
+ 'token' => Token,
40
45
  'transfer' => Transfer,
46
+ 'transfer_reversal' => Reversal,
41
47
  'bitcoin_receiver' => BitcoinReceiver,
42
- 'bitcoin_transaction' => BitcoinTransaction
48
+ 'bitcoin_transaction' => BitcoinTransaction,
49
+ 'dispute' => Dispute,
50
+ 'product' => Product,
51
+ 'sku' => SKU,
52
+ 'order' => Order,
43
53
  }
44
54
  end
45
55
 
46
- def self.convert_to_stripe_object(resp, api_key)
56
+ def self.convert_to_stripe_object(resp, opts)
47
57
  case resp
48
58
  when Array
49
- resp.map { |i| convert_to_stripe_object(i, api_key) }
59
+ resp.map { |i| convert_to_stripe_object(i, opts) }
50
60
  when Hash
51
61
  # Try converting to a known object class. If none available, fall back to generic StripeObject
52
- object_classes.fetch(resp[:object], StripeObject).construct_from(resp, api_key)
62
+ object_classes.fetch(resp[:object], StripeObject).construct_from(resp, opts)
53
63
  else
54
64
  resp
55
65
  end
@@ -84,14 +94,30 @@ module Stripe
84
94
  end
85
95
  end
86
96
 
97
+ # Encodes a hash of parameters in a way that's suitable for use as query
98
+ # parameters in a URI or as form parameters in a request body. This mainly
99
+ # involves escaping special characters from parameter keys and values (e.g.
100
+ # `&`).
101
+ def self.encode_parameters(params)
102
+ Util.flatten_params(params).
103
+ map { |k,v| "#{url_encode(k)}=#{url_encode(v)}" }.join('&')
104
+ end
105
+
106
+ # Encodes a string in a way that makes it suitable for use in a set of
107
+ # query parameters in a URI or in a set of form parameters in a request
108
+ # body.
87
109
  def self.url_encode(key)
88
- URI.escape(key.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
110
+ CGI.escape(key.to_s).
111
+ # Don't use strict form encoding by changing the square bracket control
112
+ # characters back to their literals. This is fine by the server, and
113
+ # makes these parameter strings easier to read.
114
+ gsub('%5B', '[').gsub('%5D', ']')
89
115
  end
90
116
 
91
117
  def self.flatten_params(params, parent_key=nil)
92
118
  result = []
93
119
  params.each do |key, value|
94
- calculated_key = parent_key ? "#{parent_key}[#{url_encode(key)}]" : url_encode(key)
120
+ calculated_key = parent_key ? "#{parent_key}[#{key}]" : "#{key}"
95
121
  if value.is_a?(Hash)
96
122
  result += flatten_params(value, calculated_key)
97
123
  elsif value.is_a?(Array)
@@ -100,14 +126,19 @@ module Stripe
100
126
  result << [calculated_key, value]
101
127
  end
102
128
  end
103
- result
129
+
130
+ # The #sort_by call here is mostly so that we can get some stability in
131
+ # our 1.8.7 test suite where Hash key order is not preserved.
132
+ #
133
+ # https://www.igvita.com/2009/02/04/ruby-19-internals-ordered-hash/
134
+ result.sort_by { |(k, _)| k }
104
135
  end
105
136
 
106
137
  def self.flatten_params_array(value, calculated_key)
107
138
  result = []
108
139
  value.each do |elem|
109
140
  if elem.is_a?(Hash)
110
- result += flatten_params(elem, calculated_key)
141
+ result += flatten_params(elem, "#{calculated_key}[]")
111
142
  elsif elem.is_a?(Array)
112
143
  result += flatten_params_array(elem, calculated_key)
113
144
  else
@@ -117,26 +148,38 @@ module Stripe
117
148
  result
118
149
  end
119
150
 
151
+ def self.normalize_id(id)
152
+ if id.kind_of?(Hash) # overloaded id
153
+ params_hash = id.dup
154
+ id = params_hash.delete(:id)
155
+ else
156
+ params_hash = {}
157
+ end
158
+ [id, params_hash]
159
+ end
160
+
120
161
  # The secondary opts argument can either be a string or hash
121
162
  # Turn this value into an api_key and a set of headers
122
- def self.parse_opts(opts)
163
+ def self.normalize_opts(opts)
123
164
  case opts
124
- when NilClass
125
- return nil, {}
126
165
  when String
127
- return opts, {}
166
+ {:api_key => opts}
128
167
  when Hash
129
- headers = {}
130
- if opts[:idempotency_key]
131
- headers[:idempotency_key] = opts[:idempotency_key]
132
- end
133
- if opts[:stripe_account]
134
- headers[:stripe_account] = opts[:stripe_account]
135
- end
136
- return opts[:api_key], headers
168
+ check_api_key!(opts.fetch(:api_key)) if opts.has_key?(:api_key)
169
+ opts.clone
137
170
  else
138
- raise TypeError.new("parse_opts expects a string or a hash")
171
+ raise TypeError.new('normalize_opts expects a string or a hash')
139
172
  end
140
173
  end
174
+
175
+ def self.check_string_argument!(key)
176
+ raise TypeError.new("argument must be a string") unless key.is_a?(String)
177
+ key
178
+ end
179
+
180
+ def self.check_api_key!(key)
181
+ raise TypeError.new("api_key must be a string") unless key.is_a?(String)
182
+ key
183
+ end
141
184
  end
142
185
  end
@@ -1,3 +1,3 @@
1
1
  module Stripe
2
- VERSION = '1.18.0'
2
+ VERSION = '1.30.0'
3
3
  end