stripe 4.20.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +17 -4
  3. data/.rubocop_todo.yml +10 -9
  4. data/.travis.yml +2 -6
  5. data/CHANGELOG.md +52 -1
  6. data/Gemfile +2 -12
  7. data/README.md +10 -10
  8. data/Rakefile +8 -7
  9. data/VERSION +1 -1
  10. data/lib/stripe/api_operations/list.rb +0 -6
  11. data/lib/stripe/api_resource.rb +16 -0
  12. data/lib/stripe/connection_manager.rb +131 -0
  13. data/lib/stripe/error_object.rb +94 -0
  14. data/lib/stripe/errors.rb +15 -2
  15. data/lib/stripe/list_object.rb +2 -1
  16. data/lib/stripe/multipart_encoder.rb +131 -0
  17. data/lib/stripe/object_types.rb +1 -4
  18. data/lib/stripe/resources/account.rb +7 -7
  19. data/lib/stripe/resources/account_link.rb +1 -1
  20. data/lib/stripe/resources/alipay_account.rb +1 -1
  21. data/lib/stripe/resources/apple_pay_domain.rb +1 -1
  22. data/lib/stripe/resources/application_fee.rb +1 -12
  23. data/lib/stripe/resources/application_fee_refund.rb +1 -1
  24. data/lib/stripe/resources/balance.rb +1 -1
  25. data/lib/stripe/resources/balance_transaction.rb +1 -5
  26. data/lib/stripe/resources/bank_account.rb +1 -1
  27. data/lib/stripe/resources/bitcoin_receiver.rb +1 -1
  28. data/lib/stripe/resources/bitcoin_transaction.rb +1 -1
  29. data/lib/stripe/resources/capability.rb +1 -1
  30. data/lib/stripe/resources/card.rb +1 -1
  31. data/lib/stripe/resources/charge.rb +7 -69
  32. data/lib/stripe/resources/checkout/session.rb +1 -1
  33. data/lib/stripe/resources/country_spec.rb +1 -1
  34. data/lib/stripe/resources/coupon.rb +1 -1
  35. data/lib/stripe/resources/credit_note.rb +7 -3
  36. data/lib/stripe/resources/customer.rb +5 -66
  37. data/lib/stripe/resources/customer_balance_transaction.rb +1 -1
  38. data/lib/stripe/resources/discount.rb +1 -1
  39. data/lib/stripe/resources/dispute.rb +7 -9
  40. data/lib/stripe/resources/ephemeral_key.rb +1 -1
  41. data/lib/stripe/resources/event.rb +1 -1
  42. data/lib/stripe/resources/exchange_rate.rb +1 -1
  43. data/lib/stripe/resources/file.rb +3 -13
  44. data/lib/stripe/resources/file_link.rb +1 -1
  45. data/lib/stripe/resources/invoice.rb +36 -11
  46. data/lib/stripe/resources/invoice_item.rb +1 -1
  47. data/lib/stripe/resources/invoice_line_item.rb +1 -1
  48. data/lib/stripe/resources/issuing/authorization.rb +13 -5
  49. data/lib/stripe/resources/issuing/card.rb +7 -3
  50. data/lib/stripe/resources/issuing/card_details.rb +1 -1
  51. data/lib/stripe/resources/issuing/cardholder.rb +1 -1
  52. data/lib/stripe/resources/issuing/dispute.rb +1 -1
  53. data/lib/stripe/resources/issuing/transaction.rb +1 -1
  54. data/lib/stripe/resources/login_link.rb +1 -1
  55. data/lib/stripe/resources/order.rb +13 -13
  56. data/lib/stripe/resources/order_return.rb +1 -1
  57. data/lib/stripe/resources/payment_intent.rb +19 -7
  58. data/lib/stripe/resources/payment_method.rb +13 -5
  59. data/lib/stripe/resources/payout.rb +7 -9
  60. data/lib/stripe/resources/person.rb +1 -1
  61. data/lib/stripe/resources/plan.rb +1 -1
  62. data/lib/stripe/resources/product.rb +1 -1
  63. data/lib/stripe/resources/radar/early_fraud_warning.rb +1 -1
  64. data/lib/stripe/resources/radar/value_list.rb +1 -1
  65. data/lib/stripe/resources/radar/value_list_item.rb +1 -1
  66. data/lib/stripe/resources/recipient.rb +1 -5
  67. data/lib/stripe/resources/recipient_transfer.rb +1 -1
  68. data/lib/stripe/resources/refund.rb +1 -1
  69. data/lib/stripe/resources/reporting/report_run.rb +1 -1
  70. data/lib/stripe/resources/reporting/report_type.rb +1 -1
  71. data/lib/stripe/resources/reversal.rb +1 -1
  72. data/lib/stripe/resources/review.rb +7 -3
  73. data/lib/stripe/resources/setup_intent.rb +32 -0
  74. data/lib/stripe/resources/sigma/scheduled_query_run.rb +1 -1
  75. data/lib/stripe/resources/sku.rb +1 -1
  76. data/lib/stripe/resources/source.rb +7 -9
  77. data/lib/stripe/resources/source_transaction.rb +1 -1
  78. data/lib/stripe/resources/subscription.rb +9 -9
  79. data/lib/stripe/resources/subscription_item.rb +4 -1
  80. data/lib/stripe/resources/subscription_schedule.rb +13 -13
  81. data/lib/stripe/resources/tax_id.rb +1 -1
  82. data/lib/stripe/resources/tax_rate.rb +1 -1
  83. data/lib/stripe/resources/terminal/connection_token.rb +1 -1
  84. data/lib/stripe/resources/terminal/location.rb +1 -1
  85. data/lib/stripe/resources/terminal/reader.rb +1 -1
  86. data/lib/stripe/resources/three_d_secure.rb +1 -1
  87. data/lib/stripe/resources/token.rb +1 -1
  88. data/lib/stripe/resources/topup.rb +7 -3
  89. data/lib/stripe/resources/transfer.rb +7 -8
  90. data/lib/stripe/resources/usage_record.rb +1 -17
  91. data/lib/stripe/resources/usage_record_summary.rb +1 -1
  92. data/lib/stripe/resources/webhook_endpoint.rb +1 -1
  93. data/lib/stripe/resources.rb +1 -2
  94. data/lib/stripe/stripe_client.rb +281 -183
  95. data/lib/stripe/stripe_object.rb +4 -23
  96. data/lib/stripe/stripe_response.rb +53 -21
  97. data/lib/stripe/util.rb +14 -11
  98. data/lib/stripe/version.rb +1 -1
  99. data/lib/stripe/webhook.rb +1 -1
  100. data/lib/stripe.rb +56 -15
  101. data/stripe.gemspec +10 -3
  102. data/test/stripe/account_test.rb +0 -16
  103. data/test/stripe/api_operations_test.rb +2 -2
  104. data/test/stripe/api_resource_test.rb +98 -8
  105. data/test/stripe/balance_transaction_test.rb +20 -0
  106. data/test/stripe/charge_test.rb +0 -16
  107. data/test/stripe/connection_manager_test.rb +138 -0
  108. data/test/stripe/customer_test.rb +1 -44
  109. data/test/stripe/errors_test.rb +29 -8
  110. data/test/stripe/file_test.rb +0 -10
  111. data/test/stripe/invoice_test.rb +17 -1
  112. data/test/stripe/list_object_test.rb +0 -16
  113. data/test/stripe/login_link_test.rb +1 -1
  114. data/test/stripe/multipart_encoder_test.rb +130 -0
  115. data/test/stripe/payment_intent_test.rb +2 -2
  116. data/test/stripe/setup_intent_test.rb +84 -0
  117. data/test/stripe/source_test.rb +0 -18
  118. data/test/stripe/stripe_client_test.rb +214 -29
  119. data/test/stripe/stripe_object_test.rb +7 -35
  120. data/test/stripe/stripe_response_test.rb +70 -24
  121. data/test/stripe/subscription_item_test.rb +12 -0
  122. data/test/stripe/subscription_schedule_test.rb +0 -34
  123. data/test/stripe/subscription_test.rb +2 -2
  124. data/test/stripe/webhook_test.rb +2 -2
  125. data/test/stripe_mock.rb +4 -3
  126. data/test/stripe_test.rb +0 -13
  127. data/test/test_helper.rb +10 -5
  128. metadata +23 -43
  129. data/lib/stripe/resources/issuer_fraud_record.rb +0 -9
  130. data/lib/stripe/resources/subscription_schedule_revision.rb +0 -34
  131. data/test/stripe/file_upload_test.rb +0 -79
  132. data/test/stripe/issuer_fraud_record_test.rb +0 -20
  133. data/test/stripe/subscription_schedule_revision_test.rb +0 -37
  134. data/test/stripe/usage_record_test.rb +0 -28
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 410f62f787eb7bf6284fdc2b3b2e722b5d804b58ac24594d4001f89a5e8f915c
4
- data.tar.gz: ae1f9e13178bb81ada414ef131e57fc6a34e3592d6163d70175d5b7c655f8d6e
3
+ metadata.gz: fa015ad0ee6a063db43580f0234ec2738fe5670c82cfa4843ed3bc91d8eb4670
4
+ data.tar.gz: f987cba3323dbac56c0121fd0d89d5c282a2b3cab9d46f9284cae99b0093d534
5
5
  SHA512:
