stripe 5.32.0 → 5.36.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e600b7741930b12c7ffaa1b6cfdcf6a540d5d57f8955a2c0be38a37d6f5ff556
4
- data.tar.gz: dfd0a97aff35a0e38a4818a1c239da46b3d47d741cf1fb3c7608d7d5c7c182b9
3
+ metadata.gz: 9055258932833823356b606115c73e9a909bbfc2e6d70506e2c71d21e2176c27
4
+ data.tar.gz: 4a7261f19e29f65407bff7ee8ae916c1b826e81ac4e1e9c102b6ac147c548b31
5
5
  SHA512:
6
- metadata.gz: 7fe07169d17aa534beffca79063fdc9c48ebebc48176aed097220a183c0d305d696b97bba255f6c3633755e92c96bbbacb5cb1865c66c99754ca28c4f23e7c84
7
- data.tar.gz: 9b06b7398144207f98d74bb270777fdf5b8a54f454c776891d95401cae9a86edd487aeebfe44d1b38744ff17e3f8d952b34415308241597f3351720936791504
6
+ metadata.gz: bd7fa29256871a690e19758b6777d9ee58e51fa4cf0a7b3e576fac24deca605cdb400e7eb091378ff15540c1a48ccfd25ba0bb9befba04d6a92d95fb1202416b
7
+ data.tar.gz: ce6d07144a874d49e088033645916e1aa09b2e5eedf787ea1eb182ef963ffddafd314d7442a258937e028b8d84ed04c00d02c68f6a93841a262dbd5bc6e5aecd
data/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # Changelog
2
2
 
