stripe 3.3.2 → 3.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +20 -0
  4. data/.rubocop_todo.yml +62 -0
  5. data/.travis.yml +1 -1
  6. data/Gemfile +19 -12
  7. data/History.txt +10 -0
  8. data/README.md +5 -1
  9. data/Rakefile +8 -5
  10. data/VERSION +1 -1
  11. data/bin/stripe-console +2 -2
  12. data/lib/stripe.rb +72 -74
  13. data/lib/stripe/account.rb +15 -17
  14. data/lib/stripe/alipay_account.rb +10 -7
  15. data/lib/stripe/api_operations/create.rb +1 -1
  16. data/lib/stripe/api_operations/delete.rb +1 -1
  17. data/lib/stripe/api_operations/list.rb +2 -2
  18. data/lib/stripe/api_operations/request.rb +5 -12
  19. data/lib/stripe/api_operations/save.rb +6 -6
  20. data/lib/stripe/api_resource.rb +7 -9
  21. data/lib/stripe/apple_pay_domain.rb +2 -2
  22. data/lib/stripe/application_fee.rb +5 -5
  23. data/lib/stripe/application_fee_refund.rb +5 -5
  24. data/lib/stripe/balance.rb +1 -1
  25. data/lib/stripe/balance_transaction.rb +2 -2
  26. data/lib/stripe/bank_account.rb +7 -7
  27. data/lib/stripe/bitcoin_receiver.rb +4 -2
  28. data/lib/stripe/bitcoin_transaction.rb +3 -1
  29. data/lib/stripe/card.rb +5 -5
  30. data/lib/stripe/charge.rb +18 -18
  31. data/lib/stripe/country_spec.rb +2 -2
  32. data/lib/stripe/coupon.rb +1 -1
  33. data/lib/stripe/customer.rb +23 -23
  34. data/lib/stripe/dispute.rb +3 -3
  35. data/lib/stripe/ephemeral_key.rb +4 -4
  36. data/lib/stripe/errors.rb +4 -4
  37. data/lib/stripe/event.rb +1 -1
  38. data/lib/stripe/file_upload.rb +5 -5
  39. data/lib/stripe/invoice.rb +7 -7
  40. data/lib/stripe/invoice_item.rb +1 -1
  41. data/lib/stripe/invoice_line_item.rb +1 -1
  42. data/lib/stripe/list_object.rb +14 -18
  43. data/lib/stripe/login_link.rb +3 -3
  44. data/lib/stripe/oauth.rb +15 -13
  45. data/lib/stripe/order.rb +5 -5
  46. data/lib/stripe/order_return.rb +1 -1
  47. data/lib/stripe/payout.rb +3 -3
  48. data/lib/stripe/plan.rb +1 -1
  49. data/lib/stripe/product.rb +1 -1
  50. data/lib/stripe/recipient.rb +3 -2
  51. data/lib/stripe/recipient_transfer.rb +1 -2
  52. data/lib/stripe/refund.rb +1 -1
  53. data/lib/stripe/reversal.rb +5 -5
  54. data/lib/stripe/singleton_api_resource.rb +3 -3
  55. data/lib/stripe/sku.rb +1 -1
  56. data/lib/stripe/source.rb +13 -10
  57. data/lib/stripe/stripe_client.rb +149 -169
  58. data/lib/stripe/stripe_object.rb +77 -76
  59. data/lib/stripe/subscription.rb +5 -5
  60. data/lib/stripe/subscription_item.rb +2 -2
  61. data/lib/stripe/three_d_secure.rb +1 -1
  62. data/lib/stripe/token.rb +1 -1
  63. data/lib/stripe/transfer.rb +3 -3
  64. data/lib/stripe/util.rb +77 -62
  65. data/lib/stripe/version.rb +1 -1
  66. data/lib/stripe/webhook.rb +14 -10
  67. data/stripe.gemspec +14 -14
  68. data/test/stripe/account_test.rb +69 -81
  69. data/test/stripe/alipay_account_test.rb +19 -1
  70. data/test/stripe/api_operations_test.rb +7 -7
  71. data/test/stripe/api_resource_test.rb +224 -260
  72. data/test/stripe/apple_pay_domain_test.rb +8 -8
  73. data/test/stripe/application_fee_refund_test.rb +8 -8
  74. data/test/stripe/application_fee_test.rb +3 -3
  75. data/test/stripe/balance_test.rb +2 -2
  76. data/test/stripe/bank_account_test.rb +9 -11
  77. data/test/stripe/charge_test.rb +11 -11
  78. data/test/stripe/country_spec_test.rb +4 -4
  79. data/test/stripe/coupon_test.rb +10 -10
  80. data/test/stripe/customer_card_test.rb +11 -15
  81. data/test/stripe/customer_test.rb +26 -27
  82. data/test/stripe/dispute_test.rb +8 -8
  83. data/test/stripe/ephemeral_key_test.rb +14 -14
  84. data/test/stripe/errors_test.rb +2 -2
  85. data/test/stripe/file_upload_test.rb +26 -28
  86. data/test/stripe/invoice_item_test.rb +14 -14
  87. data/test/stripe/invoice_line_item_test.rb +1 -1
  88. data/test/stripe/invoice_test.rb +37 -37
  89. data/test/stripe/list_object_test.rb +60 -76
  90. data/test/stripe/login_link_test.rb +14 -14
  91. data/test/stripe/oauth_test.rb +42 -50
  92. data/test/stripe/order_return_test.rb +5 -5
  93. data/test/stripe/order_test.rb +12 -12
  94. data/test/stripe/payout_test.rb +9 -9
  95. data/test/stripe/plan_test.rb +9 -9
  96. data/test/stripe/product_test.rb +8 -8
  97. data/test/stripe/recipient_test.rb +9 -10
  98. data/test/stripe/refund_test.rb +9 -9
  99. data/test/stripe/reversal_test.rb +10 -10
  100. data/test/stripe/sku_test.rb +8 -8
  101. data/test/stripe/source_test.rb +14 -16
  102. data/test/stripe/stripe_client_test.rb +235 -266
  103. data/test/stripe/stripe_object_test.rb +163 -147
  104. data/test/stripe/stripe_response_test.rb +4 -3
  105. data/test/stripe/subscription_item_test.rb +11 -11
  106. data/test/stripe/subscription_test.rb +14 -14
  107. data/test/stripe/three_d_secure_test.rb +2 -2
  108. data/test/stripe/transfer_test.rb +8 -8
  109. data/test/stripe/util_test.rb +59 -57
  110. data/test/stripe/webhook_test.rb +18 -16
  111. data/test/stripe_test.rb +4 -4
  112. data/test/test_data.rb +26 -26
  113. data/test/test_helper.rb +29 -25
  114. metadata +6 -10
  115. data/test/stripe/bitcoin_receiver_test.rb +0 -67
  116. data/test/stripe/bitcoin_transaction_test.rb +0 -19
  117. data/test/stripe/recipient_card_test.rb +0 -44