6
- metadata.gz: fd074e764a3dc6ca94873982b25c3427319ad1d58842d846dc8888383e2bad2eb22b31f6bbce370ecb6c20d643091cd79b355aff83e0c25affb46c00dbf2e8a3
7
- data.tar.gz: c16a7d1aeb72497f1abc2a89b70509fc94b2d8581b3a7cad3ce317ff6021c4b80514342a395f711a527cc45ccc2ed65f309de45e69dad32ce1feae4c2dad11d7
6
+ metadata.gz: 9b5d25d67c8ade84275d3187988de8660df98d1b2323fa231bc4e1a5ef6dfc9edb2ffcbe71bff404f7a473f4cdde0c5644ec379c625f9a45ea62606792f29871
7
+ data.tar.gz: ede395b847a59fba4fc3200f174d212c79fa0781222def2323d27cfdec626f3ff869147c2dfc3639206ce9b4d5ff0a282ec92059d04b8ff6b26d619d81655acd
data/.rubocop.yml CHANGED
@@ -2,21 +2,31 @@ inherit_from: .rubocop_todo.yml
2
2
 
3
3
  AllCops:
4
4
  DisplayCopNames: true
5
- TargetRubyVersion: 2.1
5
+ TargetRubyVersion: 2.3
6
6
 
