stripe 5.34.0 → 5.35.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/VERSION +1 -1
- data/lib/stripe/api_operations/request.rb +35 -2
- data/lib/stripe/api_resource.rb +8 -0
- data/lib/stripe/connection_manager.rb +17 -2
- data/lib/stripe/stripe_client.rb +120 -57
- data/lib/stripe/stripe_response.rb +80 -52
- data/lib/stripe/util.rb +3 -1
- data/lib/stripe/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f51ef2fd825e626807098544261c034bf55a84cf59852a7ac1c88a213add62ca
|
4
|
+
data.tar.gz: 6df0829f6b372f47393a5a22cc8aba022c40620188c0e8c3619d41965d84837b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1d0c7c97de7a70c94ebd08659f6a0630f3508347772d2ed7a799778f2c08db2e6a1540a9b77b377f31edeadc6d5a874da4e084994c8ce23e4690512db083c987
|
7
|
+
data.tar.gz: 180af07a05467d75b0a88907bf59a0f837981ab4cd6ca16673ec4f17bedcff33e7efcf80ff482cd14517b9a2efa25095ce018011fc82b70d62a20bddc1cd2525
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 5.35.0 - 2021-06-30
|
4
|
+
* [#985](https://github.com/stripe/stripe-ruby/pull/985) Update normalize_opts to use dup instead of clone.
|
5
|
+
* [#982](https://github.com/stripe/stripe-ruby/pull/982) Deprecate travis
|
6
|
+
* [#983](https://github.com/stripe/stripe-ruby/pull/983) Add support for making a request and receiving the response as a stream.
|
7
|
+
|
3
8
|
## 5.34.0 - 2021-06-04
|
4
9
|
* [#981](https://github.com/stripe/stripe-ruby/pull/981) API Updates
|
5
10
|
* Add support for `TaxCode` API.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
5.
|
1
|
+
5.35.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.
|
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
|
data/lib/stripe/api_resource.rb
CHANGED
@@ -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
|
-
|
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
|
|
data/lib/stripe/stripe_client.rb
CHANGED
@@ -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
|
-
|
217
|
-
|
218
|
-
|
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
|
-
|
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
|
-
#
|
5
|
-
# the
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
#
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
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
|
-
|
29
|
+
@hash = {}
|
33
30
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
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
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
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
|
-
|
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
|
77
|
-
resp
|
78
|
-
|
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
|
-
|
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
|
data/lib/stripe/version.rb
CHANGED
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.
|
4
|
+
version: 5.35.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stripe
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-06-
|
11
|
+
date: 2021-06-30 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.
|