data/lib/stripe/order.rb CHANGED
@@ -4,14 +4,14 @@ module Stripe
4
4
  extend Stripe::APIOperations::Create
5
5
  include Stripe::APIOperations::Save
6
6
 
7
- OBJECT_NAME = 'order'
7
+ OBJECT_NAME = "order".freeze
8
8
 
9
- def pay(params, opts={})
9
+ def pay(params, opts = {})
10
10
  resp, opts = request(:post, pay_url, params, opts)
11
11
  initialize_from(resp.data, opts)
12
12
  end
13
13
 
14
- def return_order(params, opts={})
14
+ def return_order(params, opts = {})
15
15
  resp, opts = request(:post, returns_url, params, opts)
16
16
  Util.convert_to_stripe_object(resp.data, opts)
17
17
  end
@@ -19,11 +19,11 @@ module Stripe
19
19
  private
20
20
 
21
21
  def pay_url
22
- resource_url + '/pay'
22
+ resource_url + "/pay"
23
23
  end
24
24
 
25
25
  def returns_url
26
- resource_url + '/returns'
26
+ resource_url + "/returns"
27
27
  end
28
28
  end
29
29
  end
@@ -2,7 +2,7 @@ module Stripe
2
2
  class OrderReturn < APIResource
3
3
  extend Stripe::APIOperations::List
4
4
 
5
- OBJECT_NAME = 'order_return'
5
+ OBJECT_NAME = "order_return".freeze
6
6
 
7
7
  def self.resource_url
8
8
  "/v1/order_returns"
data/lib/stripe/payout.rb CHANGED
@@ -4,15 +4,15 @@ module Stripe
4
4
  extend Stripe::APIOperations::Create
5
5
  include Stripe::APIOperations::Save
6
6
 
7
- OBJECT_NAME = 'payout'
7
+ OBJECT_NAME = "payout".freeze
8
8
 
9
9
  def cancel
10
- resp, api_key = self.request(:post, cancel_url)
10
+ resp, api_key = request(:post, cancel_url)
11
11
  initialize_from(resp.data, api_key)
12
12
  end
13
13
 
14
14
  def cancel_url
15
- resource_url + '/cancel'
15
+ resource_url + "/cancel"
16
16
  end
17
17
  end
18
18
  end
data/lib/stripe/plan.rb CHANGED
@@ -5,6 +5,6 @@ module Stripe
5
5
  extend Stripe::APIOperations::List
6
6
  include Stripe::APIOperations::Save
7
7
 
8
- OBJECT_NAME = 'plan'
8
+ OBJECT_NAME = "plan".freeze
9
9
  end
10
10
  end
@@ -5,6 +5,6 @@ module Stripe
5
5
  include Stripe::APIOperations::Save
6
6
  include Stripe::APIOperations::Delete