7
7
  Layout/CaseIndentation:
8
8
  EnforcedStyle: end
9
9
 
10
- Layout/IndentArray:
10
+ Layout/IndentFirstArrayElement:
11
11
  EnforcedStyle: consistent
12
12
 
13
- Layout/IndentHash:
13
+ Layout/IndentFirstHashElement:
14
14
  EnforcedStyle: consistent
15
15
 
16
- Metrics/LineLength:
16
+ # This can be re-enabled once we're 2.3+ only and can use the squiggly heredoc
17
+ # operator. Prior to that, Rubocop recommended bringing in a library like
18
+ # ActiveSupport to get heredoc indentation, which is just terrible.
19
+ Layout/IndentHeredoc:
20
+ Enabled: false
21
+
22
+ Metrics/ClassLength:
17
23
  Exclude:
18
24
  - "test/**/*.rb"
25
+
26
+ Metrics/LineLength:
27
+ Exclude:
19
28
  - "lib/stripe/resources/**/*.rb"
29
+ - "test/**/*.rb"
20
30
 
21
31
  Metrics/MethodLength:
22
32
  # There's ~2 long methods in `StripeClient`. If we want to truncate those a
@@ -33,6 +43,9 @@ Style/AccessModifierDeclarations:
33
43
  Style/FrozenStringLiteralComment:
