stripe 3.3.2 → 3.4.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 (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