7
7
 
8
- OBJECT_NAME = 'product'
8
+ OBJECT_NAME = "product".freeze
9
9
  end
10
10
  end
@@ -1,14 +1,15 @@
1
1
  module Stripe
2
+ # Recipients objects are deprecated. Please use Stripe Connect instead.
2
3
  class Recipient < APIResource
3
4
  extend Stripe::APIOperations::Create
4
5
  include Stripe::APIOperations::Delete
5
6
  include Stripe::APIOperations::Save
6
7
  extend Stripe::APIOperations::List
7
8
 
8
- OBJECT_NAME = 'recipient'
9
+ OBJECT_NAME = "recipient".freeze
9
10
 
10
11
  def transfers
11
- Transfer.all({ :recipient => id }, @api_key)
12
+ Transfer.all({ recipient: id }, @api_key)
12
13
  end
13
14
  end
14
15
  end
@@ -1,6 +1,5 @@
1
1
  module Stripe
2
2
  class RecipientTransfer < StripeObject
3
-
4
- OBJECT_NAME = 'recipient_transfer'
3
+ OBJECT_NAME = "recipient_transfer".freeze
5
4
  end
6
5
  end
data/lib/stripe/refund.rb CHANGED
@@ -4,6 +4,6 @@ module Stripe
4
4
  extend Stripe::APIOperations::List
5
5
  include Stripe::APIOperations::Save
6
6
 
7
- OBJECT_NAME = 'refund'
7
+ OBJECT_NAME = "refund".freeze
8
8
  end
9
9
  end
@@ -3,18 +3,18 @@ module Stripe
3
3
  extend Stripe::APIOperations::List
4
4
  include Stripe::APIOperations::Save
5
5
 
6
- OBJECT_NAME = 'transfer_reversal'
6
+ OBJECT_NAME = "transfer_reversal".freeze
7
7
 
8
8
  def resource_url
9
9
  "#{Transfer.resource_url}/#{CGI.escape(transfer)}/reversals/#{CGI.escape(id)}"
10
10
  end
11
11
 
12
- def self.update(id, params=nil, opts=nil)
13
- raise NotImplementedError.new("Reversals cannot be updated without a transfer ID. Update a reversal using `r = transfer.reversals.retrieve('reversal_id'); r.save`")
12
+ def self.update(_id, _params = nil, _opts = nil)
13
+ raise NotImplementedError, "Reversals cannot be updated without a transfer ID. Update a reversal using `r = transfer.reversals.retrieve('reversal_id'); r.save`"
14
14
  end
15
15
 
16
- def self.retrieve(id, opts={})
17
- raise NotImplementedError.new("Reversals cannot be retrieved without a transfer ID. Retrieve a reversal using transfer.reversals.retrieve('reversal_id')")
16
+ def self.retrieve(_id, _opts = {})
17
+ raise NotImplementedError, "Reversals cannot be retrieved without a transfer ID. Retrieve a reversal using transfer.reversals.retrieve('reversal_id')"
18
18
  end
19
19
  end
20
20
  end
@@ -2,7 +2,7 @@ module Stripe
2
2
  class SingletonAPIResource < APIResource
3
3
  def self.resource_url
4
4
  if self == SingletonAPIResource
5
- raise NotImplementedError.new('SingletonAPIResource is an abstract class. You should perform actions on its subclasses (Account, etc.)')
5
+ raise NotImplementedError, "SingletonAPIResource is an abstract class. You should perform actions on its subclasses (Account, etc.)"
6
6
  end
7
7
  "/v1/#{CGI.escape(class_name.downcase)}"
8
8
  end
@@ -11,8 +11,8 @@ module Stripe
11
11
  self.class.resource_url
12
12
  end
13
13
 
14
- def self.retrieve(opts={})
15
- instance = self.new(nil, Util.normalize_opts(opts))
14
+ def self.retrieve(opts = {})
15
+ instance = new(nil, Util.normalize_opts(opts))
16
16
  instance.refresh
17
17
  instance
18
18
  end
data/lib/stripe/sku.rb CHANGED
@@ -5,6 +5,6 @@ module Stripe
5
5
  include Stripe::APIOperations::Save
6
6
  include Stripe::APIOperations::Delete
7
7
 
8
- OBJECT_NAME = 'sku'
8
+ OBJECT_NAME = "sku".freeze
9
9
  end
10
10
  end
data/lib/stripe/source.rb CHANGED
@@ -3,20 +3,23 @@ module Stripe
3
3
  extend Stripe::APIOperations::Create
4
4
  include Stripe::APIOperations::Save
5
5
 
6
- OBJECT_NAME = 'source'
6
+ OBJECT_NAME = "source".freeze
7
7
 