34
44
  EnforcedStyle: always
35
45
 
46
+ Style/NumericPredicate:
47
+ Enabled: false
48
+
36
49
  Style/StringLiterals:
37
50
  EnforcedStyle: double_quotes
38
51
 
data/.rubocop_todo.yml CHANGED
@@ -1,24 +1,25 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2019-05-24 10:18:48 -0700 using RuboCop version 0.57.2.
3
+ # on 2019-07-30 09:56:31 +0800 using RuboCop version 0.73.0.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
- # Offense count: 20
9
+ # Offense count: 23
10
10
  Metrics/AbcSize:
11
- Max: 53
11
+ Max: 51
12
12
 
13
- # Offense count: 31
13
+ # Offense count: 33
14
14
  # Configuration parameters: CountComments, ExcludedMethods.
15
+ # ExcludedMethods: refine
15
16
  Metrics/BlockLength:
16
- Max: 498
17
+ Max: 509
17
18
 
18
- # Offense count: 11
19
+ # Offense count: 12
19
20
  # Configuration parameters: CountComments.
20
21
  Metrics/ClassLength:
21
- Max: 673
22
+ Max: 694
22
23
 
23
24
  # Offense count: 12
24
25
  Metrics/CyclomaticComplexity:
@@ -29,10 +30,10 @@ Metrics/CyclomaticComplexity:
29
30
  Metrics/ParameterLists:
30
31
  Max: 7
31
32
 
32
- # Offense count: 7
33
+ # Offense count: 8
33
34
  Metrics/PerceivedComplexity:
34
35
  Max: 17
35
36
 
36
- # Offense count: 84
37
+ # Offense count: 86
37
38
  Style/Documentation:
38
39
  Enabled: false
data/.travis.yml CHANGED
@@ -1,13 +1,11 @@
1
1
  language: ruby
2
2
 
3
3
  rvm:
4
- - 2.1
5
- - 2.2
6
4
  - 2.3
7
5
  - 2.4
8
6
  - 2.5
9
7
  - 2.6
10
- - jruby-9.0.5.0
8
+ - jruby-9.2.7.0
11
9
 
12
10
  notifications:
13
11
  email:
@@ -18,15 +16,13 @@ sudo: false
18
16
  env:
19
17
  global:
20
18
  # If changing this number, please also change it in `test/test_helper.rb`.
21
- - STRIPE_MOCK_VERSION=0.58.0
19
+ - STRIPE_MOCK_VERSION=0.63.0
22
20
 
23
21
  cache:
24
22
  directories:
25
23
  - stripe-mock
26
24
 
27
25
  before_install:
28
- # Install bundler 1.x, because we need to support Ruby 2.1 for now
29
- - gem install bundler -v "~> 1.0"
30
26
  # Unpack and start stripe-mock so that the test suite can talk to it
31
27
  - |
32
28
  if [ ! -d "stripe-mock/stripe-mock_${STRIPE_MOCK_VERSION}" ]; then
data/CHANGELOG.md CHANGED
@@ -1,5 +1,56 @@
1
1
  # Changelog
2
2
 
