stripe 1.58.0 → 2.0.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 (84) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +4 -0
  3. data/.travis.yml +1 -2
  4. data/Gemfile +11 -12
  5. data/History.txt +8 -0
  6. data/README.md +44 -31
  7. data/Rakefile +1 -1
  8. data/VERSION +1 -1
  9. data/lib/stripe.rb +4 -344
  10. data/lib/stripe/account.rb +4 -4
  11. data/lib/stripe/api_operations/create.rb +2 -2
  12. data/lib/stripe/api_operations/delete.rb +2 -2
  13. data/lib/stripe/api_operations/list.rb +2 -2
  14. data/lib/stripe/api_operations/request.rb +9 -3
  15. data/lib/stripe/api_operations/save.rb +4 -6
  16. data/lib/stripe/api_resource.rb +2 -2
  17. data/lib/stripe/bank_account.rb +2 -2
  18. data/lib/stripe/bitcoin_receiver.rb +1 -1
  19. data/lib/stripe/charge.rb +12 -12
  20. data/lib/stripe/customer.rb +6 -6
  21. data/lib/stripe/dispute.rb +2 -3
  22. data/lib/stripe/errors.rb +20 -10
  23. data/lib/stripe/invoice.rb +4 -4
  24. data/lib/stripe/list_object.rb +2 -2
  25. data/lib/stripe/order.rb +4 -4
  26. data/lib/stripe/reversal.rb +1 -1
  27. data/lib/stripe/source.rb +2 -2
  28. data/lib/stripe/stripe_client.rb +396 -0
  29. data/lib/stripe/stripe_response.rb +48 -0
  30. data/lib/stripe/transfer.rb +2 -2
  31. data/lib/stripe/util.rb +6 -6
  32. data/lib/stripe/version.rb +1 -1
  33. data/spec/fixtures.json +0 -0
  34. data/spec/fixtures.yaml +0 -0
  35. data/spec/spec.json +0 -0
  36. data/spec/spec.yaml +0 -0
  37. data/stripe.gemspec +1 -1
  38. data/test/api_fixtures.rb +29 -0
  39. data/test/api_stub_helpers.rb +125 -0
  40. data/test/stripe/account_test.rb +153 -247
  41. data/test/stripe/alipay_account_test.rb +10 -2
  42. data/test/stripe/api_operations_test.rb +3 -3
  43. data/test/stripe/api_resource_test.rb +139 -499
  44. data/test/stripe/apple_pay_domain_test.rb +22 -23
  45. data/test/stripe/application_fee_refund_test.rb +22 -31
  46. data/test/stripe/application_fee_test.rb +6 -17
  47. data/test/stripe/balance_test.rb +3 -3
  48. data/test/stripe/bank_account_test.rb +31 -11
  49. data/test/stripe/bitcoin_receiver_test.rb +51 -42
  50. data/test/stripe/bitcoin_transaction_test.rb +11 -19
  51. data/test/stripe/charge_test.rb +39 -126
  52. data/test/stripe/country_spec_test.rb +7 -30
  53. data/test/stripe/coupon_test.rb +33 -17
  54. data/test/stripe/customer_card_test.rb +25 -46
  55. data/test/stripe/customer_test.rb +86 -81
  56. data/test/stripe/dispute_test.rb +27 -38
  57. data/test/stripe/errors_test.rb +2 -2
  58. data/test/stripe/file_upload_test.rb +32 -24
  59. data/test/stripe/invoice_item_test.rb +46 -10
  60. data/test/stripe/invoice_test.rb +48 -48
  61. data/test/stripe/list_object_test.rb +22 -31
  62. data/test/stripe/order_return_test.rb +11 -15
  63. data/test/stripe/order_test.rb +38 -51
  64. data/test/stripe/plan_test.rb +39 -18
  65. data/test/stripe/product_test.rb +29 -33
  66. data/test/stripe/recipient_card_test.rb +23 -40
  67. data/test/stripe/recipient_test.rb +39 -10
  68. data/test/stripe/refund_test.rb +20 -45
  69. data/test/stripe/reversal_test.rb +27 -31
  70. data/test/stripe/sku_test.rb +36 -19
  71. data/test/stripe/source_test.rb +26 -66
  72. data/test/stripe/stripe_client_test.rb +428 -0
  73. data/test/stripe/stripe_object_test.rb +6 -2
  74. data/test/stripe/stripe_response_test.rb +46 -0
  75. data/test/stripe/subscription_item_test.rb +37 -59
  76. data/test/stripe/subscription_test.rb +40 -176
  77. data/test/stripe/three_d_secure_test.rb +13 -12
  78. data/test/stripe/transfer_test.rb +36 -19
  79. data/test/stripe_test.rb +3 -36
  80. data/test/test_data.rb +5 -931
  81. data/test/test_helper.rb +21 -25
  82. metadata +22 -17
  83. data/test/stripe/charge_refund_test.rb +0 -67
  84. data/test/stripe/metadata_test.rb +0 -129
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 62e0a925e86bf0a18b48c88a9a359241075cd94a
4
- data.tar.gz: 8de490482c9fd1a2e7e8d5bd28ac8eb34a0276c6
3
+ metadata.gz: fe6ecafb3e94d2c21da1cad428be4ac9fda47ed9
4
+ data.tar.gz: d69bf4b5289a9661d3d8a9383bb4acea4cb2c0b9
5
5
  SHA512:
6
- metadata.gz: bf4525ce47f09b015d0a450667df948a15794538b13c076aefa0ba147d7d6829e344abd7c61285f38c2fcbad7a859f708942a661fe6521b4f76357383627ca6d
7
- data.tar.gz: b86195048056fb06aade87235e6bf46c7d642101bf55b7bfd1f3375bf9f741ff522c22f1b74cee3fa4c7d8228a47f1fd53bf548e89b243e8af5826f5ebef3393
6
+ metadata.gz: 381878036316652650840edfa24814e60b21ce6813a9e8cc4a5e58ff000349434d7947e63e51390d962d817755e0b40b68a1370781262b982cef93aa90296879
7
+ data.tar.gz: 9afa8b57e838b7a44264f302afbb2c9b62c40176dc699a17ff83fb5fe50c4c481f0cf7de3f83dd7c7ec70211dc466d5a22e290b3157cbb2ed34bc10562871bac
@@ -0,0 +1,4 @@
1
+ # may be useful in hiding large schema changes in pull request diffs (but not
2
+ # using it for now)
3
+ spec/*.json binary
4
+ spec/*.yaml binary
@@ -1,12 +1,11 @@
1
1
  language: ruby
2
2
 
3
3
  rvm:
4
- - 1.9.3
5
4
  - 2.0.0
6
5
  - 2.1
7
6
  - 2.2
8
7
  - 2.3.0
9
- - jruby-19mode
8
+ - 2.4.0
10
9
  - jruby-9.0.5.0
11
10
 
12
11
  notifications:
data/Gemfile CHANGED
@@ -3,23 +3,21 @@ source "https://rubygems.org"
3
3
  gemspec
4
4
 
5
5
  group :development do
6
+ gem 'committee', '2.0.0.pre6'
6
7
  gem 'mocha', '~> 0.13.2'
7
- gem 'pry'
8
8
  gem 'rake'
9
9
  gem 'shoulda-context'
10
+ gem 'sinatra'
10
11
  gem 'test-unit'
12
+ gem 'webmock'
11
13
 
12
- # mime-types has become only compatible with Ruby versions > 2 and we're
13
- # still supporting 1.9 for the time being. Lock to old versions of
14
- # mime-types and rest-client which are known to work in our Gemfile (it's
15
- # fine to use newer versions in live environments so we don't have these in
16
- # the gemspec).
17
- #
18
- # https://github.com/travis-ci/travis-ci/issues/5145
19
- #
20
- if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.0.0')
21
- gem 'mime-types', '2.6.2'
22
- gem 'rest-client', '1.8.0'
14
+ # Rack 2.0+ requires Ruby >= 2.2.2 which is problematic for the test suite on
15
+ # older Ruby versions. Check Ruby the version here and put a maximum
16
+ # constraint on Rack if necessary.
17
+ if RUBY_VERSION >= '2.2.2'
18
+ gem "rack", ">= 1.5"
19
+ else
20
+ gem "rack", ">= 1.5", "< 2.0"
23
21
  end
24
22
 
25
23
  platforms :mri do
@@ -27,6 +25,7 @@ group :development do
27
25
  # it's known to work well
28
26
  if Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.0.0')
29
27
  gem 'byebug'
28
+ gem 'pry'
30
29
  gem 'pry-byebug'
31
30
  end
32
31
  end
@@ -1,3 +1,11 @@
1
+ === 2.0.0 2017-02-14
2
+
3
+ * Drop support for Ruby 1.9
4
+ * Allow HTTP client that makes Stripe calls to be configured via Faraday
5
+ * Drop RestClient
6
+ * Switch to OpenAPI 2.0 spec and generated fixtures in test suite
7
+ * Switch to Webmock in test suite
8
+
1
9
  === 1.58.0 2017-01-19
2
10
 
3
11
  * Remove erroneously added list methods for `Source` model
data/README.md CHANGED
@@ -32,8 +32,7 @@ If you want to build the gem from source:
32
32
 
33
33
  ### Requirements
34
34
 
35
- * Ruby 1.9.3 or above.
36
- * rest-client
35
+ * Ruby 2.0+.
37
36
 
38
37
  ### Bundler
39
38
 
@@ -51,8 +50,8 @@ gem 'stripe'
51
50
  ## Usage
52
51
 
53
52
  The library needs to be configured with your account's secret key which is
54
- available in the [Dashboard][dashboard]. Assign its value to `Stripe.api_key`
55
- and the library will send it along automatically with every request:
53
+ available in your [Stripe Dashboard][dashboard]. Set `Stripe.api_key` to its
54
+ value:
56
55
 
57
56
  ``` ruby
58
57
  require "stripe"
@@ -67,14 +66,11 @@ Stripe::Charge.retrieve(
67
66
  )
68
67
  ```
69
68
 
70
- You can also set a per-request key and/or account like in the examples below.
71
- This is often useful for Connect applications that use multiple API keys during
72
- the lifetime of a process.
69
+ ### Per-request Configuration
73
70
 
74
- Authentication is transparently handled for you in subsequent method calls on
75
- the returned object.
76
-
77
- For example:
71
+ For apps that need to use multiple keys during the lifetime of a process, like
72
+ one that uses [Stripe Connect][connect], it's also possible to set a
73
+ per-request key and/or account:
78
74
 
79
75
  ``` ruby
80
76
  require "stripe"
@@ -92,6 +88,40 @@ Stripe::Charge.retrieve(
92
88
  )
93
89
  ```
94
90
 
91
+ ### Configuring a Client
92
+
93
+ While a default HTTP client is used by default, it's also possible to have the
94
+ library use any client supported by [Faraday][faraday] by initializing a
95
+ `Stripe::StripeClient` object and giving it a connection:
96
+
97
+ ``` ruby
98
+ conn = Faraday.new
99
+ client = Stripe::StripeClient.new(conn)
100
+ client.request do
101
+ charge, resp = Stripe::Charge.retrieve(
102
+ "ch_18atAXCdGbJFKhCuBAa4532Z",
103
+ )
104
+ end
105
+ puts resp.request_id
106
+ ```
107
+
108
+ ### Configuring CA Bundles
109
+
110
+ By default, the library will use its own internal bundle of known CA
111
+ certificates, but it's possible to configure your own:
112
+
113
+ Stripe.ca_bundle_path = "path/to/ca/bundle"
114
+
115
+ ### Configuring Automatic Retries
116
+
117
+ The library can be configured to automatically retry requests that fail due to
118
+ an intermittent network problem:
119
+
120
+ Stripe.max_network_retries = 2
121
+
122
+ [Idempotency keys][idempotency-keys] are added to requests to guarantee that
123
+ retries are safe.
124
+
95
125
  ## Development
96
126
 
97
127
  Run all tests:
@@ -110,25 +140,8 @@ Update bundled CA certificates from the [Mozilla cURL release][curl]:
110
140
 
111
141
  bundle exec rake update_certs
112
142
 
113
- ## Configuration
114
-
115
- ### ca_bundle_path
116
-
117
- The location of a file containing a bundle of CA certificates. By default the
118
- library will use an included bundle that can successfully validate Stripe
119
- certificates.
120
-
121
- ### max_network_retries
122
-
123
- When `max_network_retries` is set to a positive integer, stripe will retry
124
- requests that fail on a network error. Idempotency keys will be added to `POST`
125
- and `DELETE` requests to ensure the safety of retrying. There will be a short delay
126
- between each retry, with an exponential backoff algorithm used to determine the
127
- length of the delay. Default value is 0.
128
-
129
- Example:
130
-
131
- Stripe.max_network_retries = 2
132
-
143
+ [connect]: https://stripe.com/connect
133
144
  [curl]: http://curl.haxx.se/docs/caextract.html
145
+ [faraday]: https://github.com/lostisland/faraday
146
+ [idempotency-keys]: https://stripe.com/docs/api/ruby#idempotent_requests
134
147
  [dashboard]: https://dashboard.stripe.com/account
data/Rakefile CHANGED
@@ -10,7 +10,7 @@ desc "update bundled certs"
10
10
  task :update_certs do
11
11
  require "restclient"
12
12
  File.open(File.join(File.dirname(__FILE__), 'lib', 'data', 'ca-certificates.crt'), 'w') do |file|
13
- resp = RestClient.get "https://raw.githubusercontent.com/bagder/ca-bundle/master/ca-bundle.crt"
13
+ resp = Faraday.get "https://raw.githubusercontent.com/bagder/ca-bundle/master/ca-bundle.crt"
14
14
  abort("bad response when fetching bundle") unless resp.code == 200
15
15
  file.write(resp.to_str)
16
16
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.58.0
1
+ 2.0.0
@@ -6,7 +6,7 @@ require 'rbconfig'
6
6
  require 'set'
7
7
  require 'socket'
8
8
 
9
- require 'rest-client'
9
+ require 'faraday'
10
10
  require 'json'
11
11
 
12
12
  # Version
@@ -22,7 +22,9 @@ require 'stripe/api_operations/request'
22
22
  # API resource support classes
23
23
  require 'stripe/errors'
24
24
  require 'stripe/util'
25
+ require 'stripe/stripe_client'
25
26
  require 'stripe/stripe_object'
27
+ require 'stripe/stripe_response'
26
28
  require 'stripe/list_object'
27
29
  require 'stripe/api_resource'
28
30
  require 'stripe/singleton_api_resource'
@@ -66,35 +68,6 @@ require 'stripe/transfer'
66
68
  module Stripe
67
69
  DEFAULT_CA_BUNDLE_PATH = File.dirname(__FILE__) + '/data/ca-certificates.crt'
68
70
 
69
- # Exceptions which we'd like to retry. This includes both socket errors that
70
- # may represent an intermittent problem and some special HTTP statuses.
71
- RETRY_EXCEPTIONS = [
72
- # Destination refused the connection. This could occur from a single
73
- # saturated server, so retry in case it's intermittent.
74
- Errno::ECONNREFUSED,
75
-
76
- # Connection reset. This occasionally occurs on a server problem, and
77
- # deserves a retry because the server should terminate all requests
78
- # properly even if they were invalid.
79
- Errno::ECONNRESET,
80
-
81
- # Timed out making the connection. It's worth retrying under this
82
- # circumstance.
83
- Errno::ETIMEDOUT,
84
-
85
- # A server may respond with a 409 to indicate that there is a concurrent
86
- # request executing with the same idempotency key. In the case that a
87
- # request failed due to a connection problem and the client has retried too
88
- # early, but the server is still executing the old request, we would like
89
- # the client to continue retrying until getting a "real" response status
90
- # back.
91
- RestClient::Conflict,
92
-
93
- # Retry on timeout-related problems. This shouldn't be lumped in with HTTP
94
- # exceptions, but with RestClient it is.
95
- RestClient::RequestTimeout,
96
- ].freeze
97
-
98
71
  @api_base = 'https://api.stripe.com'
99
72
  @connect_base = 'https://connect.stripe.com'
100
73
  @uploads_base = 'https://uploads.stripe.com'
@@ -103,7 +76,7 @@ module Stripe
103
76
  @max_network_retry_delay = 2
104
77
  @initial_network_retry_delay = 0.5
105
78
 
106
- @ca_bundle_path = DEFAULT_CA_BUNDLE_PATH
79
+ @ca_bundle_path = DEFAULT_CA_BUNDLE_PATH
107
80
  @ca_store = nil
108
81
  @verify_ssl_certs = true
109
82
 
@@ -117,10 +90,6 @@ module Stripe
117
90
  attr_reader :max_network_retry_delay, :initial_network_retry_delay
118
91
  end
119
92
 
120
- def self.api_url(url='', api_base_url=nil)
121
- (api_base_url || @api_base) + url
122
- end
123
-
124
93
  # The location of a file containing a bundle of CA certificates. By default
125
94
  # the library will use an included bundle that can successfully validate
126
95
  # Stripe certificates.
@@ -152,62 +121,6 @@ module Stripe
152
121
  end
153
122
  end
154
123
 
155
- def self.request(method, url, api_key, params={}, headers={}, api_base_url=nil)
156
- api_base_url = api_base_url || @api_base
157
-
158
- unless api_key ||= @api_key
159
- raise AuthenticationError.new('No API key provided. ' \
160
- 'Set your API key using "Stripe.api_key = <API-KEY>". ' \
161
- 'You can generate API keys from the Stripe web interface. ' \
162
- 'See https://stripe.com/api for details, or email support@stripe.com ' \
163
- 'if you have any questions.')
164
- end
165
-
166
- if api_key =~ /\s/
167
- raise AuthenticationError.new('Your API key is invalid, as it contains ' \
168
- 'whitespace. (HINT: You can double-check your API key from the ' \
169
- 'Stripe web interface. See https://stripe.com/api for details, or ' \
170
- 'email support@stripe.com if you have any questions.)')
171
- end
172
-
173
- if verify_ssl_certs
174
- request_opts = {:verify_ssl => OpenSSL::SSL::VERIFY_PEER,
175
- :ssl_cert_store => ca_store}
176
- else
177
- request_opts = {:verify_ssl => false}
178
- unless @verify_ssl_warned
179
- @verify_ssl_warned = true
180
- $stderr.puts("WARNING: Running without SSL cert verification. " \
181
- "You should never do this in production. " \
182
- "Execute 'Stripe.verify_ssl_certs = true' to enable verification.")
183
- end
184
- end
185
-
186
- params = Util.objects_to_ids(params)
187
- url = api_url(url, api_base_url)
188
-
189
- case method.to_s.downcase.to_sym
190
- when :get, :head, :delete
191
- # Make params into GET parameters
192
- url += "#{URI.parse(url).query ? '&' : '?'}#{Util.encode_parameters(params)}" if params && params.any?
193
- payload = nil
194
- else
195
- if headers[:content_type] && headers[:content_type] == "multipart/form-data"
196
- payload = params
197
- else
198
- payload = Util.encode_parameters(params)
199
- end
200
- end
201
-
202
- request_opts.update(:headers => request_headers(api_key, method).update(headers),
203
- :method => method, :open_timeout => open_timeout,
204
- :payload => payload, :url => url, :timeout => read_timeout)
205
-
206
- response = execute_request_with_rescues(request_opts, api_base_url)
207
-
208
- [parse(response), api_key]
209
- end
210
-
211
124
  def self.max_network_retries
212
125
  @max_network_retries
213
126
  end
@@ -218,242 +131,6 @@ module Stripe
218
131
 
219
132
  private
220
133
 
221
- def self.api_error(error, resp, error_obj)
222
- APIError.new(error[:message], resp.code, resp.body, error_obj, resp.headers)
223
- end
224
-
225
- def self.authentication_error(error, resp, error_obj)
226
- AuthenticationError.new(error[:message], resp.code, resp.body, error_obj,
227
- resp.headers)
228
- end
229
-
230
- def self.card_error(error, resp, error_obj)
231
- CardError.new(error[:message], error[:param], error[:code],
232
- resp.code, resp.body, error_obj, resp.headers)
233
- end
234
-
235
- def self.execute_request(opts)
236
- RestClient::Request.execute(opts)
237
- end
238
-
239
- def self.execute_request_with_rescues(request_opts, api_base_url, retry_count = 0)
240
- begin
241
- response = execute_request(request_opts)
242
-
243
- # We rescue all exceptions from a request so that we have an easy spot to
244
- # implement our retry logic across the board. We'll re-raise if it's a type
245
- # of exception that we didn't expect to handle.
246
- rescue => e
247
- if should_retry?(e, retry_count)
248
- retry_count = retry_count + 1
249
- sleep sleep_time(retry_count)
250
- retry
251
- end
252
-
253
- case e
254
- when SocketError
255
- response = handle_restclient_error(e, request_opts, retry_count, api_base_url)
256
-
257
- when RestClient::ExceptionWithResponse
258
- if e.response
259
- handle_api_error(e.response)
260
- else
261
- response = handle_restclient_error(e, request_opts, retry_count, api_base_url)
262
- end
263
-
264
- when RestClient::Exception, Errno::ECONNREFUSED, OpenSSL::SSL::SSLError
265
- response = handle_restclient_error(e, request_opts, retry_count, api_base_url)
266
-
267
- # Only handle errors when we know we can do so, and re-raise otherwise.
268
- # This should be pretty infrequent.
269
- else
270
- raise
271
- end
272
- end
273
-
274
- response
275
- end
276
-
277
- def self.general_api_error(rcode, rbody)
278
- APIError.new("Invalid response object from API: #{rbody.inspect} " +
279
- "(HTTP response code was #{rcode})", rcode, rbody)
280
- end
281
-
282
- def self.get_uname
283
- if File.exist?('/proc/version')
284
- File.read('/proc/version').strip
285
- else
286
- case RbConfig::CONFIG['host_os']
287
- when /linux|darwin|bsd|sunos|solaris|cygwin/i
288
- get_uname_from_system
289
- when /mswin|mingw/i
290
- get_uname_from_system_ver
291
- else
292
- "unknown platform"
293
- end
294
- end
295
- end
296
-
297
- def self.get_uname_from_system
298
- (`uname -a 2>/dev/null` || '').strip
299
- rescue Errno::ENOENT
300
- "uname executable not found"
301
- rescue Errno::ENOMEM # couldn't create subprocess
302
- "uname lookup failed"
303
- end
304
-
305
- def self.get_uname_from_system_ver
306
- (`ver` || '').strip
307
- rescue Errno::ENOENT
308
- "ver executable not found"
309
- rescue Errno::ENOMEM # couldn't create subprocess
310
- "uname lookup failed"
311
- end
312
-
313
- def self.handle_api_error(resp)
314
- begin
315
- error_obj = JSON.parse(resp.body)
316
- error_obj = Util.symbolize_names(error_obj)
317
- error = error_obj[:error]
318
- raise StripeError.new unless error && error.is_a?(Hash)
319
-
320
- rescue JSON::ParserError, StripeError
321
- raise general_api_error(resp.code, resp.body)
322
- end
323
-
324
- case resp.code
325
- when 400, 404
326
- raise invalid_request_error(error, resp, error_obj)
327
- when 401
328
- raise authentication_error(error, resp, error_obj)
329
- when 402
330
- raise card_error(error, resp, error_obj)
331
- when 403
332
- raise permission_error(error, resp, error_obj)
333
- when 429
334
- raise rate_limit_error(error, resp, error_obj)
335
- else
336
- raise api_error(error, resp, error_obj)
337
- end
338
-
339
- end
340
-
341
- def self.handle_restclient_error(e, request_opts, retry_count, api_base_url=nil)
342
-
343
- api_base_url = @api_base unless api_base_url
344
- connection_message = "Please check your internet connection and try again. " \
345
- "If this problem persists, you should check Stripe's service status at " \
346
- "https://twitter.com/stripestatus, or let us know at support@stripe.com."
347
-
348
- case e
349
- when RestClient::RequestTimeout
350
- message = "Could not connect to Stripe (#{api_base_url}). #{connection_message}"
351
-
352
- when RestClient::ServerBrokeConnection
353
- message = "The connection to the server (#{api_base_url}) broke before the " \
354
- "request completed. #{connection_message}"
355
-
356
- when OpenSSL::SSL::SSLError
357
- message = "Could not establish a secure connection to Stripe, you may " \
358
- "need to upgrade your OpenSSL version. To check, try running " \
359
- "'openssl s_client -connect api.stripe.com:443' from the " \
360
- "command line."
361
-
362
- when RestClient::SSLCertificateNotVerified
363
- message = "Could not verify Stripe's SSL certificate. " \
364
- "Please make sure that your network is not intercepting certificates. " \
365
- "(Try going to https://api.stripe.com/v1 in your browser.) " \
366
- "If this problem persists, let us know at support@stripe.com."
367
-
368
- when SocketError
369
- message = "Unexpected error communicating when trying to connect to Stripe. " \
370
- "You may be seeing this message because your DNS is not working. " \
371
- "To check, try running 'host stripe.com' from the command line."
372
-
373
- else
374
- message = "Unexpected error communicating with Stripe. " \
375
- "If this problem persists, let us know at support@stripe.com."
376
-
377
- end
378
-
379
- if retry_count > 0
380
- message += " Request was retried #{retry_count} times."
381
- end
382
-
383
- raise APIConnectionError.new(message + "\n\n(Network error: #{e.message})")
384
- end
385
-
386
- def self.invalid_request_error(error, resp, error_obj)
387
- InvalidRequestError.new(error[:message], error[:param], resp.code,
388
- resp.body, error_obj, resp.headers)
389
- end
390
-
391
- def self.parse(response)
392
- begin
393
- # Would use :symbolize_names => true, but apparently there is
394
- # some library out there that makes symbolize_names not work.
395
- response = JSON.parse(response.body)
396
- rescue JSON::ParserError
397
- raise general_api_error(response.code, response.body)
398
- end
399
-
400
- Util.symbolize_names(response)
401
- end
402
-
403
- def self.permission_error(error, resp, error_obj)
404
- PermissionError.new(error[:message], resp.code, resp.body, error_obj, resp.headers)
405
- end
406
-
407
- def self.rate_limit_error(error, resp, error_obj)
408
- RateLimitError.new(error[:message], resp.code, resp.body, error_obj,
409
- resp.headers)
410
- end
411
-
412
- def self.request_headers(api_key, method)
413
- headers = {
414
- 'User-Agent' => "Stripe/v1 RubyBindings/#{Stripe::VERSION}",
415
- 'Authorization' => "Bearer #{api_key}",
416
- 'Content-Type' => 'application/x-www-form-urlencoded'
417
- }
418
-
419
- # It is only safe to retry network failures on post and delete
420
- # requests if we add an Idempotency-Key header
421
- if [:post, :delete].include?(method) && self.max_network_retries > 0
422
- headers['Idempotency-Key'] ||= SecureRandom.uuid
423
- end
424
-
425
- headers['Stripe-Version'] = api_version if api_version
426
- headers['Stripe-Account'] = stripe_account if stripe_account
427
-
428
- begin
429
- headers.update('X-Stripe-Client-User-Agent' => JSON.generate(user_agent))
430
- rescue => e
431
- headers.update('X-Stripe-Client-Raw-User-Agent' => user_agent.inspect,
432
- :error => "#{e} (#{e.class})")
433
- end
434
- end
435
-
436
- def self.should_retry?(e, retry_count)
437
- retry_count < self.max_network_retries &&
438
- RETRY_EXCEPTIONS.any? { |klass| e.is_a?(klass) }
439
- end
440
-
441
- def self.sleep_time(retry_count)
442
- # Apply exponential backoff with initial_network_retry_delay on the number
443
- # of attempts so far as inputs. Do not allow the number to exceed
444
- # max_network_retry_delay.
445
- sleep_seconds = [initial_network_retry_delay * (2 ** (retry_count - 1)), max_network_retry_delay].min
446
-
447
- # Apply some jitter by randomizing the value in the range of (sleep_seconds
448
- # / 2) to (sleep_seconds).
449
- sleep_seconds = sleep_seconds * (0.5 * (1 + rand()))
450
-
451
- # But never sleep less than the base sleep seconds.
452
- sleep_seconds = [initial_network_retry_delay, sleep_seconds].max
453
-
454
- sleep_seconds
455
- end
456
-
457
134
  # DEPRECATED. Use `Util#encode_parameters` instead.
458
135
  def self.uri_encode(params)
459
136
  Util.encode_parameters(params)
@@ -462,21 +139,4 @@ module Stripe
462
139
  extend Gem::Deprecate
463
140
  deprecate :uri_encode, "Stripe::Util#encode_parameters", 2016, 01
464
141
  end
465
-
466
- def self.user_agent
467
- @uname ||= get_uname
468
- lang_version = "#{RUBY_VERSION} p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE})"
469
-
470
- {
471
- :bindings_version => Stripe::VERSION,
472
- :lang => 'ruby',
473
- :lang_version => lang_version,
474
- :platform => RUBY_PLATFORM,
475
- :engine => defined?(RUBY_ENGINE) ? RUBY_ENGINE : '',
476
- :publisher => 'stripe',
477
- :uname => @uname,
478
- :hostname => Socket.gethostname,
479
- }
480
-
481
- end
482
142
  end