8
- def delete(params={}, opts={})
9
- if respond_to?(:customer) && !customer.nil? && !customer.empty?
10
- url = "#{Customer.resource_url}/#{CGI.escape(customer)}/sources/#{CGI.escape(id)}"
11
- resp, opts = request(:delete, url, params, Util.normalize_opts(opts))
12
- initialize_from(resp.data, opts)
13
- else
14
- raise NotImplementedError.new("Source objects cannot be deleted, they can only be detached from customer objects. This source object does not appear to be currently attached to a customer object.")
8
+ def delete(params = {}, opts = {})
9
+ if !respond_to?(:customer) || customer.nil? || customer.empty?
10
+ raise NotImplementedError,
11
+ "Source objects cannot be deleted, they can only be detached " \
12
+ "from customer objects. This source object does not appear to " \
13
+ "be currently attached to a customer object."
15
14
  end
15
+
16
+ url = "#{Customer.resource_url}/#{CGI.escape(customer)}/sources/#{CGI.escape(id)}"
17
+ resp, opts = request(:delete, url, params, Util.normalize_opts(opts))
18
+ initialize_from(resp.data, opts)
16
19
  end
17
20
 
18
- def verify(params={}, opts={})
19
- resp, opts = request(:post, resource_url + '/verify', params, Util.normalize_opts(opts))
21
+ def verify(params = {}, opts = {})
22
+ resp, opts = request(:post, resource_url + "/verify", params, Util.normalize_opts(opts))
20
23
  initialize_from(resp.data, opts)
21
24
  end
22
25
  end
@@ -79,11 +79,11 @@ module Stripe
79
79
  # Apply exponential backoff with initial_network_retry_delay on the
80
80
  # number of num_retries so far as inputs. Do not allow the number to exceed
81
81
  # max_network_retry_delay.
82
- sleep_seconds = [Stripe.initial_network_retry_delay * (2 ** (num_retries - 1)), Stripe.max_network_retry_delay].min
82
+ sleep_seconds = [Stripe.initial_network_retry_delay * (2**(num_retries - 1)), Stripe.max_network_retry_delay].min
83
83
 
84
84
  # Apply some jitter by randomizing the value in the range of (sleep_seconds
85
85
  # / 2) to (sleep_seconds).
86
- sleep_seconds = sleep_seconds * (0.5 * (1 + rand()))
86
+ sleep_seconds *= (0.5 * (1 + rand))
87
87
 
88
88
  # But never sleep less than the base sleep seconds.
89
89
  sleep_seconds = [Stripe.initial_network_retry_delay, sleep_seconds].max
@@ -96,13 +96,13 @@ module Stripe
96
96
  # client = StripeClient.new
97
97
  # charge, resp = client.request { Charge.create }
98
98
  #
99
- def request(&block)
99
+ def request
100
100
  @last_response = nil
101
101
  old_stripe_client = Thread.current[:stripe_client]
102
102
  Thread.current[:stripe_client] = self
103
103
 
104
104
  begin
105
- res = block.call
105
+ res = yield
106
106
  [res, @last_response]
107
107
  ensure
108
108
  Thread.current[:stripe_client] = old_stripe_client
@@ -110,7 +110,7 @@ module Stripe
110
110
  end
111
111
 
112
112
  def execute_request(method, path,
113
- api_base: nil, api_key: nil, headers: {}, params: {})
113
+ api_base: nil, api_key: nil, headers: {}, params: {})
114
114
 
115
115
  api_base ||= Stripe.api_base
116
116
  api_key ||= Stripe.api_key
@@ -120,36 +120,38 @@ module Stripe
120
120
  params = Util.objects_to_ids(params)
121
121
  url = api_url(path, api_base)
122
122
 
123
+ body = nil
124
+ query_string = nil
125
+
123
126
  case method.to_s.downcase.to_sym
124
127
  when :get, :head, :delete
125
- # Make params into GET parameters
126
- url += "#{URI.parse(url).query ? '&' : '?'}#{Util.encode_parameters(params)}" if params && params.any?
127
- payload = nil
128
+ query_string = Util.encode_parameters(params) if params && params.any?
129
+ url += "#{URI.parse(url).query ? '&' : '?'}#{query_string}" unless query_string.nil?
128
130
  else
129
- if headers[:content_type] && headers[:content_type] == "multipart/form-data"
130
- payload = params
131
- else
132
- payload = Util.encode_parameters(params)
133
- end
131
+ body = if headers[:content_type] && headers[:content_type] == "multipart/form-data"
132
+ params
133
+ else
134
+ Util.encode_parameters(params)
135
+ end
134
136
  end
135
137
 
136
- headers = request_headers(api_key, method).
137
- update(Util.normalize_headers(headers))
138
+ headers = request_headers(api_key, method)
139
+ .update(Util.normalize_headers(headers))
138
140
 
139
141
  # stores information on the request we're about to make so that we don't
140
142
  # have to pass as many parameters around for logging.