3
+ ## 5.36.0 - 2021-07-09
4
+ * [#987](https://github.com/stripe/stripe-ruby/pull/987) Add support for `Quote` API
5
+
6
+ ## 5.35.0 - 2021-06-30
7
+ * [#985](https://github.com/stripe/stripe-ruby/pull/985) Update normalize_opts to use dup instead of clone.
8
+ * [#982](https://github.com/stripe/stripe-ruby/pull/982) Deprecate travis
9
+ * [#983](https://github.com/stripe/stripe-ruby/pull/983) Add support for making a request and receiving the response as a stream.
10
+
11
+ ## 5.34.0 - 2021-06-04
12
+ * [#981](https://github.com/stripe/stripe-ruby/pull/981) API Updates
13
+ * Add support for `TaxCode` API.
14
+
15
+ ## 5.33.0 - 2021-05-19
16
+ * [#979](https://github.com/stripe/stripe-ruby/pull/979) Add support for the Identify VerificationSession and VerificationReport APIs
17
+
18
+ ## 5.32.1 - 2021-04-05
19
+ * Correct use of regexp `match` in gemspec for old versions of Ruby
20
+
3
21
  ## 5.32.0 - 2021-04-05
4
22
  * [#973](https://github.com/stripe/stripe-ruby/pull/973) Reduce packed gem size
5
23
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 5.32.0
1
+ 5.36.0
@@ -6,6 +6,28 @@ module Stripe
6
6
  module ClassMethods
7
7
  def execute_resource_request(method, url,
8
8
  params = {}, opts = {})
9
+ execute_resource_request_internal(
10
+ :execute_request, method, url, params, opts
11
+ )
12
+ end
13
+
14
+ def execute_resource_request_stream(method, url,
15
+ params = {}, opts = {},
16
+ &read_body_chunk_block)
17
+ execute_resource_request_internal(
18
+ :execute_request_stream,
19
+ method,
20
+ url,
21
+ params,
22
+ opts,
23
+ &read_body_chunk_block
24
+ )
25
+ end
26
+
27
+ private def execute_resource_request_internal(client_request_method_sym,
28
+ method, url,
29
+ params, opts,
30
+ &read_body_chunk_block)
9
31
  params ||= {}
10
32
 
11
33
  error_on_invalid_params(params)
@@ -22,10 +44,12 @@ module Stripe
22
44
  client = headers.delete(:client)
23
45
  # Assume all remaining opts must be headers
24
46
 
25
- resp, opts[:api_key] = client.execute_request(
47
+ resp, opts[:api_key] = client.send(
48
+ client_request_method_sym,
26
49
  method, url,
27
50
  api_base: api_base, api_key: api_key,
28
- headers: headers, params: params
51
+ headers: headers, params: params,
52
+ &read_body_chunk_block
29
53
  )
30
54
 
31
55
  # Hash#select returns an array before 1.9
@@ -89,6 +113,15 @@ module Stripe
89
113
  self.class.execute_resource_request(method, url, params, opts)
90
114
  end
91
115
 
116
+ protected def execute_resource_request_stream(method, url,
117
+ params = {}, opts = {},
118
+ &read_body_chunk_block)
119
+ opts = @opts.merge(Util.normalize_opts(opts))
120
+ self.class.execute_resource_request_stream(
121
+ method, url, params, opts, &read_body_chunk_block
122
+ )
123
+ end
124
+
92
125
  # See notes on `alias` above.
93
126
  alias request execute_resource_request
94
127
  end
@@ -115,5 +115,13 @@ module Stripe
115
115
  Util.convert_to_stripe_object(resp.data, opts)
116
116
  end
117
117
  end
118
+
119
+ protected def request_stream(method:, path:, params:, opts: {},
120
+ &read_body_chunk_block)
121
+ resp, = execute_resource_request_stream(
122
+ method, path, params, opts, &read_body_chunk_block
123
+ )
124
+ resp
125
+ end
118
126
  end
119
127
  end
@@ -66,7 +66,8 @@ module Stripe
66
66
 
67
67
  # Executes an HTTP request to the given URI with the given method. Also
68
68
  # allows a request body, headers, and query string to be specified.
69
- def execute_request(method, uri, body: nil, headers: nil, query: nil)
69
+ def execute_request(method, uri, body: nil, headers: nil, query: nil,
70
+ &block)
70
71
  # Perform some basic argument validation because it's easy to get
71
72
  # confused between strings and hashes for things like body and query
72
73
  # parameters.
@@ -92,8 +93,22 @@ module Stripe
92
93
  u.path
93
94
  end
94
95
 
96
+ method_name = method.to_s.upcase
97
+ has_response_body = method_name != "HEAD"
98
+ request = Net::HTTPGenericRequest.new(
99
+ method_name,
100
+ (body ? true : false),
101
+ has_response_body,
102
+ path,
103
+ headers
104
+ )
105
+
95
106
  @mutex.synchronize do
96
- connection.send_request(method.to_s.upcase, path, body, headers)
107
+ # The block parameter is special here. If a block is provided, the block
108
+ # is invoked with the Net::HTTPResponse. However, the body will not have
109
+ # been read yet in the block, and can be streamed by calling
110
+ # HTTPResponse#read_body.
111
+ connection.request(request, body, &block)
97
112
  end
98
113
  end
99
114
 
@@ -41,6 +41,8 @@ module Stripe
41
41
  File::OBJECT_NAME => File,
42
42
  File::OBJECT_NAME_ALT => File,
43
43
  FileLink::OBJECT_NAME => FileLink,
44
+ Identity::VerificationReport::OBJECT_NAME => Identity::VerificationReport,
45
+ Identity::VerificationSession::OBJECT_NAME => Identity::VerificationSession,
44
46
  Invoice::OBJECT_NAME => Invoice,
45
47
  InvoiceItem::OBJECT_NAME => InvoiceItem,
46
48
  InvoiceLineItem::OBJECT_NAME => InvoiceLineItem,
@@ -63,6 +65,7 @@ module Stripe
63
65
  Price::OBJECT_NAME => Price,
64
66
  Product::OBJECT_NAME => Product,
65
67
  PromotionCode::OBJECT_NAME => PromotionCode,
68
+ Quote::OBJECT_NAME => Quote,
66
69
  Radar::EarlyFraudWarning::OBJECT_NAME => Radar::EarlyFraudWarning,
67
70
  Radar::ValueList::OBJECT_NAME => Radar::ValueList,
68
71
  Radar::ValueListItem::OBJECT_NAME => Radar::ValueListItem,
@@ -82,6 +85,7 @@ module Stripe
82
85
  Subscription::OBJECT_NAME => Subscription,
83
86
  SubscriptionItem::OBJECT_NAME => SubscriptionItem,
84
87
  SubscriptionSchedule::OBJECT_NAME => SubscriptionSchedule,
88
+ TaxCode::OBJECT_NAME => TaxCode,
85
89
  TaxId::OBJECT_NAME => TaxId,
86
90
  TaxRate::OBJECT_NAME => TaxRate,
87
91
  Terminal::ConnectionToken::OBJECT_NAME => Terminal::ConnectionToken,
@@ -30,6 +30,8 @@ require "stripe/resources/event"
30
30
  require "stripe/resources/exchange_rate"
31
31
  require "stripe/resources/file"
32
32
  require "stripe/resources/file_link"
33
+ require "stripe/resources/identity/verification_report"
34
+ require "stripe/resources/identity/verification_session"
33
35
  require "stripe/resources/invoice"
34
36
  require "stripe/resources/invoice_item"
35
37
  require "stripe/resources/invoice_line_item"
@@ -52,6 +54,7 @@ require "stripe/resources/plan"
52
54
  require "stripe/resources/price"
53
55
  require "stripe/resources/product"
54
56
  require "stripe/resources/promotion_code"
57
+ require "stripe/resources/quote"
55
58
  require "stripe/resources/radar/early_fraud_warning"
56
59
  require "stripe/resources/radar/value_list"
57
60
  require "stripe/resources/radar/value_list_item"
@@ -71,6 +74,7 @@ require "stripe/resources/source_transaction"
71
74
  require "stripe/resources/subscription"
72
75
  require "stripe/resources/subscription_item"
73
76
  require "stripe/resources/subscription_schedule"
77
+ require "stripe/resources/tax_code"
74
78
  require "stripe/resources/tax_id"
75
79
  require "stripe/resources/tax_rate"
76
80
  require "stripe/resources/terminal/connection_token"
@@ -0,0 +1,12 @@
1
+ # File generated from our OpenAPI spec
2
+ # frozen_string_literal: true
3
+
4
+ module Stripe
5
+ module Identity
6
+ class VerificationReport < APIResource
7
+ extend Stripe::APIOperations::List
8
+
9
+ OBJECT_NAME = "identity.verification_report"
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,35 @@
1
+ # File generated from our OpenAPI spec
2
+ # frozen_string_literal: true
3
+
4
+ module Stripe
5
+ module Identity
6
+ class VerificationSession < APIResource
7
+ extend Stripe::APIOperations::Create
8
+ extend Stripe::APIOperations::List
9
+ include Stripe::APIOperations::Save
10
+
11
+ OBJECT_NAME = "identity.verification_session"
12
+
13
+ custom_method :cancel, http_verb: :post
14
+ custom_method :redact, http_verb: :post
15
+
16
+ def cancel(params = {}, opts = {})
17
+ request_stripe_object(
18
+ method: :post,
19
+ path: resource_url + "/cancel",
20
+ params: params,
21
+ opts: opts
22
+ )
23
+ end
24
+
25
+ def redact(params = {}, opts = {})
26
+ request_stripe_object(
27
+ method: :post,
28
+ path: resource_url + "/redact",
29
+ params: params,
30
+ opts: opts
31
+ )
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,95 @@
1
+ # File generated from our OpenAPI spec
2
+ # frozen_string_literal: true
3
+
4
+ module Stripe
5
+ class Quote < APIResource
6
+ extend Stripe::APIOperations::Create
7
+ extend Stripe::APIOperations::List
8
+ include Stripe::APIOperations::Save
9
+
10
+ OBJECT_NAME = "quote"
11
+
12
+ custom_method :accept, http_verb: :post
13
+ custom_method :cancel, http_verb: :post
14
+ custom_method :finalize_quote, http_verb: :post, http_path: "finalize"
15
+ custom_method :list_line_items, http_verb: :get, http_path: "line_items"
16
+
17
+ def accept(params = {}, opts = {})
18
+ request_stripe_object(
19
+ method: :post,
20
+ path: resource_url + "/accept",
21
+ params: params,
22
+ opts: opts
23
+ )
24
+ end
25
+
26
+ def cancel(params = {}, opts = {})
27
+ request_stripe_object(
28
+ method: :post,
29
+ path: resource_url + "/cancel",
30
+ params: params,
31
+ opts: opts
32
+ )
33
+ end
34
+
35
+ def finalize_quote(params = {}, opts = {})
36
+ request_stripe_object(
37
+ method: :post,
38
+ path: resource_url + "/finalize",
39
+ params: params,
40
+ opts: opts
41
+ )
42
+ end
43
+
44
+ def list_line_items(params = {}, opts = {})
45
+ request_stripe_object(
46
+ method: :get,
47
+ path: resource_url + "/line_items",
48
+ params: params,
49
+ opts: opts
50
+ )
51
+ end
52
+
53
+ def pdf(params = {}, opts = {}, &read_body_chunk_block)
54
+ unless block_given?
55
+ raise ArgumentError, "A read_body_chunk_block block parameter is required when calling the pdf method."
56
+ end
57
+
58
+ config = opts[:client]&.config || Stripe.config
59
+
60
+ request_stream(
61
+ method: :get,
62
+ path: resource_url + "/pdf",
63
+ params: params,
64
+ opts: {
65
+ api_base: config.uploads_base,
66
+ }.merge(opts),
67
+ &read_body_chunk_block
68
+ )
69
+ end
70
+
71
+ def self.pdf(id, params = {}, opts = {}, &read_body_chunk_block)
72
+ unless id.is_a?(String)
73
+ raise ArgumentError,
74
+ "id should be a string representing the ID of an API resource"
75
+ end
76
+
77
+ unless block_given?
78
+ raise ArgumentError, "A read_body_chunk_block block parameter is required when calling the pdf method."
79
+ end
80
+
81
+ config = opts[:client]&.config || Stripe.config
82
+
83
+ resp = execute_resource_request_stream(
84
+ :get,
85
+ "#{resource_url}/#{CGI.escape(id)}/pdf",
86
+ params,
87
+ {
88
+ api_base: config.uploads_base,
89
+ }.merge(opts),
90
+ &read_body_chunk_block
91
+ )
92
+ resp
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,10 @@
1
+ # File generated from our OpenAPI spec
2
+ # frozen_string_literal: true
3
+
4
+ module Stripe
5
+ class TaxCode < APIResource
6
+ extend Stripe::APIOperations::List
7
+
8
+ OBJECT_NAME = "tax_code"
9
+ end
10
+ end
@@ -213,62 +213,9 @@ module Stripe
213
213
 
214
214
  def execute_request(method, path,
215
215
  api_base: nil, api_key: nil, headers: {}, params: {})
216
- raise ArgumentError, "method should be a symbol" \
217
- unless method.is_a?(Symbol)
218
- raise ArgumentError, "path should be a string" \
219
- unless path.is_a?(String)
220
-
221
- api_base ||= config.api_base
222
- api_key ||= config.api_key
223
- params = Util.objects_to_ids(params)
224
-
225
- check_api_key!(api_key)
226
-
227
- body_params = nil
228
- query_params = nil
229
- case method
230
- when :get, :head, :delete
231
- query_params = params
232
- else
233
- body_params = params
234
- end
235
-
236
- query_params, path = merge_query_params(query_params, path)
237
-
238
- headers = request_headers(api_key, method)
239
- .update(Util.normalize_headers(headers))
240
- url = api_url(path, api_base)
241
-
242
- # Merge given query parameters with any already encoded in the path.
243
- query = query_params ? Util.encode_parameters(query_params) : nil
244
-
245
- # Encoding body parameters is a little more complex because we may have
246
- # to send a multipart-encoded body. `body_log` is produced separately as
247
- # a log-friendly variant of the encoded form. File objects are displayed
248
- # as such instead of as their file contents.
249
- body, body_log =
250
- body_params ? encode_body(body_params, headers) : [nil, nil]
251
-
252
- # stores information on the request we're about to make so that we don't
253
- # have to pass as many parameters around for logging.
254
- context = RequestLogContext.new
255
- context.account = headers["Stripe-Account"]
256
- context.api_key = api_key
257
- context.api_version = headers["Stripe-Version"]
258
- context.body = body_log
259
- context.idempotency_key = headers["Idempotency-Key"]
260
- context.method = method
261
- context.path = path
262
- context.query = query
263
-
264
- http_resp = execute_request_with_rescues(method, api_base, context) do
265
- self.class
266
- .default_connection_manager(config)
267
- .execute_request(method, url,
268
- body: body,
269
- headers: headers,
270
- query: query)
271
- end
216
+ http_resp, api_key = execute_request_internal(
217
+ method, path, api_base, api_key, headers, params
218
+ )
272
219
 
273
220
  begin
274
221
  resp = StripeResponse.from_net_http(http_resp)
@@ -284,6 +231,38 @@ module Stripe
284
231
  [resp, api_key]
285
232
  end
286
233
 
234
+ # Executes a request and returns the body as a stream instead of converting
235
+ # it to a StripeObject. This should be used for any request where we expect
236
+ # an arbitrary binary response.
237
+ #
238
+ # A `read_body_chunk` block can be passed, which will be called repeatedly
239
+ # with the body chunks read from the socket.
240
+ #
241
+ # If a block is passed, a StripeHeadersOnlyResponse is returned as the
242
+ # block is expected to do all the necessary body processing. If no block is
243
+ # passed, then a StripeStreamResponse is returned containing an IO stream
244
+ # with the response body.
245
+ def execute_request_stream(method, path,
246
+ api_base: nil, api_key: nil,
247
+ headers: {}, params: {},
248
+ &read_body_chunk_block)
249
+ unless block_given?
250
+ raise ArgumentError,
251
+ "execute_request_stream requires a read_body_chunk_block"
252
+ end
253
+
254
+ http_resp, api_key = execute_request_internal(
255
+ method, path, api_base, api_key, headers, params, &read_body_chunk_block
256
+ )
257
+
258
+ # When the read_body_chunk_block is given, we no longer have access to the
259
+ # response body at this point and so return a response object containing
260
+ # only the headers. This is because the body was consumed by the block.
261
+ resp = StripeHeadersOnlyResponse.from_net_http(http_resp)
262
+
263
+ [resp, api_key]
264
+ end
265
+
287
266
  def store_last_response(object_id, resp)
288
267
  return unless last_response_has_key?(object_id)
289
268
 
@@ -451,6 +430,83 @@ module Stripe
451
430
  pruned_contexts.count
452
431
  end
453
432
 
433
+ private def execute_request_internal(method, path,
434
+ api_base, api_key, headers, params,
435
+ &read_body_chunk_block)
436
+ raise ArgumentError, "method should be a symbol" \
437
+ unless method.is_a?(Symbol)
438
+ raise ArgumentError, "path should be a string" \
439
+ unless path.is_a?(String)
440
+
441
+ api_base ||= config.api_base
442
+ api_key ||= config.api_key
443
+ params = Util.objects_to_ids(params)
444
+
445
+ check_api_key!(api_key)
446
+
447
+ body_params = nil
448
+ query_params = nil
449
+ case method
450
+ when :get, :head, :delete
451
+ query_params = params
452
+ else
453
+ body_params = params
454
+ end
455
+
456
+ query_params, path = merge_query_params(query_params, path)
457
+
458
+ headers = request_headers(api_key, method)
459
+ .update(Util.normalize_headers(headers))
460
+ url = api_url(path, api_base)
461
+
462
+ # Merge given query parameters with any already encoded in the path.
463
+ query = query_params ? Util.encode_parameters(query_params) : nil
464
+
465
+ # Encoding body parameters is a little more complex because we may have
466
+ # to send a multipart-encoded body. `body_log` is produced separately as
467
+ # a log-friendly variant of the encoded form. File objects are displayed
468
+ # as such instead of as their file contents.
469
+ body, body_log =
470
+ body_params ? encode_body(body_params, headers) : [nil, nil]
471
+
472
+ # stores information on the request we're about to make so that we don't
473
+ # have to pass as many parameters around for logging.
474
+ context = RequestLogContext.new
475
+ context.account = headers["Stripe-Account"]
476
+ context.api_key = api_key
477
+ context.api_version = headers["Stripe-Version"]
478
+ context.body = body_log
479
+ context.idempotency_key = headers["Idempotency-Key"]
480
+ context.method = method
481
+ context.path = path
482
+ context.query = query
483
+
484
+ # A block can be passed in to read the content directly from the response.
485
+ # We want to execute this block only when the response was actually
486
+ # successful. When it wasn't, we defer to the standard error handling as
487
+ # we have to read the body and parse the error JSON.
488
+ response_block =
489
+ if block_given?
490
+ lambda do |response|
491
+ unless should_handle_as_error(response.code.to_i)
492
+ response.read_body(&read_body_chunk_block)
493
+ end
494
+ end
495
+ end
496
+
497
+ http_resp = execute_request_with_rescues(method, api_base, context) do
498
+ self.class
499
+ .default_connection_manager(config)
500
+ .execute_request(method, url,
501
+ body: body,
502
+ headers: headers,
503
+ query: query,
504
+ &response_block)
505
+ end
506
+
507
+ [http_resp, api_key]
508
+ end
509
+
454
510
  private def api_url(url = "", api_base = nil)
455
511
  (api_base || config.api_base) + url
456
512
  end
@@ -490,6 +546,7 @@ module Stripe
490
546
  # that's more condusive to logging.
491
547
  flattened_params =
492
548
  flattened_params.map { |k, v| [k, v.is_a?(String) ? v : v.to_s] }.to_h
549
+
493
550
  else
494
551
  body = Util.encode_parameters(body_params)
495
552
  end
@@ -503,6 +560,10 @@ module Stripe
503
560
  [body, body_log]
504
561
  end
505
562
 
563
+ private def should_handle_as_error(http_status)
564
+ http_status >= 400
565
+ end
566
+
506
567
  private def execute_request_with_rescues(method, api_base, context)
507
568
  num_retries = 0
508
569
 
@@ -520,7 +581,9 @@ module Stripe
520
581
  http_status = resp.code.to_i
521
582
  context = context.dup_from_response_headers(resp)
522
583
 
523
- handle_error_response(resp, context) if http_status >= 400
584
+ if should_handle_as_error(http_status)
585
+ handle_error_response(resp, context)
586
+ end
524
587
 
525
588
  log_response(context, request_start, http_status, resp.body)
526
589
  notify_request_end(context, request_duration, http_status,
@@ -1,63 +1,54 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Stripe
4
- # StripeResponse encapsulates some vitals of a response that came back from
5
- # the Stripe API.
6
- class StripeResponse
7
- # Headers provides an access wrapper to an API response's header data. It
8
- # mainly exists so that we don't need to expose the entire
9
- # `Net::HTTPResponse` object while still getting some of its benefits like
10
- # case-insensitive access to header names and flattening of header values.
11
- class Headers
12
- # Initializes a Headers object from a Net::HTTP::HTTPResponse object.
13
- def self.from_net_http(resp)
14
- new(resp.to_hash)
15
- end
4
+ # Headers provides an access wrapper to an API response's header data. It
5
+ # mainly exists so that we don't need to expose the entire
6
+ # `Net::HTTPResponse` object while still getting some of its benefits like
7
+ # case-insensitive access to header names and flattening of header values.
8
+ class StripeResponseHeaders
9
+ # Initializes a Headers object from a Net::HTTP::HTTPResponse object.
10
+ def self.from_net_http(resp)
11
+ new(resp.to_hash)
12
+ end
16
13
 
17
- # `hash` is expected to be a hash mapping header names to arrays of
18
- # header values. This is the default format generated by calling
19
- # `#to_hash` on a `Net::HTTPResponse` object because headers can be
20
- # repeated multiple times. Using `#[]` will collapse values down to just
21
- # the first.
22
- def initialize(hash)
23
- if !hash.is_a?(Hash) ||
24
- !hash.keys.all? { |n| n.is_a?(String) } ||
25
- !hash.values.all? { |a| a.is_a?(Array) } ||
26
- !hash.values.all? { |a| a.all? { |v| v.is_a?(String) } }
27
- raise ArgumentError,
28
- "expect hash to be a map of string header names to arrays of " \
29
- "header values"
30
- end
14
+ # `hash` is expected to be a hash mapping header names to arrays of
15
+ # header values. This is the default format generated by calling
16
+ # `#to_hash` on a `Net::HTTPResponse` object because headers can be
17
+ # repeated multiple times. Using `#[]` will collapse values down to just
18
+ # the first.
19
+ def initialize(hash)
20
+ if !hash.is_a?(Hash) ||
21
+ !hash.keys.all? { |n| n.is_a?(String) } ||
22
+ !hash.values.all? { |a| a.is_a?(Array) } ||
23
+ !hash.values.all? { |a| a.all? { |v| v.is_a?(String) } }
24
+ raise ArgumentError,
25
+ "expect hash to be a map of string header names to arrays of " \
26
+ "header values"
27
+ end
31
28
 
32
- @hash = {}
29
+ @hash = {}
33
30
 
34
- # This shouldn't be strictly necessary because `Net::HTTPResponse` will
35
- # produce a hash with all headers downcased, but do it anyway just in
36
- # case an object of this class was constructed manually.
37
- #
38
- # Also has the effect of duplicating the hash, which is desirable for a
39
- # little extra object safety.
40
- hash.each do |k, v|
41
- @hash[k.downcase] = v
42
- end
31
+ # This shouldn't be strictly necessary because `Net::HTTPResponse` will
32
+ # produce a hash with all headers downcased, but do it anyway just in
33
+ # case an object of this class was constructed manually.
34
+ #
35
+ # Also has the effect of duplicating the hash, which is desirable for a
36
+ # little extra object safety.
37
+ hash.each do |k, v|
38
+ @hash[k.downcase] = v
43
39
  end
40
+ end
44
41
 
45
- def [](name)
46
- values = @hash[name.downcase]
47
- if values && values.count > 1
48
- warn("Duplicate header values for `#{name}`; returning only first")
49
- end
50
- values ? values.first : nil
42
+ def [](name)
43
+ values = @hash[name.downcase]
44
+ if values && values.count > 1
45
+ warn("Duplicate header values for `#{name}`; returning only first")
51
46
  end
47
+ values ? values.first : nil
52
48
  end
49
+ end
53
50
 
54
- # The data contained by the HTTP body of the response deserialized from
55
- # JSON.
56
- attr_accessor :data
57
-
58
- # The raw HTTP body of the response.
59
- attr_accessor :http_body
60
-
51
+ module StripeResponseBase
61
52
  # A Hash of the HTTP headers of the response.
62
53
  attr_accessor :http_headers
63
54
 
@@ -67,15 +58,52 @@ module Stripe
67
58
  # The Stripe request ID of the response.
68
59
  attr_accessor :request_id
69
60
 
61
+ def self.populate_for_net_http(resp, http_resp)
62
+ resp.http_headers = StripeResponseHeaders.from_net_http(http_resp)
63
+ resp.http_status = http_resp.code.to_i
64
+ resp.request_id = http_resp["request-id"]
65
+ end
66
+ end
67
+
68
+ # StripeResponse encapsulates some vitals of a response that came back from
69
+ # the Stripe API.
70
+ class StripeResponse
71
+ include StripeResponseBase
72
+ # The data contained by the HTTP body of the response deserialized from
73
+ # JSON.
74
+ attr_accessor :data
75
+
76
+ # The raw HTTP body of the response.
77
+ attr_accessor :http_body
78
+
70
79
  # Initializes a StripeResponse object from a Net::HTTP::HTTPResponse
71
80
  # object.
72
81
  def self.from_net_http(http_resp)
73
82
  resp = StripeResponse.new
74
83
  resp.data = JSON.parse(http_resp.body, symbolize_names: true)
75
84
  resp.http_body = http_resp.body
76
- resp.http_headers = Headers.from_net_http(http_resp)
77
- resp.http_status = http_resp.code.to_i
78
- resp.request_id = http_resp["request-id"]
85
+ StripeResponseBase.populate_for_net_http(resp, http_resp)
86
+ resp
87
+ end
88
+ end
89
+
90
+ # We have to alias StripeResponseHeaders to StripeResponse::Headers, as this
91
+ # class used to be embedded within StripeResponse and we want to be backwards
92
+ # compatible.
93
+ StripeResponse::Headers = StripeResponseHeaders
94
+
95
+ # StripeHeadersOnlyResponse includes only header-related vitals of the
96
+ # response. This is used for streaming requests where the response was read
97
+ # directly in a block and we explicitly don't want to store the body of the
98
+ # response in memory.
99
+ class StripeHeadersOnlyResponse
100
+ include StripeResponseBase
101
+
102
+ # Initializes a StripeHeadersOnlyResponse object from a
103
+ # Net::HTTP::HTTPResponse object.
104
+ def self.from_net_http(http_resp)
105
+ resp = StripeHeadersOnlyResponse.new
106
+ StripeResponseBase.populate_for_net_http(resp, http_resp)
79
107
  resp
80
108
  end
81
109
  end
data/lib/stripe/util.rb CHANGED
@@ -208,7 +208,9 @@ module Stripe
208
208
  { api_key: opts }
209
209
  when Hash
210
210
  check_api_key!(opts.fetch(:api_key)) if opts.key?(:api_key)
211
- opts.clone
211
+ # Explicitly use dup here instead of clone to avoid preserving freeze
212
+ # state on input params.
213
+ opts.dup
212
214
  else
213
215
  raise TypeError, "normalize_opts expects a string or a hash"
214
216
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Stripe
4
- VERSION = "5.32.0"
4
+ VERSION = "5.36.0"
5
5
  end
data/stripe.gemspec CHANGED
@@ -27,14 +27,14 @@ Gem::Specification.new do |s|
27
27
  }
28
28
 
29
29
  ignored = Regexp.union(
30
- %r{\A\.editorconfig},
31
- %r{\A\.git},
32
- %r{\A\.rubocop},
33
- %r{\A\.travis.yml},
34
- %r{\A\.vscode},
35
- %r{\Atest/}
30
+ /\A\.editorconfig/,
31
+ /\A\.git/,
32
+ /\A\.rubocop/,
33
+ /\A\.travis.yml/,
34
+ /\A\.vscode/,
35
+ /\Atest/
36
36
  )
37
- s.files = `git ls-files`.split("\n").reject { |f| ignored.match?(f) }
37
+ s.files = `git ls-files`.split("\n").reject { |f| ignored.match(f) }
38
38
  s.executables = `git ls-files -- bin/*`.split("\n")
39
39
  .map { |f| ::File.basename(f) }
40
40
  s.require_paths = ["lib"]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stripe
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.32.0
4
+ version: 5.36.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stripe
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-04-05 00:00:00.000000000 Z
11
+ date: 2021-07-09 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Stripe is the easiest way to accept payments online. See https://stripe.com
14
14
  for details.
@@ -76,6 +76,8 @@ files:
76
76
  - lib/stripe/resources/exchange_rate.rb
77
77
  - lib/stripe/resources/file.rb
78
78
  - lib/stripe/resources/file_link.rb
79
+ - lib/stripe/resources/identity/verification_report.rb
80
+ - lib/stripe/resources/identity/verification_session.rb
79
81
  - lib/stripe/resources/invoice.rb
80
82
  - lib/stripe/resources/invoice_item.rb
81
83
  - lib/stripe/resources/invoice_line_item.rb
@@ -98,6 +100,7 @@ files:
98
100
  - lib/stripe/resources/price.rb
99
101
  - lib/stripe/resources/product.rb
100
102
  - lib/stripe/resources/promotion_code.rb
103
+ - lib/stripe/resources/quote.rb
101
104
  - lib/stripe/resources/radar/early_fraud_warning.rb
102
105
  - lib/stripe/resources/radar/value_list.rb
103
106
  - lib/stripe/resources/radar/value_list_item.rb
@@ -117,6 +120,7 @@ files:
117
120
  - lib/stripe/resources/subscription.rb
118
121
  - lib/stripe/resources/subscription_item.rb
119
122
  - lib/stripe/resources/subscription_schedule.rb
123
+ - lib/stripe/resources/tax_code.rb
120
124
  - lib/stripe/resources/tax_id.rb
121
125
  - lib/stripe/resources/tax_rate.rb
122
126
  - lib/stripe/resources/terminal/connection_token.rb
@@ -148,7 +152,7 @@ metadata:
148
152
  github_repo: ssh://github.com/stripe/stripe-ruby
149
153
  homepage_uri: https://stripe.com/docs/api/ruby
150
154
  source_code_uri: https://github.com/stripe/stripe-ruby
151
- post_install_message:
155
+ post_install_message:
152
156
  rdoc_options: []
153
157
  require_paths:
154
158
  - lib
@@ -164,7 +168,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
164
168
  version: '0'
165
169
  requirements: []
166
170
  rubygems_version: 3.1.2
167
- signing_key:
171
+ signing_key:
168
172
  specification_version: 4
169
173
  summary: Ruby bindings for the Stripe API
170
174
  test_files: []