3
+ ## 5.0.0 - 2019-08-20
4
+ Major version release. The [migration guide](https://github.com/stripe/stripe-ruby/wiki/Migration-guide-for-v5) contains a detailed list of backwards-incompatible changes with upgrade instructions.
5
+
6
+ Pull requests included in this release (cf. [#815](https://github.com/stripe/stripe-ruby/pull/815)) (⚠️ = breaking changes):
7
+ * [x] ⚠️ #813: Convert library to use built-in `Net::HTTP`
8
+ * [x] ⚠️ #816: Make `code` argument in `CardError` named instead of positional.
9
+ * [x] ⚠️ #817: Drop support for very old Ruby versions.
10
+ * [x] #818: Bump Rubocop to latest version
11
+ * [x] #819: Ruby minimum version increase followup
12
+ * [x] ⚠️ #820: Remove old deprecated methods
13
+ * [x] ⚠️ #823: Remove all alias for list methods
14
+ * [x] ⚠️ #826: Remove `UsageRecord.create` method
15
+ * [x] ⚠️ #827: Remove `IssuerFraudRecord`
16
+ * [x] #811: Add `ErrorObject` to `StripeError` exceptions
17
+ * [x] #828: Tweak retry logic to be a little more like stripe-node
18
+ * [x] #829: Reset connections when connection-changing configuration changes (optional)
19
+ * [x] #830: Fix inverted sign for 500 retries
20
+ * [x] ⚠️#831: Remove a few more very old deprecated methods
21
+ * [x] #832: Minor cleanup in `StripeClient`
22
+ * [x] #833: Do better bookkeeping when tracking state in `Thread.current`
23
+ * [x] #834: Add `Invoice.list_upcoming_line_items` method
24
+
25
+ ## 4.24.0 - 2019-08-12
26
+ * [#825](https://github.com/stripe/stripe-ruby/pull/825) Add `SubscriptionItem.create_usage_record` method
27
+ - This release also removed the `SubscriptionSchedule.revisions` method. This should have been included in the previous release (4.23.0)
28
+
29
+ ## 4.23.0 - 2019-08-09
30
+ * [#824](https://github.com/stripe/stripe-ruby/pull/824) Remove SubscriptionScheduleRevision
31
+ - This is technically a breaking change. We've chosen to release it as a minor vesion bump because the associated API is unused.
32
+
33
+ ## 4.22.1 - 2019-08-09
34
+ * [#808](https://github.com/stripe/stripe-ruby/pull/808) Unify request/response handling
35
+
36
+ ## 4.22.0 - 2019-07-30
37
+ * [#821](https://github.com/stripe/stripe-ruby/pull/821) Listing `BalanceTransaction` objects now uses `/v1/balance_transactions` instead of `/v1/balance/history`
38
+
39
+ ## 4.21.3 - 2019-07-15
40
+ * [#810](https://github.com/stripe/stripe-ruby/pull/810) Better error message when passing non-string to custom method
41
+
42
+ ## 4.21.2 - 2019-07-05
43
+ * [#806](https://github.com/stripe/stripe-ruby/pull/806) Revert back to `initialize_from` from `Util.convert_to_stripe_object`
44
+
45
+ ## 4.21.1 - 2019-07-04
46
+ * [#807](https://github.com/stripe/stripe-ruby/pull/807) Add gem metadata
47
+
48
+ ## 4.21.0 - 2019-06-28
49
+ * [#803](https://github.com/stripe/stripe-ruby/pull/803) Add support for the `SetupIntent` resource and APIs
50
+
51
+ ## 4.20.1 - 2019-06-28
52
+ * [#805](https://github.com/stripe/stripe-ruby/pull/805) Fix formatting in `ConnectionFailed` error message
53
+
3
54
  ## 4.20.0 - 2019-06-24
4
55
  * [#800](https://github.com/stripe/stripe-ruby/pull/800) Enable request latency telemetry by default
5
56
 
@@ -67,7 +118,7 @@
67
118
  * [#718](https://github.com/stripe/stripe-ruby/pull/718) Fix an error message typo
68
119
 
69
120
  ## 4.4.0 - 2018-12-21
70
- * [#716](https://github.com/stripe/stripe-ruby/pull/716) Add support for the `CheckoutSession` resource
121
+ * [#716](https://github.com/stripe/stripe-ruby/pull/716) Add support for the `CheckoutSession` resource
71
122
 
72
123
  ## 4.3.0 - 2018-12-10
73
124
  * [#711](https://github.com/stripe/stripe-ruby/pull/711) Add support for account links
data/Gemfile CHANGED
@@ -7,6 +7,7 @@ gemspec
7
7
  group :development do
8
8
  gem "coveralls", require: false
9
9
  gem "mocha", "~> 0.13.2"
10
+ gem "rack", ">= 2.0.6"
10
11
  gem "rake"
11
12
  gem "shoulda-context"
12
13
  gem "test-unit"
@@ -18,18 +19,7 @@ group :development do
18
19
  # `Gemfile.lock` checked in, so to prevent good builds from suddenly going
19
20
  # bad, pin to a specific version number here. Try to keep this relatively
20
21
  # up-to-date, but it's not the end of the world if it's not.
21
- # Note that 0.57.2 is the most recent version we can use until we drop
22
- # support for Ruby 2.1.
23
- gem "rubocop", "0.57.2"
24
-
25
- # Rack 2.0+ requires Ruby >= 2.2.2 which is problematic for the test suite on
26
- # older Ruby versions. Check Ruby the version here and put a maximum
27
- # constraint on Rack if necessary.
28
- if RUBY_VERSION >= "2.2.2"
29
- gem "rack", ">= 2.0.6"
30
- else
31
- gem "rack", ">= 1.6.11", "< 2.0" # rubocop:disable Bundler/DuplicatedGem
32
- end
22
+ gem "rubocop", "0.73"
33
23
 
34
24
  platforms :mri do
35
25
  gem "byebug"
data/README.md CHANGED
@@ -39,7 +39,7 @@ gem build stripe.gemspec
39
39
 
40
40
  ### Requirements
41
41
 
42
- - Ruby 2.1+.
42
+ - Ruby 2.3+.
43
43
 
44
44
  ### Bundler
45
45
 
@@ -112,15 +112,13 @@ Stripe::Charge.retrieve(
112
112
  )
113
113
  ```
114
114
 
115
- ### Configuring a Client
115
+ ### Accessing a response object
116
116
 
117
- While a default HTTP client is used by default, it's also possible to have the
118
- library use any client supported by [Faraday][faraday] by initializing a
119
- `Stripe::StripeClient` object and giving it a connection:
117
+ Get access to response objects by initializing a client and using its `request`
118
+ method:
120
119
 
121
120
  ```ruby
122
- conn = Faraday.new
123
- client = Stripe::StripeClient.new(conn)
121
+ client = Stripe::StripeClient.new
124
122
  charge, resp = client.request do
125
123
  Stripe::Charge.retrieve(
126
124
  "ch_18atAXCdGbJFKhCuBAa4532Z",
@@ -159,13 +157,16 @@ Stripe.ca_bundle_path = "path/to/ca/bundle"
159
157
 
160
158
  ### Configuring Automatic Retries
161
159
 
162
- The library can be configured to automatically retry requests that fail due to
163
- an intermittent network problem:
160
+ You can enable automatic retries on requests that fail due to a transient
161
+ problem by configuring the maximum number of retries:
164
162
 
165
163
  ```ruby
166
164
  Stripe.max_network_retries = 2
167
165
  ```
168
166
 
167
+ Various errors can trigger a retry, like a connection error or a timeout, and
168
+ also certain API responses like HTTP status `409 Conflict`.
169
+
169
170
  [Idempotency keys][idempotency-keys] are added to requests to guarantee that
170
171
  retries are safe.
171
172
 
@@ -272,7 +273,6 @@ Update the bundled [stripe-mock] by editing the version number found in
272
273
  [api-keys]: https://dashboard.stripe.com/account/apikeys
273
274
  [connect]: https://stripe.com/connect
274
275
  [curl]: http://curl.haxx.se/docs/caextract.html
275
- [faraday]: https://github.com/lostisland/faraday
276
276
  [idempotency-keys]: https://stripe.com/docs/api/ruby#idempotent_requests
277
277
  [stripe-mock]: https://github.com/stripe/stripe-mock
278
278
  [versioning]: https://stripe.com/docs/api/ruby#versioning
data/Rakefile CHANGED
@@ -13,7 +13,8 @@ RuboCop::RakeTask.new
13
13
 
14
14
  desc "Update bundled certs"
15
15
  task :update_certs do
16
- require "faraday"
16
+ require "net/http"
17
+ require "uri"
17
18
 
18
19
  fetch_file "https://curl.haxx.se/ca/cacert.pem",
19
20
  ::File.expand_path("../lib/data/ca-certificates.crt", __FILE__)
@@ -23,14 +24,14 @@ end
23
24
  # helpers
24
25
  #
25
26
 
26
- def fetch_file(url, dest)
27
+ def fetch_file(uri, dest)
27
28
  ::File.open(dest, "w") do |file|
28
- resp = Faraday.get(url)
29
- unless resp.status == 200
30
- abort("bad response when fetching: #{url}\n" \
31
- "Status #{resp.status}: #{resp.body}")
29
+ resp = Net::HTTP.get_response(URI.parse(uri))
30
+ unless resp.code.to_i == 200
31
+ abort("bad response when fetching: #{uri}\n" \
32
+ "Status #{resp.code}: #{resp.body}")
32
33
  end
33
34
  file.write(resp.body)
34
- puts "Successfully fetched: #{url}"
35
+ puts "Successfully fetched: #{uri}"
35
36
  end
36
37
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 4.20.0
1
+ 5.0.0
@@ -19,12 +19,6 @@ module Stripe
19
19
 
20
20
  obj
21
21
  end
22
-
23
- # The original version of #list was given the somewhat unfortunate name of
24
- # #all, and this alias allows us to maintain backward compatibility (the
25
- # choice was somewhat misleading in the way that it only returned a single
26
- # page rather than all objects).
27
- alias all list
28
22
  end
29
23
  end
30
24
  end
@@ -70,6 +70,11 @@ module Stripe
70
70
  end
71
71
  http_path ||= name.to_s
72
72
  define_singleton_method(name) do |id, params = {}, opts = {}|
73
+ unless id.is_a?(String)
74
+ raise ArgumentError,
75
+ "id should be a string representing the ID of an API resource"
76
+ end
77
+
73
78
  url = "#{resource_url}/#{CGI.escape(id)}/#{CGI.escape(http_path)}"
74
79
  resp, opts = request(http_verb, url, params, opts)
75
80
  Util.convert_to_stripe_object(resp.data, opts)
@@ -98,5 +103,16 @@ module Stripe
98
103
  instance.refresh
99
104
  instance
100
105
  end
106
+
107
+ protected def request_stripe_object(method:, path:, params:, opts: {})
108
+ resp, opts = request(method, path, params, opts)
109
+
110
+ # If we're getting back this thing, update; otherwise, instantiate.
111
+ if Util.object_name_matches_class?(resp.data[:object], self.class)
112
+ initialize_from(resp.data, opts)
113
+ else
114
+ Util.convert_to_stripe_object(resp.data, opts)
115
+ end
116
+ end
101
117
  end
102
118
  end
@@ -0,0 +1,131 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Stripe
4
+ # Manages connections across multiple hosts which is useful because the
5
+ # library may connect to multiple hosts during a typical session (main API,
6
+ # Connect, Uploads). Ruby doesn't provide an easy way to make this happen
7
+ # easily, so this class is designed to track what we're connected to and
8
+ # manage the lifecycle of those connections.
9
+ #
10
+ # Note that this class in itself is *not* thread safe. We expect it to be
11
+ # instantiated once per thread.
12
+ #
13
+ # Note also that this class doesn't currently clean up after itself because
14
+ # it expects to only ever have a few connections. It'd be possible to tank
15
+ # memory by constantly changing the value of `Stripe.api_base` or the like. A
16
+ # possible improvement might be to detect and prune old connections whenever
17
+ # a request is executed.
18
+ class ConnectionManager
19
+ def initialize
20
+ @active_connections = {}
21
+ end
22
+
23
+ # Finishes any active connections by closing their TCP connection and
24
+ # clears them from internal tracking.
25
+ def clear
26
+ @active_connections.each do |_, connection|
27
+ connection.finish
28
+ end
29
+ @active_connections = {}
30
+ end
31
+
32
+ # Gets a connection for a given URI. This is for internal use only as it's
33
+ # subject to change (we've moved between HTTP client schemes in the past
34
+ # and may do it again).
35
+ #
36
+ # `uri` is expected to be a string.
37
+ def connection_for(uri)
38
+ u = URI.parse(uri)
39
+ connection = @active_connections[[u.host, u.port]]
40
+
41
+ if connection.nil?
42
+ connection = create_connection(u)
43
+
44
+ # TODO: what happens after TTL?
45
+ connection.start
46
+
47
+ @active_connections[[u.host, u.port]] = connection
48
+ end
49
+
50
+ connection
51
+ end
52
+
53
+ # Executes an HTTP request to the given URI with the given method. Also
54
+ # allows a request body, headers, and query string to be specified.
55
+ def execute_request(method, uri, body: nil, headers: nil, query: nil)
56
+ # Perform some basic argument validation because it's easy to get
57
+ # confused between strings and hashes for things like body and query
58
+ # parameters.
59
+ raise ArgumentError, "method should be a symbol" \
60
+ unless method.is_a?(Symbol)
61
+ raise ArgumentError, "uri should be a string" \
62
+ unless uri.is_a?(String)
63
+ raise ArgumentError, "body should be a string" \
64
+ if body && !body.is_a?(String)
65
+ raise ArgumentError, "headers should be a hash" \
66
+ if headers && !headers.is_a?(Hash)
67
+ raise ArgumentError, "query should be a string" \
68
+ if query && !query.is_a?(String)
69
+
70
+ connection = connection_for(uri)
71
+
72
+ u = URI.parse(uri)
73
+ path = if query
74
+ u.path + "?" + query
75
+ else
76
+ u.path
77
+ end
78
+
79
+ connection.send_request(method.to_s.upcase, path, body, headers)
80
+ end
81
+
82
+ #
83
+ # private
84
+ #
85
+
86
+ # `uri` should be a parsed `URI` object.
87
+ private def create_connection(uri)
88
+ # These all come back as `nil` if no proxy is configured.
89
+ proxy_host, proxy_port, proxy_user, proxy_pass = proxy_parts
90
+
91
+ connection = Net::HTTP.new(uri.host, uri.port,
92
+ proxy_host, proxy_port,
93
+ proxy_user, proxy_pass)
94
+
95
+ connection.open_timeout = Stripe.open_timeout
96
+ connection.read_timeout = Stripe.read_timeout
97
+
98
+ connection.use_ssl = uri.scheme == "https"
99
+
100
+ if Stripe.verify_ssl_certs
101
+ connection.verify_mode = OpenSSL::SSL::VERIFY_PEER
102
+ connection.cert_store = Stripe.ca_store
103
+ else
104
+ connection.verify_mode = OpenSSL::SSL::VERIFY_NONE
105
+
106
+ unless @verify_ssl_warned
107
+ @verify_ssl_warned = true
108
+ warn("WARNING: Running without SSL cert verification. " \
109
+ "You should never do this in production. " \
110
+ "Execute `Stripe.verify_ssl_certs = true` to enable " \
111
+ "verification.")
112
+ end
113
+ end
114
+
115
+ connection
116
+ end
117
+
118
+ # `Net::HTTP` somewhat awkwardly requires each component of a proxy URI
119
+ # (host, port, etc.) rather than the URI itself. This method simply parses
120
+ # out those pieces to make passing them into a new connection a little less
121
+ # ugly.
122
+ private def proxy_parts
123
+ if Stripe.proxy.nil?
124
+ [nil, nil, nil, nil]
125
+ else
126
+ u = URI.parse(Stripe.proxy)
127
+ [u.host, u.port, u.user, u.password]
128
+ end
129
+ end
130
+ end
131
+ end
@@ -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
- # TODO: make code a keyword arg in next major release
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
@@ -7,7 +7,7 @@ module Stripe
7
7
  include Stripe::APIOperations::Request
8
8
  include Stripe::APIOperations::Create
9
9
 
10
- OBJECT_NAME = "list".freeze
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)