141
- context = RequestLogContext.new(
142
- account: headers["Stripe-Account"],
143
- api_key: api_key,
144
- api_version: headers["Stripe-Version"],
145
- idempotency_key: headers["Idempotency-Key"],
146
- method: method,
147
- path: path,
148
- payload: payload,
149
- )
143
+ context = RequestLogContext.new
144
+ context.account = headers["Stripe-Account"]
145
+ context.api_key = api_key
146
+ context.api_version = headers["Stripe-Version"]
147
+ context.body = body
148
+ context.idempotency_key = headers["Idempotency-Key"]
149
+ context.method = method
150
+ context.path = path
151
+ context.query_string = query_string
150
152
 
151
153
  http_resp = execute_request_with_rescues(api_base, context) do
152
- conn.run_request(method, url, payload, headers) do |req|
154
+ conn.run_request(method, url, body, headers) do |req|
153
155
  req.options.open_timeout = Stripe.open_timeout
154
156
  req.options.timeout = Stripe.read_timeout
155
157
  end
@@ -168,40 +170,40 @@ module Stripe
168
170
 
169
171
  private
170
172
 
171
- def api_url(url='', api_base=nil)
173
+ def api_url(url = "", api_base = nil)
172
174
  (api_base || Stripe.api_base) + url
173
175
  end
174
176
 
175
177
  def check_api_key!(api_key)
176
178
  unless api_key
177
- raise AuthenticationError.new('No API key provided. ' \
179
+ raise AuthenticationError, "No API key provided. " \
178
180
  'Set your API key using "Stripe.api_key = <API-KEY>". ' \
179
- 'You can generate API keys from the Stripe web interface. ' \
180
- 'See https://stripe.com/api for details, or email support@stripe.com ' \
181
- 'if you have any questions.')
181
+ "You can generate API keys from the Stripe web interface. " \
182
+ "See https://stripe.com/api for details, or email support@stripe.com " \
183
+ "if you have any questions."
182
184
  end
183
185
 
184
- if api_key =~ /\s/
185
- raise AuthenticationError.new('Your API key is invalid, as it contains ' \
186
- 'whitespace. (HINT: You can double-check your API key from the ' \
187
- 'Stripe web interface. See https://stripe.com/api for details, or ' \
188
- 'email support@stripe.com if you have any questions.)')
189
- end
186
+ return unless api_key =~ /\s/
187
+
188
+ raise AuthenticationError, "Your API key is invalid, as it contains " \
189
+ "whitespace. (HINT: You can double-check your API key from the " \
190
+ "Stripe web interface. See https://stripe.com/api for details, or " \
191
+ "email support@stripe.com if you have any questions.)"
190
192
  end
191
193
 
192
- def execute_request_with_rescues(api_base, context, &block)
194
+ def execute_request_with_rescues(api_base, context)
193
195
  num_retries = 0
194
196
  begin
195
197
  request_start = Time.now
196
198
  log_request(context, num_retries)
197
- resp = block.call
199
+ resp = yield
198
200
  context = context.dup_from_response(resp)
199
201
  log_response(context, request_start, resp.status, resp.body)
200
202
 
201
203
  # We rescue all exceptions from a request so that we have an easy spot to
202
204
  # implement our retry logic across the board. We'll re-raise if it's a type
203
205
  # of exception that we didn't expect to handle.
204
- rescue => e
206
+ rescue StandardError => e
205
207
  # If we modify context we copy it into a new variable so as not to
206
208
  # taint the original on a retry.
207
209
  error_context = context
@@ -209,7 +211,7 @@ module Stripe
209
211
  if e.respond_to?(:response) && e.response
210
212
  error_context = context.dup_from_response(e.response)
211
213
  log_response(error_context, request_start,
212
- e.response[:status], e.response[:body])
214
+ e.response[:status], e.response[:body])
213
215
  else
214
216
  log_response_error(error_context, request_start, e)
215
217
  end
@@ -239,7 +241,7 @@ module Stripe
239
241
  end
240
242
 
241
243
  def general_api_error(status, body)
