stripe 4.24.0 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +17 -4
- data/.rubocop_todo.yml +10 -9
- data/.travis.yml +1 -5
- data/CHANGELOG.md +22 -0
- data/Gemfile +2 -12
- data/README.md +10 -10
- data/Rakefile +8 -7
- data/VERSION +1 -1
- data/lib/stripe.rb +56 -15
- data/lib/stripe/api_operations/list.rb +0 -6
- data/lib/stripe/connection_manager.rb +131 -0
- data/lib/stripe/error_object.rb +94 -0
- data/lib/stripe/errors.rb +15 -2
- data/lib/stripe/list_object.rb +2 -1
- data/lib/stripe/multipart_encoder.rb +131 -0
- data/lib/stripe/object_types.rb +0 -1
- data/lib/stripe/resources.rb +0 -1
- data/lib/stripe/resources/account.rb +1 -5
- data/lib/stripe/resources/account_link.rb +1 -1
- data/lib/stripe/resources/alipay_account.rb +1 -1
- data/lib/stripe/resources/apple_pay_domain.rb +1 -1
- data/lib/stripe/resources/application_fee.rb +1 -12
- data/lib/stripe/resources/application_fee_refund.rb +1 -1
- data/lib/stripe/resources/balance.rb +1 -1
- data/lib/stripe/resources/balance_transaction.rb +1 -1
- data/lib/stripe/resources/bank_account.rb +1 -1
- data/lib/stripe/resources/bitcoin_receiver.rb +1 -1
- data/lib/stripe/resources/bitcoin_transaction.rb +1 -1
- data/lib/stripe/resources/capability.rb +1 -1
- data/lib/stripe/resources/card.rb +1 -1
- data/lib/stripe/resources/charge.rb +7 -69
- data/lib/stripe/resources/checkout/session.rb +1 -1
- data/lib/stripe/resources/country_spec.rb +1 -1
- data/lib/stripe/resources/coupon.rb +1 -1
- data/lib/stripe/resources/credit_note.rb +1 -1
- data/lib/stripe/resources/customer.rb +3 -63
- data/lib/stripe/resources/customer_balance_transaction.rb +1 -1
- data/lib/stripe/resources/discount.rb +1 -1
- data/lib/stripe/resources/dispute.rb +1 -7
- data/lib/stripe/resources/ephemeral_key.rb +1 -1
- data/lib/stripe/resources/event.rb +1 -1
- data/lib/stripe/resources/exchange_rate.rb +1 -1
- data/lib/stripe/resources/file.rb +3 -13
- data/lib/stripe/resources/file_link.rb +1 -1
- data/lib/stripe/resources/invoice.rb +6 -1
- data/lib/stripe/resources/invoice_item.rb +1 -1
- data/lib/stripe/resources/invoice_line_item.rb +1 -1
- data/lib/stripe/resources/issuing/authorization.rb +1 -1
- data/lib/stripe/resources/issuing/card.rb +1 -1
- data/lib/stripe/resources/issuing/card_details.rb +1 -1
- data/lib/stripe/resources/issuing/cardholder.rb +1 -1
- data/lib/stripe/resources/issuing/dispute.rb +1 -1
- data/lib/stripe/resources/issuing/transaction.rb +1 -1
- data/lib/stripe/resources/login_link.rb +1 -1
- data/lib/stripe/resources/order.rb +1 -9
- data/lib/stripe/resources/order_return.rb +1 -1
- data/lib/stripe/resources/payment_intent.rb +1 -1
- data/lib/stripe/resources/payment_method.rb +1 -1
- data/lib/stripe/resources/payout.rb +1 -7
- data/lib/stripe/resources/person.rb +1 -1
- data/lib/stripe/resources/plan.rb +1 -1
- data/lib/stripe/resources/product.rb +1 -1
- data/lib/stripe/resources/radar/early_fraud_warning.rb +1 -1
- data/lib/stripe/resources/radar/value_list.rb +1 -1
- data/lib/stripe/resources/radar/value_list_item.rb +1 -1
- data/lib/stripe/resources/recipient.rb +1 -5
- data/lib/stripe/resources/recipient_transfer.rb +1 -1
- data/lib/stripe/resources/refund.rb +1 -1
- data/lib/stripe/resources/reporting/report_run.rb +1 -1
- data/lib/stripe/resources/reporting/report_type.rb +1 -1
- data/lib/stripe/resources/reversal.rb +1 -1
- data/lib/stripe/resources/review.rb +1 -1
- data/lib/stripe/resources/setup_intent.rb +1 -1
- data/lib/stripe/resources/sigma/scheduled_query_run.rb +1 -1
- data/lib/stripe/resources/sku.rb +1 -1
- data/lib/stripe/resources/source.rb +1 -7
- data/lib/stripe/resources/source_transaction.rb +1 -1
- data/lib/stripe/resources/subscription.rb +9 -9
- data/lib/stripe/resources/subscription_item.rb +1 -1
- data/lib/stripe/resources/subscription_schedule.rb +1 -1
- data/lib/stripe/resources/tax_id.rb +1 -1
- data/lib/stripe/resources/tax_rate.rb +1 -1
- data/lib/stripe/resources/terminal/connection_token.rb +1 -1
- data/lib/stripe/resources/terminal/location.rb +1 -1
- data/lib/stripe/resources/terminal/reader.rb +1 -1
- data/lib/stripe/resources/three_d_secure.rb +1 -1
- data/lib/stripe/resources/token.rb +1 -1
- data/lib/stripe/resources/topup.rb +1 -1
- data/lib/stripe/resources/transfer.rb +1 -6
- data/lib/stripe/resources/usage_record.rb +1 -17
- data/lib/stripe/resources/usage_record_summary.rb +1 -1
- data/lib/stripe/resources/webhook_endpoint.rb +1 -1
- data/lib/stripe/stripe_client.rb +281 -183
- data/lib/stripe/stripe_object.rb +4 -23
- data/lib/stripe/stripe_response.rb +53 -21
- data/lib/stripe/util.rb +10 -11
- data/lib/stripe/version.rb +1 -1
- data/lib/stripe/webhook.rb +1 -1
- data/stripe.gemspec +6 -9
- data/test/stripe/account_test.rb +0 -16
- data/test/stripe/api_operations_test.rb +2 -2
- data/test/stripe/api_resource_test.rb +2 -10
- data/test/stripe/charge_test.rb +0 -16
- data/test/stripe/connection_manager_test.rb +138 -0
- data/test/stripe/customer_test.rb +1 -44
- data/test/stripe/errors_test.rb +29 -8
- data/test/stripe/file_test.rb +0 -10
- data/test/stripe/invoice_test.rb +17 -1
- data/test/stripe/list_object_test.rb +0 -16
- data/test/stripe/login_link_test.rb +1 -1
- data/test/stripe/multipart_encoder_test.rb +130 -0
- data/test/stripe/payment_intent_test.rb +1 -1
- data/test/stripe/setup_intent_test.rb +1 -1
- data/test/stripe/source_test.rb +0 -18
- data/test/stripe/stripe_client_test.rb +214 -29
- data/test/stripe/stripe_object_test.rb +7 -35
- data/test/stripe/stripe_response_test.rb +70 -24
- data/test/stripe/subscription_test.rb +2 -2
- data/test/stripe/webhook_test.rb +2 -2
- data/test/stripe_mock.rb +4 -3
- data/test/stripe_test.rb +0 -13
- data/test/test_helper.rb +10 -5
- metadata +11 -39
- data/lib/stripe/resources/issuer_fraud_record.rb +0 -9
- data/test/stripe/file_upload_test.rb +0 -79
- data/test/stripe/issuer_fraud_record_test.rb +0 -20
- data/test/stripe/usage_record_test.rb +0 -28
@@ -0,0 +1,94 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Stripe
|
4
|
+
# Represents an error object as returned by the API.
|
5
|
+
#
|
6
|
+
# @see https://stripe.com/docs/api/errors
|
7
|
+
class ErrorObject < StripeObject
|
8
|
+
# Unlike other objects, we explicitly declare getter methods here. This
|
9
|
+
# is because the API doesn't return `null` values for fields on this
|
10
|
+
# object, rather the fields are omitted entirely. Not declaring the getter
|
11
|
+
# methods would cause users to run into `NoMethodError` exceptions and
|
12
|
+
# get in the way of generic error handling.
|
13
|
+
|
14
|
+
# For card errors, the ID of the failed charge.
|
15
|
+
def charge
|
16
|
+
@values[:charge]
|
17
|
+
end
|
18
|
+
|
19
|
+
# For some errors that could be handled programmatically, a short string
|
20
|
+
# indicating the error code reported.
|
21
|
+
def code
|
22
|
+
@values[:code]
|
23
|
+
end
|
24
|
+
|
25
|
+
# For card errors resulting from a card issuer decline, a short string
|
26
|
+
# indicating the card issuer's reason for the decline if they provide one.
|
27
|
+
def decline_code
|
28
|
+
@values[:decline_code]
|
29
|
+
end
|
30
|
+
|
31
|
+
# A URL to more information about the error code reported.
|
32
|
+
def doc_url
|
33
|
+
@values[:doc_url]
|
34
|
+
end
|
35
|
+
|
36
|
+
# A human-readable message providing more details about the error. For card
|
37
|
+
# errors, these messages can be shown to your users.
|
38
|
+
def message
|
39
|
+
@values[:message]
|
40
|
+
end
|
41
|
+
|
42
|
+
# If the error is parameter-specific, the parameter related to the error.
|
43
|
+
# For example, you can use this to display a message near the correct form
|
44
|
+
# field.
|
45
|
+
def param
|
46
|
+
@values[:param]
|
47
|
+
end
|
48
|
+
|
49
|
+
# The PaymentIntent object for errors returned on a request involving a
|
50
|
+
# PaymentIntent.
|
51
|
+
def payment_intent
|
52
|
+
@values[:payment_intent]
|
53
|
+
end
|
54
|
+
|
55
|
+
# The PaymentMethod object for errors returned on a request involving a
|
56
|
+
# PaymentMethod.
|
57
|
+
def payment_method
|
58
|
+
@values[:payment_method]
|
59
|
+
end
|
60
|
+
|
61
|
+
# The SetupIntent object for errors returned on a request involving a
|
62
|
+
# SetupIntent.
|
63
|
+
def setup_intent
|
64
|
+
@values[:setup_intent]
|
65
|
+
end
|
66
|
+
|
67
|
+
# The source object for errors returned on a request involving a source.
|
68
|
+
def source
|
69
|
+
@values[:source]
|
70
|
+
end
|
71
|
+
|
72
|
+
# The type of error returned. One of `api_connection_error`, `api_error`,
|
73
|
+
# `authentication_error`, `card_error`, `idempotency_error`,
|
74
|
+
# `invalid_request_error`, or `rate_limit_error`.
|
75
|
+
def type
|
76
|
+
@values[:type]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Represents on OAuth error returned by the OAuth API.
|
81
|
+
#
|
82
|
+
# @see https://stripe.com/docs/connect/oauth-reference#post-token-errors
|
83
|
+
class OAuthErrorObject < StripeObject
|
84
|
+
# A unique error code per error type.
|
85
|
+
def error
|
86
|
+
@values[:error]
|
87
|
+
end
|
88
|
+
|
89
|
+
# A human readable description of the error.
|
90
|
+
def error_description
|
91
|
+
@values[:error_description]
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
data/lib/stripe/errors.rb
CHANGED
@@ -11,6 +11,7 @@ module Stripe
|
|
11
11
|
attr_accessor :response
|
12
12
|
|
13
13
|
attr_reader :code
|
14
|
+
attr_reader :error
|
14
15
|
attr_reader :http_body
|
15
16
|
attr_reader :http_headers
|
16
17
|
attr_reader :http_status
|
@@ -27,6 +28,13 @@ module Stripe
|
|
27
28
|
@json_body = json_body
|
28
29
|
@code = code
|
29
30
|
@request_id = @http_headers[:request_id]
|
31
|
+
@error = construct_error_object
|
32
|
+
end
|
33
|
+
|
34
|
+
def construct_error_object
|
35
|
+
return nil if @json_body.nil? || !@json_body.key?(:error)
|
36
|
+
|
37
|
+
ErrorObject.construct_from(@json_body[:error])
|
30
38
|
end
|
31
39
|
|
32
40
|
def to_s
|
@@ -59,8 +67,7 @@ module Stripe
|
|
59
67
|
class CardError < StripeError
|
60
68
|
attr_reader :param
|
61
69
|
|
62
|
-
|
63
|
-
def initialize(message, param, code, http_status: nil, http_body: nil,
|
70
|
+
def initialize(message, param, code: nil, http_status: nil, http_body: nil,
|
64
71
|
json_body: nil, http_headers: nil)
|
65
72
|
super(message, http_status: http_status, http_body: http_body,
|
66
73
|
json_body: json_body, http_headers: http_headers,
|
@@ -119,6 +126,12 @@ module Stripe
|
|
119
126
|
json_body: json_body, http_headers: http_headers,
|
120
127
|
code: code)
|
121
128
|
end
|
129
|
+
|
130
|
+
def construct_error_object
|
131
|
+
return nil if @json_body.nil?
|
132
|
+
|
133
|
+
OAuthErrorObject.construct_from(@json_body)
|
134
|
+
end
|
122
135
|
end
|
123
136
|
|
124
137
|
# InvalidClientError is raised when the client doesn't belong to you, or
|
data/lib/stripe/list_object.rb
CHANGED
@@ -7,7 +7,7 @@ module Stripe
|
|
7
7
|
include Stripe::APIOperations::Request
|
8
8
|
include Stripe::APIOperations::Create
|
9
9
|
|
10
|
-
OBJECT_NAME = "list"
|
10
|
+
OBJECT_NAME = "list"
|
11
11
|
|
12
12
|
# This accessor allows a `ListObject` to inherit various filters that were
|
13
13
|
# given to a predecessor. This allows for things like consistent limits,
|
@@ -83,6 +83,7 @@ module Stripe
|
|
83
83
|
# was given, the default limit will be fetched again.
|
84
84
|
def next_page(params = {}, opts = {})
|
85
85
|
return self.class.empty_list(opts) unless has_more
|
86
|
+
|
86
87
|
last_id = data.last.id
|
87
88
|
|
88
89
|
params = filters.merge(starting_after: last_id).merge(params)
|
@@ -0,0 +1,131 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "securerandom"
|
4
|
+
require "tempfile"
|
5
|
+
|
6
|
+
module Stripe
|
7
|
+
# Encodes parameters into a `multipart/form-data` payload as described by RFC
|
8
|
+
# 2388:
|
9
|
+
#
|
10
|
+
# https://tools.ietf.org/html/rfc2388
|
11
|
+
#
|
12
|
+
# This is most useful for transferring file-like objects.
|
13
|
+
#
|
14
|
+
# Parameters should be added with `#encode`. When ready, use `#body` to get
|
15
|
+
# the encoded result and `#content_type` to get the value that should be
|
16
|
+
# placed in the `Content-Type` header of a subsequent request (which includes
|
17
|
+
# a boundary value).
|
18
|
+
class MultipartEncoder
|
19
|
+
MULTIPART_FORM_DATA = "multipart/form-data"
|
20
|
+
|
21
|
+
# A shortcut for encoding a single set of parameters and finalizing a
|
22
|
+
# result.
|
23
|
+
#
|
24
|
+
# Returns an encoded body and the value that should be set in the content
|
25
|
+
# type header of a subsequent request.
|
26
|
+
def self.encode(params)
|
27
|
+
encoder = MultipartEncoder.new
|
28
|
+
encoder.encode(params)
|
29
|
+
encoder.close
|
30
|
+
[encoder.body, encoder.content_type]
|
31
|
+
end
|
32
|
+
|
33
|
+
# Gets the object's randomly generated boundary string.
|
34
|
+
attr_reader :boundary
|
35
|
+
|
36
|
+
# Initializes a new multipart encoder.
|
37
|
+
def initialize
|
38
|
+
# Kind of weird, but required by Rubocop because the unary plus operator
|
39
|
+
# is considered faster than `Stripe.new`.
|
40
|
+
@body = +""
|
41
|
+
|
42
|
+
# Chose the same number of random bytes that Go uses in its standard
|
43
|
+
# library implementation. Easily enough entropy to ensure that it won't
|
44
|
+
# be present in a file we're sending.
|
45
|
+
@boundary = SecureRandom.hex(30)
|
46
|
+
|
47
|
+
@closed = false
|
48
|
+
@first_field = true
|
49
|
+
end
|
50
|
+
|
51
|
+
# Gets the encoded body. `#close` must be called first.
|
52
|
+
def body
|
53
|
+
raise "object must be closed before getting body" unless @closed
|
54
|
+
|
55
|
+
@body
|
56
|
+
end
|
57
|
+
|
58
|
+
# Finalizes the object by writing the final boundary.
|
59
|
+
def close
|
60
|
+
raise "object already closed" if @closed
|
61
|
+
|
62
|
+
@body << "\r\n"
|
63
|
+
@body << "--#{@boundary}--"
|
64
|
+
|
65
|
+
@closed = true
|
66
|
+
|
67
|
+
nil
|
68
|
+
end
|
69
|
+
|
70
|
+
# Gets the value including boundary that should be put into a multipart
|
71
|
+
# request's `Content-Type`.
|
72
|
+
def content_type
|
73
|
+
"#{MULTIPART_FORM_DATA}; boundary=#{@boundary}"
|
74
|
+
end
|
75
|
+
|
76
|
+
# Encodes a set of parameters to the body.
|
77
|
+
#
|
78
|
+
# Note that parameters are expected to be a hash, but a "flat" hash such
|
79
|
+
# that complex substructures like hashes and arrays have already been
|
80
|
+
# appropriately Stripe-encoded. Pass a complex structure through
|
81
|
+
# `Util.flatten_params` first before handing it off to this method.
|
82
|
+
def encode(params)
|
83
|
+
raise "no more parameters can be written to closed object" if @closed
|
84
|
+
|
85
|
+
params.each do |name, val|
|
86
|
+
if val.is_a?(::File) || val.is_a?(::Tempfile)
|
87
|
+
write_field(name, val.read, filename: ::File.basename(val.path))
|
88
|
+
elsif val.respond_to?(:read)
|
89
|
+
write_field(name, val.read, filename: "blob")
|
90
|
+
else
|
91
|
+
write_field(name, val, filename: nil)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
nil
|
96
|
+
end
|
97
|
+
|
98
|
+
#
|
99
|
+
# private
|
100
|
+
#
|
101
|
+
|
102
|
+
# Escapes double quotes so that the given value can be used in a
|
103
|
+
# double-quoted string and replaces any linebreak characters with spaces.
|
104
|
+
private def escape(str)
|
105
|
+
str.gsub('"', "%22").tr("\n", " ").tr("\r", " ")
|
106
|
+
end
|
107
|
+
|
108
|
+
private def write_field(name, data, filename:)
|
109
|
+
if !@first_field
|
110
|
+
@body << "\r\n"
|
111
|
+
else
|
112
|
+
@first_field = false
|
113
|
+
end
|
114
|
+
|
115
|
+
@body << "--#{@boundary}\r\n"
|
116
|
+
|
117
|
+
if filename
|
118
|
+
@body << %(Content-Disposition: form-data) +
|
119
|
+
%(; name="#{escape(name.to_s)}") +
|
120
|
+
%(; filename="#{escape(filename)}"\r\n)
|
121
|
+
@body << %(Content-Type: application/octet-stream\r\n)
|
122
|
+
else
|
123
|
+
@body << %(Content-Disposition: form-data) +
|
124
|
+
%(; name="#{escape(name.to_s)}"\r\n)
|
125
|
+
end
|
126
|
+
|
127
|
+
@body << "\r\n"
|
128
|
+
@body << data.to_s
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
data/lib/stripe/object_types.rb
CHANGED
@@ -41,7 +41,6 @@ module Stripe
|
|
41
41
|
Invoice::OBJECT_NAME => Invoice,
|
42
42
|
InvoiceItem::OBJECT_NAME => InvoiceItem,
|
43
43
|
InvoiceLineItem::OBJECT_NAME => InvoiceLineItem,
|
44
|
-
IssuerFraudRecord::OBJECT_NAME => IssuerFraudRecord,
|
45
44
|
Issuing::Authorization::OBJECT_NAME => Issuing::Authorization,
|
46
45
|
Issuing::Card::OBJECT_NAME => Issuing::Card,
|
47
46
|
Issuing::CardDetails::OBJECT_NAME => Issuing::CardDetails,
|
data/lib/stripe/resources.rb
CHANGED
@@ -30,7 +30,6 @@ require "stripe/resources/file_link"
|
|
30
30
|
require "stripe/resources/invoice"
|
31
31
|
require "stripe/resources/invoice_item"
|
32
32
|
require "stripe/resources/invoice_line_item"
|
33
|
-
require "stripe/resources/issuer_fraud_record"
|
34
33
|
require "stripe/resources/issuing/authorization"
|
35
34
|
require "stripe/resources/issuing/card"
|
36
35
|
require "stripe/resources/issuing/card_details"
|
@@ -9,7 +9,7 @@ module Stripe
|
|
9
9
|
include Stripe::APIOperations::Save
|
10
10
|
extend Stripe::APIOperations::NestedResource
|
11
11
|
|
12
|
-
OBJECT_NAME = "account"
|
12
|
+
OBJECT_NAME = "account"
|
13
13
|
|
14
14
|
custom_method :reject, http_verb: :post
|
15
15
|
|
@@ -35,10 +35,6 @@ module Stripe
|
|
35
35
|
|
36
36
|
nested_resource_class_methods :login_link, operations: %i[create]
|
37
37
|
|
38
|
-
# This method is deprecated. Please use `#external_account=` instead.
|
39
|
-
save_nested_resource :bank_account
|
40
|
-
deprecate :bank_account=, "#external_account=", 2017, 8
|
41
|
-
|
42
38
|
def resource_url
|
43
39
|
if self["id"]
|
44
40
|
super
|
@@ -5,20 +5,9 @@ module Stripe
|
|
5
5
|
extend Stripe::APIOperations::List
|
6
6
|
extend Stripe::APIOperations::NestedResource
|
7
7
|
|
8
|
-
OBJECT_NAME = "application_fee"
|
8
|
+
OBJECT_NAME = "application_fee"
|
9
9
|
|
10
10
|
nested_resource_class_methods :refund,
|
11
11
|
operations: %i[create retrieve update list]
|
12
|
-
|
13
|
-
# If you don't need access to an updated fee object after the refund, it's
|
14
|
-
# more performant to just call `fee.refunds.create` directly.
|
15
|
-
def refund(params = {}, opts = {})
|
16
|
-
refunds.create(params, opts)
|
17
|
-
|
18
|
-
# now that a refund has been created, we expect the state of this object
|
19
|
-
# to change as well (i.e. `refunded` will now be `true`) so refresh it
|
20
|
-
# from the server
|
21
|
-
refresh
|
22
|
-
end
|
23
12
|
end
|
24
13
|
end
|
@@ -6,7 +6,7 @@ module Stripe
|
|
6
6
|
extend Stripe::APIOperations::List
|
7
7
|
include Stripe::APIOperations::Save
|
8
8
|
|
9
|
-
OBJECT_NAME = "bank_account"
|
9
|
+
OBJECT_NAME = "bank_account"
|
10
10
|
|
11
11
|
def verify(params = {}, opts = {})
|
12
12
|
resp, opts = request(:post, resource_url + "/verify", params, opts)
|