stripe 4.9.0 → 5.1.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/.editorconfig +10 -0
- data/.rubocop.yml +28 -4
- data/.rubocop_todo.yml +11 -22
- data/.travis.yml +3 -6
- data/.vscode/extensions.json +7 -0
- data/.vscode/settings.json +8 -0
- data/CHANGELOG.md +102 -2
- data/Gemfile +2 -10
- data/README.md +96 -40
- data/Rakefile +8 -7
- data/VERSION +1 -1
- data/lib/stripe.rb +64 -85
- data/lib/stripe/api_operations/delete.rb +23 -1
- data/lib/stripe/api_operations/list.rb +0 -6
- data/lib/stripe/api_operations/nested_resource.rb +14 -7
- data/lib/stripe/api_operations/request.rb +3 -7
- data/lib/stripe/api_operations/save.rb +1 -3
- data/lib/stripe/api_resource.rb +50 -2
- data/lib/stripe/connection_manager.rb +141 -0
- data/lib/stripe/error_object.rb +94 -0
- data/lib/stripe/errors.rb +22 -9
- data/lib/stripe/list_object.rb +11 -5
- data/lib/stripe/multipart_encoder.rb +131 -0
- data/lib/stripe/object_types.rb +94 -0
- data/lib/stripe/resources.rb +77 -0
- data/lib/stripe/{account.rb → resources/account.rb} +49 -27
- data/lib/stripe/{account_link.rb → resources/account_link.rb} +1 -1
- data/lib/stripe/resources/alipay_account.rb +34 -0
- data/lib/stripe/{apple_pay_domain.rb → resources/apple_pay_domain.rb} +1 -1
- data/lib/stripe/resources/application_fee.rb +13 -0
- data/lib/stripe/resources/application_fee_refund.rb +30 -0
- data/lib/stripe/{balance.rb → resources/balance.rb} +1 -1
- data/lib/stripe/{balance_transaction.rb → resources/balance_transaction.rb} +1 -5
- data/lib/stripe/{bank_account.rb → resources/bank_account.rb} +14 -4
- data/lib/stripe/{bitcoin_receiver.rb → resources/bitcoin_receiver.rb} +3 -3
- data/lib/stripe/{bitcoin_transaction.rb → resources/bitcoin_transaction.rb} +1 -1
- data/lib/stripe/resources/capability.rb +33 -0
- data/lib/stripe/{card.rb → resources/card.rb} +12 -4
- data/lib/stripe/resources/charge.rb +22 -0
- data/lib/stripe/{checkout → resources/checkout}/session.rb +2 -2
- data/lib/stripe/{country_spec.rb → resources/country_spec.rb} +1 -1
- data/lib/stripe/{coupon.rb → resources/coupon.rb} +2 -2
- data/lib/stripe/resources/credit_note.rb +22 -0
- data/lib/stripe/resources/customer.rb +35 -0
- data/lib/stripe/resources/customer_balance_transaction.rb +30 -0
- data/lib/stripe/resources/discount.rb +7 -0
- data/lib/stripe/{dispute.rb → resources/dispute.rb} +9 -7
- data/lib/stripe/{ephemeral_key.rb → resources/ephemeral_key.rb} +5 -2
- data/lib/stripe/{event.rb → resources/event.rb} +1 -1
- data/lib/stripe/{exchange_rate.rb → resources/exchange_rate.rb} +1 -1
- data/lib/stripe/{file.rb → resources/file.rb} +8 -11
- data/lib/stripe/{file_link.rb → resources/file_link.rb} +2 -2
- data/lib/stripe/resources/invoice.rb +73 -0
- data/lib/stripe/{invoice_item.rb → resources/invoice_item.rb} +2 -2
- data/lib/stripe/{invoice_line_item.rb → resources/invoice_line_item.rb} +1 -1
- data/lib/stripe/resources/issuing/authorization.rb +33 -0
- data/lib/stripe/resources/issuing/card.rb +24 -0
- data/lib/stripe/{issuing → resources/issuing}/card_details.rb +1 -1
- data/lib/stripe/{issuing → resources/issuing}/cardholder.rb +2 -2
- data/lib/stripe/{issuing → resources/issuing}/dispute.rb +2 -2
- data/lib/stripe/{issuing → resources/issuing}/transaction.rb +2 -2
- data/lib/stripe/resources/login_link.rb +14 -0
- data/lib/stripe/resources/order.rb +32 -0
- data/lib/stripe/{order_return.rb → resources/order_return.rb} +1 -1
- data/lib/stripe/resources/payment_intent.rb +42 -0
- data/lib/stripe/resources/payment_method.rb +32 -0
- data/lib/stripe/resources/payout.rb +22 -0
- data/lib/stripe/{person.rb → resources/person.rb} +8 -3
- data/lib/stripe/{plan.rb → resources/plan.rb} +1 -1
- data/lib/stripe/{product.rb → resources/product.rb} +3 -3
- data/lib/stripe/resources/radar/early_fraud_warning.rb +11 -0
- data/lib/stripe/{radar → resources/radar}/value_list.rb +2 -2
- data/lib/stripe/{radar → resources/radar}/value_list_item.rb +2 -2
- data/lib/stripe/{recipient.rb → resources/recipient.rb} +2 -6
- data/lib/stripe/{recipient_transfer.rb → resources/recipient_transfer.rb} +1 -1
- data/lib/stripe/{refund.rb → resources/refund.rb} +1 -1
- data/lib/stripe/{reporting → resources/reporting}/report_run.rb +2 -2
- data/lib/stripe/{reporting → resources/reporting}/report_type.rb +2 -2
- data/lib/stripe/resources/reversal.rb +29 -0
- data/lib/stripe/resources/review.rb +20 -0
- data/lib/stripe/resources/setup_intent.rb +32 -0
- data/lib/stripe/{sigma → resources/sigma}/scheduled_query_run.rb +2 -2
- data/lib/stripe/{sku.rb → resources/sku.rb} +3 -3
- data/lib/stripe/{source.rb → resources/source.rb} +17 -15
- data/lib/stripe/{source_transaction.rb → resources/source_transaction.rb} +1 -1
- data/lib/stripe/resources/subscription.rb +25 -0
- data/lib/stripe/{subscription_item.rb → resources/subscription_item.rb} +5 -2
- data/lib/stripe/resources/subscription_schedule.rb +32 -0
- data/lib/stripe/resources/tax_id.rb +26 -0
- data/lib/stripe/resources/tax_rate.rb +11 -0
- data/lib/stripe/{terminal → resources/terminal}/connection_token.rb +2 -2
- data/lib/stripe/{terminal → resources/terminal}/location.rb +3 -2
- data/lib/stripe/{terminal → resources/terminal}/reader.rb +3 -2
- data/lib/stripe/{three_d_secure.rb → resources/three_d_secure.rb} +1 -1
- data/lib/stripe/{token.rb → resources/token.rb} +1 -1
- data/lib/stripe/resources/topup.rb +22 -0
- data/lib/stripe/resources/transfer.rb +26 -0
- data/lib/stripe/resources/usage_record.rb +7 -0
- data/lib/stripe/{usage_record_summary.rb → resources/usage_record_summary.rb} +1 -1
- data/lib/stripe/{webhook_endpoint.rb → resources/webhook_endpoint.rb} +2 -2
- data/lib/stripe/singleton_api_resource.rb +3 -1
- data/lib/stripe/stripe_client.rb +347 -218
- data/lib/stripe/stripe_object.rb +72 -59
- data/lib/stripe/stripe_response.rb +53 -21
- data/lib/stripe/util.rb +54 -109
- data/lib/stripe/version.rb +1 -1
- data/lib/stripe/webhook.rb +5 -3
- data/stripe.gemspec +14 -5
- data/test/stripe/account_link_test.rb +1 -1
- data/test/stripe/account_test.rb +193 -32
- data/test/stripe/alipay_account_test.rb +1 -1
- data/test/stripe/api_operations_test.rb +3 -4
- data/test/stripe/api_resource_test.rb +119 -30
- data/test/stripe/apple_pay_domain_test.rb +18 -5
- data/test/stripe/application_fee_refund_test.rb +1 -1
- data/test/stripe/application_fee_test.rb +45 -1
- data/test/stripe/balance_test.rb +1 -1
- data/test/stripe/balance_transaction_test.rb +20 -0
- data/test/stripe/bank_account_test.rb +1 -1
- data/test/stripe/capability_test.rb +45 -0
- data/test/stripe/charge_test.rb +13 -8
- data/test/stripe/checkout/session_test.rb +7 -1
- data/test/stripe/connection_manager_test.rb +138 -0
- data/test/stripe/country_spec_test.rb +1 -1
- data/test/stripe/coupon_test.rb +16 -6
- data/test/stripe/credit_note_test.rb +61 -0
- data/test/stripe/customer_balance_transaction_test.rb +37 -0
- data/test/stripe/customer_card_test.rb +1 -1
- data/test/stripe/customer_test.rb +151 -40
- data/test/stripe/dispute_test.rb +10 -1
- data/test/stripe/ephemeral_key_test.rb +8 -1
- data/test/stripe/errors_test.rb +30 -9
- data/test/stripe/exchange_rate_test.rb +1 -1
- data/test/stripe/file_link_test.rb +1 -1
- data/test/stripe/file_test.rb +19 -5
- data/test/stripe/invoice_item_test.rb +18 -7
- data/test/stripe/invoice_line_item_test.rb +1 -1
- data/test/stripe/invoice_test.rb +77 -9
- data/test/stripe/issuing/authorization_test.rb +33 -11
- data/test/stripe/issuing/card_test.rb +15 -6
- data/test/stripe/issuing/cardholder_test.rb +1 -1
- data/test/stripe/issuing/dispute_test.rb +1 -1
- data/test/stripe/issuing/transaction_test.rb +1 -1
- data/test/stripe/list_object_test.rb +1 -17
- data/test/stripe/login_link_test.rb +2 -2
- data/test/stripe/multipart_encoder_test.rb +130 -0
- data/test/stripe/oauth_test.rb +1 -1
- data/test/stripe/order_return_test.rb +1 -1
- data/test/stripe/order_test.rb +28 -3
- data/test/stripe/payment_intent_test.rb +31 -4
- data/test/stripe/payment_method_test.rb +84 -0
- data/test/stripe/payout_test.rb +8 -1
- data/test/stripe/person_test.rb +1 -1
- data/test/stripe/plan_test.rb +26 -20
- data/test/stripe/product_test.rb +16 -6
- data/test/stripe/radar/early_fraud_warning_test.rb +22 -0
- data/test/stripe/radar/value_list_item_test.rb +16 -6
- data/test/stripe/radar/value_list_test.rb +16 -6
- data/test/stripe/recipient_test.rb +18 -5
- data/test/stripe/refund_test.rb +1 -1
- data/test/stripe/reporting/report_run_test.rb +1 -1
- data/test/stripe/reporting/report_type_test.rb +1 -1
- data/test/stripe/reversal_test.rb +1 -1
- data/test/stripe/review_test.rb +1 -1
- data/test/stripe/setup_intent_test.rb +84 -0
- data/test/stripe/sigma/scheduled_query_run_test.rb +1 -1
- data/test/stripe/sku_test.rb +16 -6
- data/test/stripe/source_test.rb +14 -19
- data/test/stripe/source_transaction_test.rb +1 -1
- data/test/stripe/stripe_client_test.rb +242 -26
- data/test/stripe/stripe_object_test.rb +8 -36
- data/test/stripe/stripe_response_test.rb +71 -25
- data/test/stripe/subscription_item_test.rb +28 -6
- data/test/stripe/subscription_schedule_test.rb +19 -1
- data/test/stripe/subscription_test.rb +29 -9
- data/test/stripe/tax_id_test.rb +31 -0
- data/test/stripe/tax_rate_test.rb +43 -0
- data/test/stripe/terminal/connection_token_test.rb +1 -1
- data/test/stripe/terminal/location_test.rb +18 -1
- data/test/stripe/terminal/reader_test.rb +18 -1
- data/test/stripe/three_d_secure_test.rb +1 -1
- data/test/stripe/topup_test.rb +9 -1
- data/test/stripe/transfer_test.rb +46 -1
- data/test/stripe/usage_record_summary_test.rb +1 -1
- data/test/stripe/util_test.rb +1 -1
- data/test/stripe/webhook_endpoint_test.rb +18 -1
- data/test/stripe/webhook_test.rb +4 -4
- data/test/stripe_mock.rb +4 -3
- data/test/stripe_test.rb +1 -14
- data/test/test_helper.rb +14 -11
- metadata +117 -125
- data/lib/stripe/alipay_account.rb +0 -27
- data/lib/stripe/application_fee.rb +0 -23
- data/lib/stripe/application_fee_refund.rb +0 -22
- data/lib/stripe/charge.rb +0 -84
- data/lib/stripe/customer.rb +0 -90
- data/lib/stripe/invoice.rb +0 -48
- data/lib/stripe/issuer_fraud_record.rb +0 -9
- data/lib/stripe/issuing/authorization.rb +0 -22
- data/lib/stripe/issuing/card.rb +0 -18
- data/lib/stripe/login_link.rb +0 -11
- data/lib/stripe/order.rb +0 -31
- data/lib/stripe/payment_intent.rb +0 -26
- data/lib/stripe/payout.rb +0 -20
- data/lib/stripe/reversal.rb +0 -22
- data/lib/stripe/review.rb +0 -14
- data/lib/stripe/subscription.rb +0 -25
- data/lib/stripe/subscription_schedule.rb +0 -32
- data/lib/stripe/subscription_schedule_revision.rb +0 -25
- data/lib/stripe/topup.rb +0 -16
- data/lib/stripe/transfer.rb +0 -23
- data/lib/stripe/usage_record.rb +0 -14
- data/test/stripe/account_external_accounts_operations_test.rb +0 -69
- data/test/stripe/account_login_links_operations_test.rb +0 -21
- data/test/stripe/account_persons_operations_test.rb +0 -70
- data/test/stripe/application_fee_refunds_operations_test.rb +0 -56
- data/test/stripe/customer_sources_operations_test.rb +0 -64
- data/test/stripe/file_upload_test.rb +0 -76
- data/test/stripe/issuer_fraud_record_test.rb +0 -20
- data/test/stripe/subscription_schedule_revision_test.rb +0 -37
- data/test/stripe/subscription_schedule_revisions_operations_test.rb +0 -35
- data/test/stripe/transfer_reversals_operations_test.rb +0 -57
- data/test/stripe/usage_record_test.rb +0 -28
data/lib/stripe/version.rb
CHANGED
data/lib/stripe/webhook.rb
CHANGED
@@ -8,7 +8,8 @@ module Stripe
|
|
8
8
|
#
|
9
9
|
# This may raise JSON::ParserError if the payload is not valid JSON, or
|
10
10
|
# SignatureVerificationError if the signature verification fails.
|
11
|
-
def self.construct_event(payload, sig_header, secret,
|
11
|
+
def self.construct_event(payload, sig_header, secret,
|
12
|
+
tolerance: DEFAULT_TOLERANCE)
|
12
13
|
Signature.verify_header(payload, sig_header, secret, tolerance: tolerance)
|
13
14
|
|
14
15
|
# It's a good idea to parse the payload only after verifying it. We use
|
@@ -21,7 +22,7 @@ module Stripe
|
|
21
22
|
end
|
22
23
|
|
23
24
|
module Signature
|
24
|
-
EXPECTED_SCHEME = "v1"
|
25
|
+
EXPECTED_SCHEME = "v1"
|
25
26
|
|
26
27
|
def self.compute_signature(payload, secret)
|
27
28
|
OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new("sha256"), secret, payload)
|
@@ -50,7 +51,8 @@ module Stripe
|
|
50
51
|
# Returns true otherwise
|
51
52
|
def self.verify_header(payload, header, secret, tolerance: nil)
|
52
53
|
begin
|
53
|
-
timestamp, signatures =
|
54
|
+
timestamp, signatures =
|
55
|
+
get_timestamp_and_signatures(header, EXPECTED_SCHEME)
|
54
56
|
rescue StandardError
|
55
57
|
raise SignatureVerificationError.new(
|
56
58
|
"Unable to extract timestamp and signatures from header",
|
data/stripe.gemspec
CHANGED
@@ -7,19 +7,28 @@ require "stripe/version"
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "stripe"
|
9
9
|
s.version = Stripe::VERSION
|
10
|
-
s.required_ruby_version = ">= 2.
|
10
|
+
s.required_ruby_version = ">= 2.3.0"
|
11
11
|
s.summary = "Ruby bindings for the Stripe API"
|
12
|
-
s.description = "Stripe is the easiest way to accept payments online.
|
12
|
+
s.description = "Stripe is the easiest way to accept payments online. " \
|
13
|
+
"See https://stripe.com for details."
|
13
14
|
s.author = "Stripe"
|
14
15
|
s.email = "support@stripe.com"
|
15
16
|
s.homepage = "https://stripe.com/docs/api/ruby"
|
16
17
|
s.license = "MIT"
|
17
18
|
|
18
|
-
s.
|
19
|
-
|
19
|
+
s.metadata = {
|
20
|
+
"bug_tracker_uri" => "https://github.com/stripe/stripe-ruby/issues",
|
21
|
+
"changelog_uri" =>
|
22
|
+
"https://github.com/stripe/stripe-ruby/blob/master/CHANGELOG.md",
|
23
|
+
"documentation_uri" => "https://stripe.com/docs/api/ruby",
|
24
|
+
"github_repo" => "ssh://github.com/stripe/stripe-ruby",
|
25
|
+
"homepage_uri" => "https://stripe.com/docs/api/ruby",
|
26
|
+
"source_code_uri" => "https://github.com/stripe/stripe-ruby",
|
27
|
+
}
|
20
28
|
|
21
29
|
s.files = `git ls-files`.split("\n")
|
22
30
|
s.test_files = `git ls-files -- test/*`.split("\n")
|
23
|
-
s.executables = `git ls-files -- bin/*`.split("\n")
|
31
|
+
s.executables = `git ls-files -- bin/*`.split("\n")
|
32
|
+
.map { |f| ::File.basename(f) }
|
24
33
|
s.require_paths = ["lib"]
|
25
34
|
end
|
data/test/stripe/account_test.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require ::File.expand_path("
|
3
|
+
require ::File.expand_path("../test_helper", __dir__)
|
4
4
|
|
5
5
|
module Stripe
|
6
6
|
class AccountTest < Test::Unit::TestCase
|
@@ -24,15 +24,18 @@ module Stripe
|
|
24
24
|
end
|
25
25
|
|
26
26
|
should "be rejectable" do
|
27
|
-
account_data = { id: "acct_foo" }
|
28
|
-
stub_request(:get, "#{Stripe.api_base}/v1/accounts/acct_foo")
|
29
|
-
.to_return(body: JSON.generate(account_data))
|
30
|
-
|
31
|
-
stub_request(:post, "#{Stripe.api_base}/v1/accounts/acct_foo/reject")
|
32
|
-
.to_return(body: JSON.generate(account_data))
|
33
|
-
|
34
27
|
account = Stripe::Account.retrieve("acct_foo")
|
35
|
-
account.reject(reason: "fraud")
|
28
|
+
account = account.reject(reason: "fraud")
|
29
|
+
assert_requested :post, "#{Stripe.api_base}/v1/accounts/#{account.id}/reject"
|
30
|
+
assert account.is_a?(Stripe::Account)
|
31
|
+
end
|
32
|
+
|
33
|
+
context ".reject" do
|
34
|
+
should "reject the account" do
|
35
|
+
account = Stripe::Account.reject("acct_foo", reason: "fraud")
|
36
|
+
assert_requested :post, "#{Stripe.api_base}/v1/accounts/#{account.id}/reject"
|
37
|
+
assert account.is_a?(Stripe::Account)
|
38
|
+
end
|
36
39
|
end
|
37
40
|
|
38
41
|
should "be creatable" do
|
@@ -54,11 +57,21 @@ module Stripe
|
|
54
57
|
assert account.is_a?(Stripe::Account)
|
55
58
|
end
|
56
59
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
60
|
+
context "#delete" do
|
61
|
+
should "be deletable" do
|
62
|
+
account = Stripe::Account.retrieve("acct_123")
|
63
|
+
account = account.delete
|
64
|
+
assert_requested :delete, "#{Stripe.api_base}/v1/accounts/#{account.id}"
|
65
|
+
assert account.is_a?(Stripe::Account)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context ".delete" do
|
70
|
+
should "be deletable" do
|
71
|
+
account = Stripe::Account.delete("acct_123")
|
72
|
+
assert_requested :delete, "#{Stripe.api_base}/v1/accounts/acct_123"
|
73
|
+
assert account.is_a?(Stripe::Account)
|
74
|
+
end
|
62
75
|
end
|
63
76
|
|
64
77
|
should "be able to list Persons" do
|
@@ -69,22 +82,6 @@ module Stripe
|
|
69
82
|
assert persons.data[0].is_a?(Stripe::Person)
|
70
83
|
end
|
71
84
|
|
72
|
-
context "#bank_account=" do
|
73
|
-
should "warn that #bank_account= is deprecated" do
|
74
|
-
old_stderr = $stderr
|
75
|
-
$stderr = StringIO.new
|
76
|
-
begin
|
77
|
-
account = Stripe::Account.retrieve("acct_123")
|
78
|
-
account.bank_account = "tok_123"
|
79
|
-
message = "NOTE: Stripe::Account#bank_account= is " \
|
80
|
-
"deprecated; use #external_account= instead"
|
81
|
-
assert_match Regexp.new(message), $stderr.string
|
82
|
-
ensure
|
83
|
-
$stderr = old_stderr
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
85
|
context "#deauthorize" do
|
89
86
|
should "deauthorize an account" do
|
90
87
|
account = Stripe::Account.retrieve("acct_123")
|
@@ -100,7 +97,12 @@ module Stripe
|
|
100
97
|
|
101
98
|
context "#legal_entity=" do
|
102
99
|
should "disallow direct overrides" do
|
103
|
-
account = Stripe::Account.
|
100
|
+
account = Stripe::Account.construct_from(
|
101
|
+
id: "acct_123",
|
102
|
+
legal_entity: {
|
103
|
+
first_name: "name",
|
104
|
+
}
|
105
|
+
)
|
104
106
|
|
105
107
|
assert_raise NoMethodError do
|
106
108
|
account.legal_entity = { first_name: "Blah" }
|
@@ -111,7 +113,7 @@ module Stripe
|
|
111
113
|
end
|
112
114
|
|
113
115
|
context "#serialize_params" do
|
114
|
-
should "serialize
|
116
|
+
should "serialize a new additional_owners" do
|
115
117
|
obj = Stripe::Util.convert_to_stripe_object({
|
116
118
|
object: "account",
|
117
119
|
legal_entity: Stripe::StripeObject.construct_from({
|
@@ -247,5 +249,164 @@ module Stripe
|
|
247
249
|
assert_equal(expected, obj.serialize_params)
|
248
250
|
end
|
249
251
|
end
|
252
|
+
|
253
|
+
context "#retrieve_capability" do
|
254
|
+
should "retrieve a capability" do
|
255
|
+
capability = Stripe::Account.retrieve_capability(
|
256
|
+
"acct_123",
|
257
|
+
"acap_123"
|
258
|
+
)
|
259
|
+
assert_requested :get, "#{Stripe.api_base}/v1/accounts/acct_123/capabilities/acap_123"
|
260
|
+
assert capability.is_a?(Stripe::Capability)
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
context "#update_capability" do
|
265
|
+
should "update a capability" do
|
266
|
+
capability = Stripe::Account.update_capability(
|
267
|
+
"acct_123",
|
268
|
+
"acap_123",
|
269
|
+
requested: true
|
270
|
+
)
|
271
|
+
assert_requested :post, "#{Stripe.api_base}/v1/accounts/acct_123/capabilities/acap_123"
|
272
|
+
assert capability.is_a?(Stripe::Capability)
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
context "#list_capabilities" do
|
277
|
+
should "list the account's external accounts" do
|
278
|
+
capabilities = Stripe::Account.list_capabilities(
|
279
|
+
"acct_123"
|
280
|
+
)
|
281
|
+
assert_requested :get, "#{Stripe.api_base}/v1/accounts/acct_123/capabilities"
|
282
|
+
assert capabilities.is_a?(Stripe::ListObject)
|
283
|
+
assert capabilities.data.is_a?(Array)
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
context "#create_external_account" do
|
288
|
+
should "create an external account" do
|
289
|
+
external_account = Stripe::Account.create_external_account(
|
290
|
+
"acct_123",
|
291
|
+
external_account: "btok_123"
|
292
|
+
)
|
293
|
+
assert_requested :post, "#{Stripe.api_base}/v1/accounts/acct_123/external_accounts"
|
294
|
+
assert external_account.is_a?(Stripe::BankAccount)
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
context "#retrieve_external_account" do
|
299
|
+
should "retrieve an external account" do
|
300
|
+
external_account = Stripe::Account.retrieve_external_account(
|
301
|
+
"acct_123",
|
302
|
+
"ba_123"
|
303
|
+
)
|
304
|
+
assert_requested :get, "#{Stripe.api_base}/v1/accounts/acct_123/external_accounts/ba_123"
|
305
|
+
assert external_account.is_a?(Stripe::BankAccount)
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
context "#update_external_account" do
|
310
|
+
should "update an external account" do
|
311
|
+
external_account = Stripe::Account.update_external_account(
|
312
|
+
"acct_123",
|
313
|
+
"ba_123",
|
314
|
+
metadata: { foo: "bar" }
|
315
|
+
)
|
316
|
+
assert_requested :post, "#{Stripe.api_base}/v1/accounts/acct_123/external_accounts/ba_123"
|
317
|
+
assert external_account.is_a?(Stripe::BankAccount)
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
context "#delete_external_account" do
|
322
|
+
should "delete an external_account" do
|
323
|
+
external_account = Stripe::Account.delete_external_account(
|
324
|
+
"acct_123",
|
325
|
+
"ba_123"
|
326
|
+
)
|
327
|
+
assert_requested :delete, "#{Stripe.api_base}/v1/accounts/acct_123/external_accounts/ba_123"
|
328
|
+
assert external_account.deleted
|
329
|
+
assert_equal "ba_123", external_account.id
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
context "#list_external_accounts" do
|
334
|
+
should "list the account's external accounts" do
|
335
|
+
external_accounts = Stripe::Account.list_external_accounts(
|
336
|
+
"acct_123"
|
337
|
+
)
|
338
|
+
assert_requested :get, "#{Stripe.api_base}/v1/accounts/acct_123/external_accounts"
|
339
|
+
assert external_accounts.is_a?(Stripe::ListObject)
|
340
|
+
assert external_accounts.data.is_a?(Array)
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
context "#create_login_link" do
|
345
|
+
should "create a login link" do
|
346
|
+
login_link = Stripe::Account.create_login_link(
|
347
|
+
"acct_123"
|
348
|
+
)
|
349
|
+
assert_requested :post, "#{Stripe.api_base}/v1/accounts/acct_123/login_links"
|
350
|
+
assert login_link.is_a?(Stripe::LoginLink)
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
context "#create_person" do
|
355
|
+
should "create a person" do
|
356
|
+
person = Stripe::Account.create_person(
|
357
|
+
"acct_123",
|
358
|
+
first_name: "John",
|
359
|
+
last_name: "Doe"
|
360
|
+
)
|
361
|
+
assert_requested :post, "#{Stripe.api_base}/v1/accounts/acct_123/persons"
|
362
|
+
assert person.is_a?(Stripe::Person)
|
363
|
+
end
|
364
|
+
end
|
365
|
+
|
366
|
+
context "#retrieve_person" do
|
367
|
+
should "retrieve a person" do
|
368
|
+
person = Stripe::Account.retrieve_person(
|
369
|
+
"acct_123",
|
370
|
+
"person_123"
|
371
|
+
)
|
372
|
+
assert_requested :get, "#{Stripe.api_base}/v1/accounts/acct_123/persons/person_123"
|
373
|
+
assert person.is_a?(Stripe::Person)
|
374
|
+
end
|
375
|
+
end
|
376
|
+
|
377
|
+
context "#update_person" do
|
378
|
+
should "update a person" do
|
379
|
+
person = Stripe::Account.update_person(
|
380
|
+
"acct_123",
|
381
|
+
"person_123",
|
382
|
+
first_name: "John"
|
383
|
+
)
|
384
|
+
assert_requested :post, "#{Stripe.api_base}/v1/accounts/acct_123/persons/person_123"
|
385
|
+
assert person.is_a?(Stripe::Person)
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
context "#delete_person" do
|
390
|
+
should "delete an person" do
|
391
|
+
person = Stripe::Account.delete_person(
|
392
|
+
"acct_123",
|
393
|
+
"person_123"
|
394
|
+
)
|
395
|
+
assert_requested :delete, "#{Stripe.api_base}/v1/accounts/acct_123/persons/person_123"
|
396
|
+
assert person.deleted
|
397
|
+
assert_equal "person_123", person.id
|
398
|
+
end
|
399
|
+
end
|
400
|
+
|
401
|
+
context "#list_persons" do
|
402
|
+
should "list the account's external accounts" do
|
403
|
+
persons = Stripe::Account.list_persons(
|
404
|
+
"acct_123"
|
405
|
+
)
|
406
|
+
assert_requested :get, "#{Stripe.api_base}/v1/accounts/acct_123/persons"
|
407
|
+
assert persons.is_a?(Stripe::ListObject)
|
408
|
+
assert persons.data.is_a?(Array)
|
409
|
+
end
|
410
|
+
end
|
250
411
|
end
|
251
412
|
end
|
@@ -1,14 +1,13 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
1
|
# frozen_string_literal: true
|
3
2
|
|
4
|
-
require ::File.expand_path("
|
3
|
+
require ::File.expand_path("../test_helper", __dir__)
|
5
4
|
|
6
5
|
module Stripe
|
7
6
|
class ApiOperationsTest < Test::Unit::TestCase
|
8
7
|
class UpdateableResource < APIResource
|
9
8
|
include Stripe::APIOperations::Save
|
10
9
|
|
11
|
-
OBJECT_NAME = "updateableresource"
|
10
|
+
OBJECT_NAME = "updateableresource"
|
12
11
|
|
13
12
|
def self.protected_fields
|
14
13
|
[:protected]
|
@@ -35,7 +34,7 @@ module Stripe
|
|
35
34
|
context ".nested_resource_class_methods" do
|
36
35
|
class MainResource < APIResource
|
37
36
|
extend Stripe::APIOperations::NestedResource
|
38
|
-
OBJECT_NAME = "mainresource"
|
37
|
+
OBJECT_NAME = "mainresource"
|
39
38
|
nested_resource_class_methods :nested,
|
40
39
|
operations: %i[create retrieve update delete list]
|
41
40
|
end
|
@@ -1,14 +1,34 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
1
|
# frozen_string_literal: true
|
3
2
|
|
4
|
-
require ::File.expand_path("
|
3
|
+
require ::File.expand_path("../test_helper", __dir__)
|
5
4
|
|
6
5
|
module Stripe
|
7
6
|
class ApiResourceTest < Test::Unit::TestCase
|
8
|
-
class
|
7
|
+
class CustomMethodAPIResource < APIResource
|
8
|
+
OBJECT_NAME = "custom_method"
|
9
|
+
custom_method :my_method, http_verb: :post
|
10
|
+
end
|
11
|
+
|
12
|
+
class NestedTestAPIResource < APIResource
|
9
13
|
save_nested_resource :external_account
|
10
14
|
end
|
11
15
|
|
16
|
+
context ".custom_method" do
|
17
|
+
should "call to an RPC-style method" do
|
18
|
+
stub_request(:post, "#{Stripe.api_base}/v1/custom_methods/ch_123/my_method")
|
19
|
+
.to_return(body: JSON.generate({}))
|
20
|
+
CustomMethodAPIResource.my_method("ch_123")
|
21
|
+
end
|
22
|
+
|
23
|
+
should "raise an error if a non-ID is passed" do
|
24
|
+
e = assert_raises ArgumentError do
|
25
|
+
CustomMethodAPIResource.my_method(id: "ch_123")
|
26
|
+
end
|
27
|
+
assert_equal "id should be a string representing the ID of an API resource",
|
28
|
+
e.message
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
12
32
|
context ".save_nested_resource" do
|
13
33
|
should "can have a scalar set" do
|
14
34
|
r = NestedTestAPIResource.new("test_resource")
|
@@ -251,14 +271,6 @@ module Stripe
|
|
251
271
|
assert_equal c.created, 12_345
|
252
272
|
end
|
253
273
|
|
254
|
-
should "accessing a property other than id or parent on an unfetched object should fetch it" do
|
255
|
-
stub_request(:get, "#{Stripe.api_base}/v1/charges")
|
256
|
-
.with(query: { customer: "cus_123" })
|
257
|
-
.to_return(body: JSON.generate(customer_fixture))
|
258
|
-
c = Stripe::Customer.new("cus_123")
|
259
|
-
c.charges
|
260
|
-
end
|
261
|
-
|
262
274
|
should "updating an object should issue a POST request with only the changed properties" do
|
263
275
|
stub_request(:post, "#{Stripe.api_base}/v1/customers/cus_123")
|
264
276
|
.with(body: { "description" => "another_mn" })
|
@@ -307,7 +319,7 @@ module Stripe
|
|
307
319
|
charges = Stripe::Charge.list.data
|
308
320
|
assert charges.is_a? Array
|
309
321
|
assert charges[0].is_a? Stripe::Charge
|
310
|
-
assert charges[0].
|
322
|
+
assert charges[0].payment_method_details.is_a?(Stripe::StripeObject)
|
311
323
|
end
|
312
324
|
|
313
325
|
should "passing in a stripe_account header should pass it through on call" do
|
@@ -375,20 +387,22 @@ module Stripe
|
|
375
387
|
end
|
376
388
|
|
377
389
|
should "correctly handle replaced nested objects" do
|
378
|
-
acct = Stripe::Account.construct_from(
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
390
|
+
acct = Stripe::Account.construct_from(
|
391
|
+
id: "acct_123",
|
392
|
+
company: {
|
393
|
+
name: "company_name",
|
394
|
+
address: {
|
395
|
+
line1: "test",
|
396
|
+
city: "San Francisco",
|
397
|
+
},
|
398
|
+
}
|
399
|
+
)
|
400
|
+
|
401
|
+
stub_request(:post, "#{Stripe.api_base}/v1/accounts/acct_123")
|
402
|
+
.with(body: { company: { address: { line1: "Test2", city: "" } } })
|
389
403
|
.to_return(body: JSON.generate("id" => "my_id"))
|
390
404
|
|
391
|
-
acct.
|
405
|
+
acct.company.address = { line1: "Test2" }
|
392
406
|
acct.save
|
393
407
|
end
|
394
408
|
|
@@ -489,7 +503,84 @@ module Stripe
|
|
489
503
|
end
|
490
504
|
end
|
491
505
|
|
492
|
-
|
506
|
+
context "#request_stripe_object" do
|
507
|
+
class HelloTestAPIResource < APIResource
|
508
|
+
OBJECT_NAME = "hello"
|
509
|
+
def say_hello(params = {}, opts = {})
|
510
|
+
request_stripe_object(
|
511
|
+
method: :post,
|
512
|
+
path: resource_url + "/say",
|
513
|
+
params: params,
|
514
|
+
opts: opts
|
515
|
+
)
|
516
|
+
end
|
517
|
+
end
|
518
|
+
|
519
|
+
setup do
|
520
|
+
Util.instance_variable_set(
|
521
|
+
:@object_classes,
|
522
|
+
Stripe::ObjectTypes.object_names_to_classes.merge(
|
523
|
+
"hello" => HelloTestAPIResource
|
524
|
+
)
|
525
|
+
)
|
526
|
+
end
|
527
|
+
teardown do
|
528
|
+
Util.class.instance_variable_set(:@object_classes, Stripe::ObjectTypes.object_names_to_classes)
|
529
|
+
end
|
530
|
+
|
531
|
+
should "make requests appropriately" do
|
532
|
+
stub_request(:post, "#{Stripe.api_base}/v1/hellos/hi_123/say")
|
533
|
+
.with(body: { foo: "bar" }, headers: { "Stripe-Account" => "acct_hi" })
|
534
|
+
.to_return(body: JSON.generate("object" => "hello"))
|
535
|
+
|
536
|
+
hello = HelloTestAPIResource.new(id: "hi_123")
|
537
|
+
hello.say_hello({ foo: "bar" }, stripe_account: "acct_hi")
|
538
|
+
end
|
539
|
+
|
540
|
+
should "update attributes in-place when it returns the same thing" do
|
541
|
+
stub_request(:post, "#{Stripe.api_base}/v1/hellos/hi_123/say")
|
542
|
+
.to_return(body: JSON.generate("object" => "hello", "additional" => "attribute"))
|
543
|
+
|
544
|
+
hello = HelloTestAPIResource.new(id: "hi_123")
|
545
|
+
hello.unsaved = "a value"
|
546
|
+
new_hello = hello.say_hello
|
547
|
+
|
548
|
+
# Doesn't matter if you use the return variable or the instance.
|
549
|
+
assert_equal(hello, new_hello)
|
550
|
+
|
551
|
+
# It updates new attributes in-place.
|
552
|
+
assert_equal("attribute", hello.additional)
|
553
|
+
|
554
|
+
# It removes unsaved attributes, but at least lets you know about them.
|
555
|
+
e = assert_raises(NoMethodError) { hello.unsaved }
|
556
|
+
assert_match("The 'unsaved' attribute was set in the past", e.message)
|
557
|
+
end
|
558
|
+
|
559
|
+
should "instantiate a new object of the appropriate class when it is different than the host class" do
|
560
|
+
stub_request(:post, "#{Stripe.api_base}/v1/hellos/hi_123/say")
|
561
|
+
.to_return(body: JSON.generate("object" => "goodbye", "additional" => "attribute"))
|
562
|
+
|
563
|
+
hello = HelloTestAPIResource.new(id: "hi_123")
|
564
|
+
hello.unsaved = "a value"
|
565
|
+
new_goodbye = hello.say_hello
|
566
|
+
|
567
|
+
# The returned value and the instance are different objects.
|
568
|
+
refute_equal(new_goodbye, hello)
|
569
|
+
|
570
|
+
# The returned value has stuff from the server.
|
571
|
+
assert_equal("attribute", new_goodbye.additional)
|
572
|
+
assert_equal("goodbye", new_goodbye.object)
|
573
|
+
|
574
|
+
# You instance doesn't have stuff from the server.
|
575
|
+
e = assert_raises(NoMethodError) { hello.additional }
|
576
|
+
refute_match(/was set in the past/, e.message)
|
577
|
+
|
578
|
+
# The instance preserves unset attributes on the original instance (not sure this is good behavior?)
|
579
|
+
assert_equal("a value", hello.unsaved)
|
580
|
+
end
|
581
|
+
end
|
582
|
+
|
583
|
+
@@fixtures = {} # rubocop:disable Style/ClassVars
|
493
584
|
setup do
|
494
585
|
if @@fixtures.empty?
|
495
586
|
cache_fixture(:charge) do
|
@@ -501,19 +592,17 @@ module Stripe
|
|
501
592
|
end
|
502
593
|
end
|
503
594
|
|
504
|
-
private
|
505
|
-
|
506
|
-
def charge_fixture
|
595
|
+
private def charge_fixture
|
507
596
|
@@fixtures[:charge]
|
508
597
|
end
|
509
598
|
|
510
|
-
def customer_fixture
|
599
|
+
private def customer_fixture
|
511
600
|
@@fixtures[:customer]
|
512
601
|
end
|
513
602
|
|
514
603
|
# Expects to retrieve a fixture from stripe-mock (an API call should be
|
515
604
|
# included in the block to yield to) and does very simple memoization.
|
516
|
-
def cache_fixture(key)
|
605
|
+
private def cache_fixture(key)
|
517
606
|
return @@fixtures[key] if @@fixtures.key?(key)
|
518
607
|
|
519
608
|
obj = yield
|