242
- APIError.new("Invalid response object from API: #{body.inspect} " +
244
+ APIError.new("Invalid response object from API: #{body.inspect} " \
243
245
  "(HTTP response code was #{status})",
244
246
  http_status: status, http_body: body)
245
247
  end
@@ -260,34 +262,30 @@ module Stripe
260
262
  resp = StripeResponse.from_faraday_hash(http_resp)
261
263
  error_data = resp.data[:error]
262
264
 
263
- unless error_data
264
- raise StripeError.new("Indeterminate error")
265
- end
266
-
265
+ raise StripeError, "Indeterminate error" unless error_data
267
266
  rescue JSON::ParserError, StripeError
268
267
  raise general_api_error(http_resp[:status], http_resp[:body])
269
268
  end
270
269
 
271
- if error_data.is_a?(String)
272
- error = specific_oauth_error(resp, error_data, context)
273
- else
274
- error = specific_api_error(resp, error_data, context)
275
- end
270
+ error = if error_data.is_a?(String)
271
+ specific_oauth_error(resp, error_data, context)
272
+ else
273
+ specific_api_error(resp, error_data, context)
274
+ end
276
275
 
277
276
  error.response = resp
278
277
  raise(error)
279
278
  end
280
279
 
281
280
  def specific_api_error(resp, error_data, context)
282
- Util.log_error('Stripe API error',
283
- status: resp.http_status,
284
- error_code: error_data['code'],
285
- error_message: error_data['message'],
286
- error_param: error_data['param'],
287
- error_type: error_data['type'],
288
- idempotency_key: context.idempotency_key,
289
- request_id: context.request_id
290
- )
281
+ Util.log_error("Stripe API error",
282
+ status: resp.http_status,
283
+ error_code: error_data["code"],
284
+ error_message: error_data["message"],
285
+ error_param: error_data["param"],
286
+ error_type: error_data["type"],
287
+ idempotency_key: context.idempotency_key,
288
+ request_id: context.request_id)
291
289
 
292
290
  case resp.http_status
293
291
  when 400, 404
@@ -336,26 +334,25 @@ module Stripe
336
334
  def specific_oauth_error(resp, error_code, context)
337
335
  description = resp.data[:error_description] || error_code
338
336
 
339
- Util.log_error('Stripe OAuth error',
340
- status: resp.http_status,
341
- error_code: error_code,
342
- error_description: description,
343
- idempotency_key: context.idempotency_key,
344
- request_id: context.request_id
345
- )
337
+ Util.log_error("Stripe OAuth error",
338
+ status: resp.http_status,
339
+ error_code: error_code,
340
+ error_description: description,
341
+ idempotency_key: context.idempotency_key,
342
+ request_id: context.request_id)
346
343
 
347
344
  args = [error_code, description, {
348
345
  http_status: resp.http_status, http_body: resp.http_body,
349
- json_body: resp.data, http_headers: resp.http_headers
350
- }]
346
+ json_body: resp.data, http_headers: resp.http_headers,
347
+ },]
351
348
 
352
349
  case error_code
353
- when 'invalid_client' then OAuth::InvalidClientError.new(*args)
354
- when 'invalid_grant' then OAuth::InvalidGrantError.new(*args)
355
- when 'invalid_request' then OAuth::InvalidRequestError.new(*args)
356
- when 'invalid_scope' then OAuth::InvalidScopeError.new(*args)
357
- when 'unsupported_grant_type' then OAuth::UnsupportedGrantTypeError.new(*args)
358
- when 'unsupported_response_type' then OAuth::UnsupportedResponseTypeError.new(*args)
350
+ when "invalid_client" then OAuth::InvalidClientError.new(*args)
351
+ when "invalid_grant" then OAuth::InvalidGrantError.new(*args)
352
+ when "invalid_request" then OAuth::InvalidRequestError.new(*args)
353
+ when "invalid_scope" then OAuth::InvalidScopeError.new(*args)
354
+ when "unsupported_grant_type" then OAuth::UnsupportedGrantTypeError.new(*args)
355
+ when "unsupported_response_type" then OAuth::UnsupportedResponseTypeError.new(*args)
359
356
  else
360
357
  # We'd prefer that all errors are typed, but we create a generic
361
358
  # OAuthError in case we run into a code that we don't recognize.
@@ -363,12 +360,11 @@ module Stripe
363
360
  end
364
361
  end
365
362
 
366
- def handle_network_error(e, context, num_retries, api_base=nil)
367
- Util.log_error('Stripe network error',
368
- error_message: e.message,
369
- idempotency_key: context.idempotency_key,
370
- request_id: context.request_id
371
- )
363
+ def handle_network_error(e, context, num_retries, api_base = nil)
364
+ Util.log_error("Stripe network error",
365
+ error_message: e.message,
366
+ idempotency_key: context.idempotency_key,
367
+ request_id: context.request_id)
372
368
 
373
369
  case e
374
370
  when Faraday::ConnectionFailed
@@ -383,7 +379,7 @@ module Stripe
383
379
  "command line."
384
380
 
385
381
  when Faraday::TimeoutError
386
- api_base = Stripe.api_base unless api_base
382
+ api_base ||= Stripe.api_base
387
383
  message = "Could not connect to Stripe (#{api_base}). " \
388
384
  "Please check your internet connection and try again. " \
389
385
  "If this problem persists, you should check Stripe's service status at " \
@@ -395,11 +391,9 @@ module Stripe
395
391
 
396
392
  end
397
393
 
398
- if num_retries > 0
399
- message += " Request was retried #{num_retries} times."
400
- end
394
+ message += " Request was retried #{num_retries} times." if num_retries > 0
401
395
 
402
- raise APIConnectionError.new(message + "\n\n(Network error: #{e.message})")
396
+ raise APIConnectionError, message + "\n\n(Network error: #{e.message})"
403
397
  end
404
398
 
405
399
  def request_headers(api_key, method)
@@ -409,28 +403,28 @@ module Stripe
409
403
  end
410
404
 
411
405
  headers = {
412
- 'User-Agent' => user_agent,
413
- 'Authorization' => "Bearer #{api_key}",
414
- 'Content-Type' => 'application/x-www-form-urlencoded'
406
+ "User-Agent" => user_agent,
407
+ "Authorization" => "Bearer #{api_key}",
408
+ "Content-Type" => "application/x-www-form-urlencoded",
415
409
  }
416
410
 
417
411
  # It is only safe to retry network failures on post and delete
418
412
  # requests if we add an Idempotency-Key header
419
- if [:post, :delete].include?(method) && Stripe.max_network_retries > 0
420
- headers['Idempotency-Key'] ||= SecureRandom.uuid
413
+ if %i[post delete].include?(method) && Stripe.max_network_retries > 0
414
+ headers["Idempotency-Key"] ||= SecureRandom.uuid
421
415
  end
422
416
 
423
- headers['Stripe-Version'] = Stripe.api_version if Stripe.api_version
424
- headers['Stripe-Account'] = Stripe.stripe_account if Stripe.stripe_account
417
+ headers["Stripe-Version"] = Stripe.api_version if Stripe.api_version
418
+ headers["Stripe-Account"] = Stripe.stripe_account if Stripe.stripe_account
425
419
 
426
420
  user_agent = @system_profiler.user_agent
427
421
  begin
428
422
  headers.update(
429
- 'X-Stripe-Client-User-Agent' => JSON.generate(user_agent)
423
+ "X-Stripe-Client-User-Agent" => JSON.generate(user_agent)
430
424
  )
431
- rescue => e
425
+ rescue StandardError => e
432
426
  headers.update(
433
- 'X-Stripe-Client-Raw-User-Agent' => user_agent.inspect,
427
+ "X-Stripe-Client-Raw-User-Agent" => user_agent.inspect,
434
428
  :error => "#{e} (#{e.class})"
435
429
  )
436
430
  end
@@ -440,54 +434,50 @@ module Stripe
440
434
 
441
435
  def log_request(context, num_retries)
442
436
  Util.log_info("Request to Stripe API",
443
- account: context.account,
444
- api_version: context.api_version,
445
- idempotency_key: context.idempotency_key,
446
- method: context.method,
447
- num_retries: num_retries,
448
- path: context.path
449
- )
437
+ account: context.account,
438
+ api_version: context.api_version,
439
+ idempotency_key: context.idempotency_key,
440
+ method: context.method,
441
+ num_retries: num_retries,
442
+ path: context.path)
450
443
  Util.log_debug("Request details",
451
- body: context.payload,
452
- idempotency_key: context.idempotency_key
453
- )
444
+ body: context.body,
445
+ idempotency_key: context.idempotency_key,
446
+ query_string: context.query_string)
454
447
  end
455
448
  private :log_request
456
449
 
457
450
  def log_response(context, request_start, status, body)
458
451
  Util.log_info("Response from Stripe API",
459
- account: context.account,
460
- api_version: context.api_version,
461
- elapsed: Time.now - request_start,
462
- idempotency_key: context.idempotency_key,
463
- method: context.method,
464
- path: context.path,
465
- request_id: context.request_id,
466
- status: status
467
- )
452
+ account: context.account,
453
+ api_version: context.api_version,
454
+ elapsed: Time.now - request_start,
455
+ idempotency_key: context.idempotency_key,
456
+ method: context.method,
457
+ path: context.path,
458
+ request_id: context.request_id,
459
+ status: status)
468
460
  Util.log_debug("Response details",
469
- body: body,
470
- idempotency_key: context.idempotency_key,
471
- request_id: context.request_id,
472
- )
473
- if context.request_id
474
- Util.log_debug("Dashboard link for request",
475
- idempotency_key: context.idempotency_key,
476
- request_id: context.request_id,
477
- url: Util.request_id_dashboard_url(context.request_id, context.api_key)
478
- )
479
- end
461
+ body: body,
462
+ idempotency_key: context.idempotency_key,
463
+ request_id: context.request_id)
464
+
465
+ return unless context.request_id
466
+
467
+ Util.log_debug("Dashboard link for request",
468
+ idempotency_key: context.idempotency_key,
469
+ request_id: context.request_id,
470
+ url: Util.request_id_dashboard_url(context.request_id, context.api_key))
480
471
  end
481
472
  private :log_response
482
473
 
483
474
  def log_response_error(context, request_start, e)
484
475
  Util.log_error("Request error",
485
- elapsed: Time.now - request_start,
486
- error_message: e.message,
487
- idempotency_key: context.idempotency_key,
488
- method: context.method,
489
- path: context.path,
490
- )
476
+ elapsed: Time.now - request_start,
477
+ error_message: e.message,
478
+ idempotency_key: context.idempotency_key,
479
+ method: context.method,
480
+ path: context.path)
491
481
  end
492
482
  private :log_response_error
493
483
 
@@ -495,26 +485,16 @@ module Stripe
495
485
  # that we can log certain information. It's useful because it means that we
496
486
  # don't have to pass around as many parameters.
497
487
  class RequestLogContext
488
+ attr_accessor :body
498
489
  attr_accessor :account
499
490
  attr_accessor :api_key
500
491
  attr_accessor :api_version
501
492
  attr_accessor :idempotency_key
502
493
  attr_accessor :method
503
494
  attr_accessor :path
504
- attr_accessor :payload
495
+ attr_accessor :query_string
505
496
  attr_accessor :request_id
506
497
 
507
- def initialize(account: nil, api_key: nil, api_version: nil,
508
- idempotency_key: nil, method: nil, path: nil, payload: nil)
509
- self.account = account
510
- self.api_key = api_key
511
- self.api_version = api_version
512
- self.idempotency_key = idempotency_key
513
- self.method = method
514
- self.path = path
515
- self.payload = payload
516
- end
517
-
518
498
  # The idea with this method is that we might want to update some of
519
499
  # context information because a response that we've received from the API
520
500
  # contains information that's more authoritative than what we started
@@ -528,12 +508,12 @@ module Stripe
528
508
  # object with a `headers` method, but on error what it puts into
529
509
  # `e.response` is an untyped `Hash`.
530
510
  headers = if resp.is_a?(Faraday::Response)
531
- resp.headers
532
- else
533
- resp[:headers]
534
- end
511
+ resp.headers
512
+ else
513
+ resp[:headers]
514
+ end
535
515
 
536
- context = self.dup
516
+ context = dup
537
517
  context.account = headers["Stripe-Account"]
538
518
  context.api_version = headers["Stripe-Version"]
539
519
  context.idempotency_key = headers["Idempotency-Key"]
@@ -546,31 +526,31 @@ module Stripe
546
526
  # in so that we can generate a rich user agent header to help debug
547
527
  # integrations.
548
528
  class SystemProfiler
549
- def self.get_uname
550
- if File.exist?('/proc/version')
551
- File.read('/proc/version').strip
529
+ def self.uname
530
+ if File.exist?("/proc/version")
531
+ File.read("/proc/version").strip
552
532
  else
553
- case RbConfig::CONFIG['host_os']
533
+ case RbConfig::CONFIG["host_os"]
554
534
  when /linux|darwin|bsd|sunos|solaris|cygwin/i
555
- get_uname_from_system
535
+ uname_from_system
556
536
  when /mswin|mingw/i
557
- get_uname_from_system_ver
537
+ uname_from_system_ver
558
538
  else
559
539
  "unknown platform"
560
540
  end
561
541
  end
562
542
  end
563
543
 
564
- def self.get_uname_from_system
565
- (`uname -a 2>/dev/null` || '').strip
544
+ def self.uname_from_system
545
+ (`uname -a 2>/dev/null` || "").strip
566
546
  rescue Errno::ENOENT
567
547
  "uname executable not found"
568
548
  rescue Errno::ENOMEM # couldn't create subprocess
569
549
  "uname lookup failed"
570
550
  end
571
551
 
572
- def self.get_uname_from_system_ver
573
- (`ver` || '').strip
552
+ def self.uname_from_system_ver
553
+ (`ver` || "").strip
574
554
  rescue Errno::ENOENT
575
555
  "ver executable not found"
576
556
  rescue Errno::ENOMEM # couldn't create subprocess
@@ -578,23 +558,23 @@ module Stripe
578
558
  end
579
559
 
580
560
  def initialize
581
- @uname = self.class.get_uname
561
+ @uname = self.class.uname
582
562
  end
583
563
 
584
564
  def user_agent
585
565
  lang_version = "#{RUBY_VERSION} p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE})"
586
566
 
587
567
  {
588
- :application => Stripe.app_info,
589
- :bindings_version => Stripe::VERSION,
590
- :lang => 'ruby',
591
- :lang_version => lang_version,
592
- :platform => RUBY_PLATFORM,
593
- :engine => defined?(RUBY_ENGINE) ? RUBY_ENGINE : '',
594
- :publisher => 'stripe',
595
- :uname => @uname,
596
- :hostname => Socket.gethostname,
597
- }.delete_if { |k, v| v.nil? }
568
+ application: Stripe.app_info,
569
+ bindings_version: Stripe::VERSION,
570
+ lang: "ruby",
571
+ lang_version: lang_version,
572
+ platform: RUBY_PLATFORM,
573
+ engine: defined?(RUBY_ENGINE) ? RUBY_ENGINE : "",
574
+ publisher: "stripe",
575
+ uname: @uname,
576
+ hostname: Socket.gethostname,
577
+ }.delete_if { |_k, v| v.nil? }
598
578
  end
599
579
  end
600
580
  end