stripe 10.1.0 → 12.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (165) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +215 -21
  3. data/Gemfile +6 -5
  4. data/Makefile +8 -1
  5. data/OPENAPI_VERSION +1 -1
  6. data/README.md +46 -14
  7. data/Rakefile +7 -5
  8. data/VERSION +1 -1
  9. data/{bin → exe}/stripe-console +1 -1
  10. data/lib/stripe/api_operations/nested_resource.rb +22 -2
  11. data/lib/stripe/api_operations/request.rb +22 -18
  12. data/lib/stripe/api_operations/save.rb +7 -9
  13. data/lib/stripe/api_operations/search.rb +5 -0
  14. data/lib/stripe/api_operations/singleton_save.rb +86 -0
  15. data/lib/stripe/api_resource.rb +13 -4
  16. data/lib/stripe/api_resource_test_helpers.rb +7 -3
  17. data/lib/stripe/api_version.rb +1 -1
  18. data/lib/stripe/connection_manager.rb +4 -6
  19. data/lib/stripe/errors.rb +3 -11
  20. data/lib/stripe/instrumentation.rb +5 -21
  21. data/lib/stripe/list_object.rb +3 -0
  22. data/lib/stripe/multipart_encoder.rb +7 -7
  23. data/lib/stripe/oauth.rb +6 -6
  24. data/lib/stripe/object_types.rb +135 -116
  25. data/lib/stripe/resources/account.rb +103 -25
  26. data/lib/stripe/resources/account_link.rb +8 -0
  27. data/lib/stripe/resources/account_session.rb +8 -0
  28. data/lib/stripe/resources/alipay_account.rb +1 -1
  29. data/lib/stripe/resources/apple_pay_domain.rb +43 -0
  30. data/lib/stripe/resources/application_fee.rb +8 -0
  31. data/lib/stripe/resources/application_fee_refund.rb +4 -2
  32. data/lib/stripe/resources/apps/secret.rb +15 -0
  33. data/lib/stripe/resources/balance.rb +3 -0
  34. data/lib/stripe/resources/balance_transaction.rb +15 -0
  35. data/lib/stripe/resources/bank_account.rb +49 -7
  36. data/lib/stripe/resources/billing/alert.rb +87 -0
  37. data/lib/stripe/resources/billing/meter.rb +83 -0
  38. data/lib/stripe/resources/billing/meter_event.rb +27 -0
  39. data/lib/stripe/resources/billing/meter_event_adjustment.rb +26 -0
  40. data/lib/stripe/resources/billing/meter_event_summary.rb +15 -0
  41. data/lib/stripe/resources/billing_portal/configuration.rb +33 -0
  42. data/lib/stripe/resources/billing_portal/session.rb +14 -1
  43. data/lib/stripe/resources/capability.rb +4 -2
  44. data/lib/stripe/resources/card.rb +28 -0
  45. data/lib/stripe/resources/cash_balance.rb +3 -0
  46. data/lib/stripe/resources/charge.rb +39 -1
  47. data/lib/stripe/resources/checkout/session.rb +47 -5
  48. data/lib/stripe/resources/climate/order.rb +67 -0
  49. data/lib/stripe/resources/climate/product.rb +27 -0
  50. data/lib/stripe/resources/climate/supplier.rb +26 -0
  51. data/lib/stripe/resources/confirmation_token.rb +39 -0
  52. data/lib/stripe/resources/country_spec.rb +8 -0
  53. data/lib/stripe/resources/coupon.rb +45 -0
  54. data/lib/stripe/resources/credit_note.rb +47 -7
  55. data/lib/stripe/resources/credit_note_line_item.rb +3 -0
  56. data/lib/stripe/resources/customer.rb +89 -26
  57. data/lib/stripe/resources/customer_balance_transaction.rb +3 -1
  58. data/lib/stripe/resources/customer_cash_balance_transaction.rb +3 -2
  59. data/lib/stripe/resources/customer_session.rb +29 -0
  60. data/lib/stripe/resources/discount.rb +3 -0
  61. data/lib/stripe/resources/dispute.rb +26 -0
  62. data/lib/stripe/resources/entitlements/active_entitlement.rb +26 -0
  63. data/lib/stripe/resources/entitlements/feature.rb +49 -0
  64. data/lib/stripe/resources/ephemeral_key.rb +23 -0
  65. data/lib/stripe/resources/event.rb +11 -3
  66. data/lib/stripe/resources/exchange_rate.rb +8 -0
  67. data/lib/stripe/resources/file.rb +29 -16
  68. data/lib/stripe/resources/file_link.rb +23 -0
  69. data/lib/stripe/resources/financial_connections/account.rb +66 -7
  70. data/lib/stripe/resources/financial_connections/account_owner.rb +3 -0
  71. data/lib/stripe/resources/financial_connections/account_ownership.rb +3 -0
  72. data/lib/stripe/resources/financial_connections/session.rb +13 -0
  73. data/lib/stripe/resources/financial_connections/transaction.rb +26 -0
  74. data/lib/stripe/resources/forwarding/request.rb +52 -0
  75. data/lib/stripe/resources/funding_instructions.rb +3 -0
  76. data/lib/stripe/resources/identity/verification_report.rb +14 -1
  77. data/lib/stripe/resources/identity/verification_session.rb +90 -4
  78. data/lib/stripe/resources/invoice.rb +170 -17
  79. data/lib/stripe/resources/invoice_item.rb +43 -0
  80. data/lib/stripe/resources/invoice_line_item.rb +21 -0
  81. data/lib/stripe/resources/invoice_rendering_template.rb +63 -0
  82. data/lib/stripe/resources/issuing/authorization.rb +88 -14
  83. data/lib/stripe/resources/issuing/card.rb +50 -16
  84. data/lib/stripe/resources/issuing/cardholder.rb +33 -0
  85. data/lib/stripe/resources/issuing/dispute.rb +35 -0
  86. data/lib/stripe/resources/issuing/personalization_design.rb +119 -0
  87. data/lib/stripe/resources/issuing/physical_bundle.rb +26 -0
  88. data/lib/stripe/resources/issuing/token.rb +18 -0
  89. data/lib/stripe/resources/issuing/transaction.rb +30 -0
  90. data/lib/stripe/resources/line_item.rb +3 -0
  91. data/lib/stripe/resources/login_link.rb +4 -1
  92. data/lib/stripe/resources/mandate.rb +3 -0
  93. data/lib/stripe/resources/payment_intent.rb +190 -25
  94. data/lib/stripe/resources/payment_link.rb +25 -0
  95. data/lib/stripe/resources/payment_method.rb +57 -4
  96. data/lib/stripe/resources/payment_method_configuration.rb +33 -0
  97. data/lib/stripe/resources/payment_method_domain.rb +46 -1
  98. data/lib/stripe/resources/payout.rb +39 -4
  99. data/lib/stripe/resources/person.rb +5 -4
  100. data/lib/stripe/resources/plan.rb +43 -0
  101. data/lib/stripe/resources/price.rb +24 -1
  102. data/lib/stripe/resources/product.rb +47 -1
  103. data/lib/stripe/resources/product_feature.rb +13 -0
  104. data/lib/stripe/resources/promotion_code.rb +23 -0
  105. data/lib/stripe/resources/quote.rb +67 -32
  106. data/lib/stripe/resources/radar/early_fraud_warning.rb +13 -0
  107. data/lib/stripe/resources/radar/value_list.rb +53 -0
  108. data/lib/stripe/resources/radar/value_list_item.rb +43 -0
  109. data/lib/stripe/resources/refund.rb +46 -0
  110. data/lib/stripe/resources/reporting/report_run.rb +23 -0
  111. data/lib/stripe/resources/reporting/report_type.rb +13 -0
  112. data/lib/stripe/resources/reversal.rb +5 -3
  113. data/lib/stripe/resources/review.rb +10 -0
  114. data/lib/stripe/resources/setup_attempt.rb +8 -0
  115. data/lib/stripe/resources/setup_intent.rb +72 -10
  116. data/lib/stripe/resources/shipping_rate.rb +23 -0
  117. data/lib/stripe/resources/sigma/scheduled_query_run.rb +13 -0
  118. data/lib/stripe/resources/source.rb +23 -1
  119. data/lib/stripe/resources/source_transaction.rb +3 -0
  120. data/lib/stripe/resources/subscription.rb +81 -13
  121. data/lib/stripe/resources/subscription_item.rb +54 -1
  122. data/lib/stripe/resources/subscription_schedule.rb +41 -4
  123. data/lib/stripe/resources/tax/calculation.rb +15 -0
  124. data/lib/stripe/resources/tax/calculation_line_item.rb +3 -0
  125. data/lib/stripe/resources/tax/registration.rb +35 -0
  126. data/lib/stripe/resources/tax/settings.rb +4 -2
  127. data/lib/stripe/resources/tax/transaction.rb +15 -8
  128. data/lib/stripe/resources/tax/transaction_line_item.rb +3 -0
  129. data/lib/stripe/resources/tax_code.rb +8 -0
  130. data/lib/stripe/resources/tax_id.rb +30 -12
  131. data/lib/stripe/resources/tax_rate.rb +23 -0
  132. data/lib/stripe/resources/terminal/configuration.rb +53 -0
  133. data/lib/stripe/resources/terminal/connection_token.rb +13 -0
  134. data/lib/stripe/resources/terminal/location.rb +54 -0
  135. data/lib/stripe/resources/terminal/reader.rb +80 -12
  136. data/lib/stripe/resources/test_helpers/test_clock.rb +45 -0
  137. data/lib/stripe/resources/token.rb +10 -1
  138. data/lib/stripe/resources/topup.rb +25 -0
  139. data/lib/stripe/resources/transfer.rb +26 -1
  140. data/lib/stripe/resources/treasury/credit_reversal.rb +23 -0
  141. data/lib/stripe/resources/treasury/debit_reversal.rb +23 -0
  142. data/lib/stripe/resources/treasury/financial_account.rb +42 -5
  143. data/lib/stripe/resources/treasury/financial_account_features.rb +3 -0
  144. data/lib/stripe/resources/treasury/inbound_transfer.rb +47 -11
  145. data/lib/stripe/resources/treasury/outbound_payment.rb +64 -8
  146. data/lib/stripe/resources/treasury/outbound_transfer.rb +64 -8
  147. data/lib/stripe/resources/treasury/received_credit.rb +17 -0
  148. data/lib/stripe/resources/treasury/received_debit.rb +17 -0
  149. data/lib/stripe/resources/treasury/transaction.rb +13 -0
  150. data/lib/stripe/resources/treasury/transaction_entry.rb +13 -0
  151. data/lib/stripe/resources/usage_record.rb +5 -0
  152. data/lib/stripe/resources/usage_record_summary.rb +3 -0
  153. data/lib/stripe/resources/webhook_endpoint.rb +55 -2
  154. data/lib/stripe/resources.rb +18 -0
  155. data/lib/stripe/search_result_object.rb +4 -1
  156. data/lib/stripe/singleton_api_resource.rb +20 -3
  157. data/lib/stripe/stripe_client.rb +61 -63
  158. data/lib/stripe/stripe_configuration.rb +13 -29
  159. data/lib/stripe/stripe_object.rb +23 -21
  160. data/lib/stripe/stripe_response.rb +1 -3
  161. data/lib/stripe/util.rb +13 -15
  162. data/lib/stripe/version.rb +1 -1
  163. data/lib/stripe.rb +26 -0
  164. data/stripe.gemspec +7 -4
  165. metadata +25 -5
@@ -8,6 +8,19 @@ module Stripe
8
8
  extend Stripe::APIOperations::List
9
9
 
10
10
  OBJECT_NAME = "treasury.transaction"
11
+ def self.object_name
12
+ "treasury.transaction"
13
+ end
14
+
15
+ # Retrieves a list of Transaction objects.
16
+ def self.list(filters = {}, opts = {})
17
+ request_stripe_object(
18
+ method: :get,
19
+ path: "/v1/treasury/transactions",
20
+ params: filters,
21
+ opts: opts
22
+ )
23
+ end
11
24
  end
12
25
  end
13
26
  end
@@ -8,6 +8,19 @@ module Stripe
8
8
  extend Stripe::APIOperations::List
9
9
 
10
10
  OBJECT_NAME = "treasury.transaction_entry"
11
+ def self.object_name
12
+ "treasury.transaction_entry"
13
+ end
14
+
15
+ # Retrieves a list of TransactionEntry objects.
16
+ def self.list(filters = {}, opts = {})
17
+ request_stripe_object(
18
+ method: :get,
19
+ path: "/v1/treasury/transaction_entries",
20
+ params: filters,
21
+ opts: opts
22
+ )
23
+ end
11
24
 
12
25
  def self.resource_url
13
26
  "/v1/treasury/transaction_entries"
@@ -6,7 +6,12 @@ module Stripe
6
6
  # metered billing of subscription prices.
7
7
  #
8
8
  # Related guide: [Metered billing](https://stripe.com/docs/billing/subscriptions/metered-billing)
9
+ #
10
+ # This is our legacy usage-based billing API. See the [updated usage-based billing docs](https://docs.stripe.com/billing/subscriptions/usage-based).
9
11
  class UsageRecord < APIResource
10
12
  OBJECT_NAME = "usage_record"
13
+ def self.object_name
14
+ "usage_record"
15
+ end
11
16
  end
12
17
  end
@@ -4,5 +4,8 @@
4
4
  module Stripe
5
5
  class UsageRecordSummary < StripeObject
6
6
  OBJECT_NAME = "usage_record_summary"
7
+ def self.object_name
8
+ "usage_record_summary"
9
+ end
7
10
  end
8
11
  end
@@ -2,13 +2,13 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Stripe
5
- # You can configure [webhook endpoints](https://stripe.com/docs/webhooks/) via the API to be
5
+ # You can configure [webhook endpoints](https://docs.stripe.com/webhooks/) via the API to be
6
6
  # notified about events that happen in your Stripe account or connected
7
7
  # accounts.
8
8
  #
9
9
  # Most users configure webhooks from [the dashboard](https://dashboard.stripe.com/webhooks), which provides a user interface for registering and testing your webhook endpoints.
10
10
  #
11
- # Related guide: [Setting up webhooks](https://stripe.com/docs/webhooks/configure)
11
+ # Related guide: [Setting up webhooks](https://docs.stripe.com/webhooks/configure)
12
12
  class WebhookEndpoint < APIResource
13
13
  extend Stripe::APIOperations::Create
14
14
  include Stripe::APIOperations::Delete
@@ -16,5 +16,58 @@ module Stripe
16
16
  include Stripe::APIOperations::Save
17
17
 
18
18
  OBJECT_NAME = "webhook_endpoint"
19
+ def self.object_name
20
+ "webhook_endpoint"
21
+ end
22
+
23
+ # A webhook endpoint must have a url and a list of enabled_events. You may optionally specify the Boolean connect parameter. If set to true, then a Connect webhook endpoint that notifies the specified url about events from all connected accounts is created; otherwise an account webhook endpoint that notifies the specified url only about events from your account is created. You can also create webhook endpoints in the [webhooks settings](https://dashboard.stripe.com/account/webhooks) section of the Dashboard.
24
+ def self.create(params = {}, opts = {})
25
+ request_stripe_object(
26
+ method: :post,
27
+ path: "/v1/webhook_endpoints",
28
+ params: params,
29
+ opts: opts
30
+ )
31
+ end
32
+
33
+ # You can also delete webhook endpoints via the [webhook endpoint management](https://dashboard.stripe.com/account/webhooks) page of the Stripe dashboard.
34
+ def self.delete(id, params = {}, opts = {})
35
+ request_stripe_object(
36
+ method: :delete,
37
+ path: format("/v1/webhook_endpoints/%<id>s", { id: CGI.escape(id) }),
38
+ params: params,
39
+ opts: opts
40
+ )
41
+ end
42
+
43
+ # You can also delete webhook endpoints via the [webhook endpoint management](https://dashboard.stripe.com/account/webhooks) page of the Stripe dashboard.
44
+ def delete(params = {}, opts = {})
45
+ request_stripe_object(
46
+ method: :delete,
47
+ path: format("/v1/webhook_endpoints/%<webhook_endpoint>s", { webhook_endpoint: CGI.escape(self["id"]) }),
48
+ params: params,
49
+ opts: opts
50
+ )
51
+ end
52
+
53
+ # Returns a list of your webhook endpoints.
54
+ def self.list(filters = {}, opts = {})
55
+ request_stripe_object(
56
+ method: :get,
57
+ path: "/v1/webhook_endpoints",
58
+ params: filters,
59
+ opts: opts
60
+ )
61
+ end
62
+
63
+ # Updates the webhook endpoint. You may edit the url, the list of enabled_events, and the status of your endpoint.
64
+ def self.update(id, params = {}, opts = {})
65
+ request_stripe_object(
66
+ method: :post,
67
+ path: format("/v1/webhook_endpoints/%<id>s", { id: CGI.escape(id) }),
68
+ params: params,
69
+ opts: opts
70
+ )
71
+ end
19
72
  end
20
73
  end
@@ -11,6 +11,11 @@ require "stripe/resources/apps/secret"
11
11
  require "stripe/resources/balance"
12
12
  require "stripe/resources/balance_transaction"
13
13
  require "stripe/resources/bank_account"
14
+ require "stripe/resources/billing/alert"
15
+ require "stripe/resources/billing/meter"
16
+ require "stripe/resources/billing/meter_event"
17
+ require "stripe/resources/billing/meter_event_adjustment"
18
+ require "stripe/resources/billing/meter_event_summary"
14
19
  require "stripe/resources/billing_portal/configuration"
15
20
  require "stripe/resources/billing_portal/session"
16
21
  require "stripe/resources/capability"
@@ -18,6 +23,10 @@ require "stripe/resources/card"
18
23
  require "stripe/resources/cash_balance"
19
24
  require "stripe/resources/charge"
20
25
  require "stripe/resources/checkout/session"
26
+ require "stripe/resources/climate/order"
27
+ require "stripe/resources/climate/product"
28
+ require "stripe/resources/climate/supplier"
29
+ require "stripe/resources/confirmation_token"
21
30
  require "stripe/resources/country_spec"
22
31
  require "stripe/resources/coupon"
23
32
  require "stripe/resources/credit_note"
@@ -25,8 +34,11 @@ require "stripe/resources/credit_note_line_item"
25
34
  require "stripe/resources/customer"
26
35
  require "stripe/resources/customer_balance_transaction"
27
36
  require "stripe/resources/customer_cash_balance_transaction"
37
+ require "stripe/resources/customer_session"
28
38
  require "stripe/resources/discount"
29
39
  require "stripe/resources/dispute"
40
+ require "stripe/resources/entitlements/active_entitlement"
41
+ require "stripe/resources/entitlements/feature"
30
42
  require "stripe/resources/ephemeral_key"
31
43
  require "stripe/resources/event"
32
44
  require "stripe/resources/exchange_rate"
@@ -36,16 +48,21 @@ require "stripe/resources/financial_connections/account"
36
48
  require "stripe/resources/financial_connections/account_owner"
37
49
  require "stripe/resources/financial_connections/account_ownership"
38
50
  require "stripe/resources/financial_connections/session"
51
+ require "stripe/resources/financial_connections/transaction"
52
+ require "stripe/resources/forwarding/request"
39
53
  require "stripe/resources/funding_instructions"
40
54
  require "stripe/resources/identity/verification_report"
41
55
  require "stripe/resources/identity/verification_session"
42
56
  require "stripe/resources/invoice"
43
57
  require "stripe/resources/invoice_item"
44
58
  require "stripe/resources/invoice_line_item"
59
+ require "stripe/resources/invoice_rendering_template"
45
60
  require "stripe/resources/issuing/authorization"
46
61
  require "stripe/resources/issuing/card"
47
62
  require "stripe/resources/issuing/cardholder"
48
63
  require "stripe/resources/issuing/dispute"
64
+ require "stripe/resources/issuing/personalization_design"
65
+ require "stripe/resources/issuing/physical_bundle"
49
66
  require "stripe/resources/issuing/token"
50
67
  require "stripe/resources/issuing/transaction"
51
68
  require "stripe/resources/line_item"
@@ -61,6 +78,7 @@ require "stripe/resources/person"
61
78
  require "stripe/resources/plan"
62
79
  require "stripe/resources/price"
63
80
  require "stripe/resources/product"
81
+ require "stripe/resources/product_feature"
64
82
  require "stripe/resources/promotion_code"
65
83
  require "stripe/resources/quote"
66
84
  require "stripe/resources/radar/early_fraud_warning"
@@ -7,6 +7,9 @@ module Stripe
7
7
  include Stripe::APIOperations::Request
8
8
 
9
9
  OBJECT_NAME = "search_result"
10
+ def self.object_name
11
+ "search_result"
12
+ end
10
13
 
11
14
  # This accessor allows a `SearchResultObject` to inherit various filters
12
15
  # that were given to a predecessor. This allows for things like consistent
@@ -80,7 +83,7 @@ module Stripe
80
83
 
81
84
  params = filters.merge(page: next_page).merge(params)
82
85
 
83
- _search(url, params, opts)
86
+ request_stripe_object(method: :get, path: url, params: params, opts: opts)
84
87
  end
85
88
  end
86
89
  end
@@ -10,15 +10,32 @@ module Stripe
10
10
  end
11
11
  # Namespaces are separated in object names with periods (.) and in URLs
12
12
  # with forward slashes (/), so replace the former with the latter.
13
- "/v1/#{self::OBJECT_NAME.downcase.tr('.', '/')}"
13
+ "/v1/#{object_name.downcase.tr('.', '/')}"
14
14
  end
15
15
 
16
16
  def resource_url
17
17
  self.class.resource_url
18
18
  end
19
19
 
20
- def self.retrieve(opts = {})
21
- instance = new(nil, Util.normalize_opts(opts))
20
+ def self.retrieve(params_or_opts = {}, definitely_opts = nil)
21
+ opts = nil
22
+ params = nil
23
+ if definitely_opts.nil?
24
+ unrecognized_key = params_or_opts.keys.find { |k| !Util::OPTS_USER_SPECIFIED.include?(k) }
25
+ if unrecognized_key
26
+ raise ArgumentError,
27
+ "Unrecognized request option: #{unrecognized_key}. Did you mean to specify this as retrieve params? " \
28
+ "If so, you must explicitly pass an opts hash as a second argument. " \
29
+ "For example: .retrieve({#{unrecognized_key}: 'foo'}, {})"
30
+ end
31
+
32
+ opts = params_or_opts
33
+ else
34
+ opts = definitely_opts
35
+ params = params_or_opts
36
+ end
37
+
38
+ instance = new(params, Util.normalize_opts(opts))
22
39
  instance.refresh
23
40
  instance
24
41
  end
@@ -18,6 +18,11 @@ module Stripe
18
18
  @system_profiler = SystemProfiler.new
19
19
  @last_request_metrics = nil
20
20
 
21
+ # The following attribute is only used to log whether or not
22
+ # StripeClient#request has been called. To be removed in a
23
+ # future major version.
24
+ @usage = []
25
+
21
26
  @config = case config_arg
22
27
  when Hash
23
28
  Stripe.config.reverse_duplicate_merge(config_arg)
@@ -36,8 +41,7 @@ module Stripe
36
41
  end
37
42
  end
38
43
 
39
- attr_reader :config
40
- attr_reader :options
44
+ attr_reader :config, :options
41
45
 
42
46
  # Gets a currently active `StripeClient`. Set for the current thread when
43
47
  # `StripeClient#request` is being run so that API operations being executed
@@ -80,9 +84,7 @@ module Stripe
80
84
  end
81
85
  end
82
86
 
83
- if thread_context.default_connection_managers.empty?
84
- pruned_contexts << thread_context
85
- end
87
+ pruned_contexts << thread_context if thread_context.default_connection_managers.empty?
86
88
  end
87
89
 
88
90
  @thread_contexts_with_connection_managers.subtract(pruned_contexts)
@@ -113,14 +115,14 @@ module Stripe
113
115
  # both socket errors that may represent an intermittent problem and some
114
116
  # special HTTP statuses.
115
117
  def self.should_retry?(error,
116
- method:, num_retries:, config: Stripe.config)
118
+ num_retries:, config: Stripe.config)
117
119
  return false if num_retries >= config.max_network_retries
118
120
 
119
121
  case error
120
122
  when Net::OpenTimeout, Net::ReadTimeout
121
123
  # Retry on timeout-related problems (either on open or read).
122
124
  true
123
- when EOFError, Errno::ECONNREFUSED, Errno::ECONNRESET,
125
+ when EOFError, Errno::ECONNREFUSED, Errno::ECONNRESET, # rubocop:todo Lint/DuplicateBranch
124
126
  Errno::EHOSTUNREACH, Errno::ETIMEDOUT, SocketError
125
127
  # Destination refused the connection, the connection was reset, or a
126
128
  # variety of other connection failures. This could occur from a single
@@ -146,15 +148,12 @@ module Stripe
146
148
  # These 429s are safe to retry.
147
149
  return true if error.http_status == 429 && error.code == "lock_timeout"
148
150
 
149
- # 500 Internal Server Error
151
+ # Retry on 500, 503, and other internal errors.
150
152
  #
151
- # We only bother retrying these for non-POST requests. POSTs end up
152
- # being cached by the idempotency layer so there's no purpose in
153
- # retrying them.
154
- return true if error.http_status == 500 && method != :post
155
-
156
- # 503 Service Unavailable
157
- error.http_status == 503
153
+ # Note that we expect the stripe-should-retry header to be false
154
+ # in most cases when a 500 is returned, since our idempotency framework
155
+ # would typically replay it anyway.
156
+ true if error.http_status >= 500
158
157
  else
159
158
  false
160
159
  end
@@ -191,7 +190,9 @@ module Stripe
191
190
  # client = StripeClient.new
192
191
  # charge, resp = client.request { Charge.create }
193
192
  #
193
+
194
194
  def request
195
+ @usage = ["stripe_client_request"]
195
196
  old_stripe_client = self.class.current_thread_context.active_client
196
197
  self.class.current_thread_context.active_client = self
197
198
 
@@ -206,15 +207,19 @@ module Stripe
206
207
  res = yield
207
208
  [res, self.class.current_thread_context.last_responses[object_id]]
208
209
  ensure
210
+ @usage = []
209
211
  self.class.current_thread_context.active_client = old_stripe_client
210
212
  self.class.current_thread_context.last_responses.delete(object_id)
211
213
  end
212
214
  end
215
+ deprecate :request, "the `last_response` property on the returned resource (see " \
216
+ "https://github.com/stripe/stripe-ruby?tab=readme-ov-file#accessing-a-response-object " \
217
+ "for usage examples)", 2024, 6
213
218
 
214
219
  def execute_request(method, path,
215
- api_base: nil, api_key: nil, headers: {}, params: {})
220
+ api_base: nil, api_key: nil, headers: {}, params: {}, usage: [])
216
221
  http_resp, api_key = execute_request_internal(
217
- method, path, api_base, api_key, headers, params
222
+ method, path, api_base, api_key, headers, params, usage
218
223
  )
219
224
 
220
225
  begin
@@ -243,7 +248,7 @@ module Stripe
243
248
  # passed, then a StripeStreamResponse is returned containing an IO stream
244
249
  # with the response body.
245
250
  def execute_request_stream(method, path,
246
- api_base: nil, api_key: nil,
251
+ api_base: nil, api_key: nil, usage: [],
247
252
  headers: {}, params: {},
248
253
  &read_body_chunk_block)
249
254
  unless block_given?
@@ -252,7 +257,7 @@ module Stripe
252
257
  end
253
258
 
254
259
  http_resp, api_key = execute_request_internal(
255
- method, path, api_base, api_key, headers, params, &read_body_chunk_block
260
+ method, path, api_base, api_key, headers, params, usage, &read_body_chunk_block
256
261
  )
257
262
 
258
263
  # When the read_body_chunk_block is given, we no longer have access to the
@@ -287,21 +292,21 @@ module Stripe
287
292
 
288
293
  ERROR_MESSAGE_CONNECTION =
289
294
  "Unexpected error communicating when trying to connect to " \
290
- "Stripe (%s). You may be seeing this message because your DNS is not " \
291
- "working or you don't have an internet connection. To check, try " \
292
- "running `host stripe.com` from the command line."
295
+ "Stripe (%s). You may be seeing this message because your DNS is not " \
296
+ "working or you don't have an internet connection. To check, try " \
297
+ "running `host stripe.com` from the command line."
293
298
  ERROR_MESSAGE_SSL =
294
299
  "Could not establish a secure connection to Stripe (%s), you " \
295
- "may need to upgrade your OpenSSL version. To check, try running " \
296
- "`openssl s_client -connect api.stripe.com:443` from the command " \
297
- "line."
300
+ "may need to upgrade your OpenSSL version. To check, try running " \
301
+ "`openssl s_client -connect api.stripe.com:443` from the command " \
302
+ "line."
298
303
 
299
304
  # Common error suffix sared by both connect and read timeout messages.
300
305
  ERROR_MESSAGE_TIMEOUT_SUFFIX =
301
306
  "Please check your internet connection and try again. " \
302
- "If this problem persists, you should check Stripe's service " \
303
- "status at https://status.stripe.com, or let us know at " \
304
- "support@stripe.com."
307
+ "If this problem persists, you should check Stripe's service " \
308
+ "status at https://status.stripe.com, or let us know at " \
309
+ "support@stripe.com."
305
310
 
306
311
  ERROR_MESSAGE_TIMEOUT_CONNECT = (
307
312
  "Timed out connecting to Stripe (%s). " +
@@ -361,7 +366,7 @@ module Stripe
361
366
  # garbage in `Thread.current`.
362
367
  attr_accessor :last_responses
363
368
 
364
- # A map of connection mangers for the thread. Normally shared between
369
+ # A map of connection managers for the thread. Normally shared between
365
370
  # all `StripeClient` objects on a particular thread, and created so as to
366
371
  # minimize the number of open connections that an application needs.
367
372
  def default_connection_managers
@@ -431,7 +436,7 @@ module Stripe
431
436
  end
432
437
 
433
438
  private def execute_request_internal(method, path,
434
- api_base, api_key, headers, params,
439
+ api_base, api_key, headers, params, usage,
435
440
  &read_body_chunk_block)
436
441
  raise ArgumentError, "method should be a symbol" \
437
442
  unless method.is_a?(Symbol)
@@ -457,6 +462,7 @@ module Stripe
457
462
 
458
463
  headers = request_headers(api_key, method)
459
464
  .update(Util.normalize_headers(headers))
465
+
460
466
  url = api_url(path, api_base)
461
467
 
462
468
  # Merge given query parameters with any already encoded in the path.
@@ -488,14 +494,12 @@ module Stripe
488
494
  response_block =
489
495
  if block_given?
490
496
  lambda do |response|
491
- unless should_handle_as_error(response.code.to_i)
492
- response.read_body(&read_body_chunk_block)
493
- end
497
+ response.read_body(&read_body_chunk_block) unless should_handle_as_error(response.code.to_i)
494
498
  end
495
499
  end
496
500
 
497
501
  http_resp =
498
- execute_request_with_rescues(method, api_base, headers, context) do
502
+ execute_request_with_rescues(api_base, headers, usage, context) do
499
503
  self.class
500
504
  .default_connection_manager(config)
501
505
  .execute_request(method, url,
@@ -515,18 +519,18 @@ module Stripe
515
519
  private def check_api_key!(api_key)
516
520
  unless api_key
517
521
  raise AuthenticationError, "No API key provided. " \
518
- 'Set your API key using "Stripe.api_key = <API-KEY>". ' \
519
- "You can generate API keys from the Stripe web interface. " \
520
- "See https://stripe.com/api for details, or email " \
521
- "support@stripe.com if you have any questions."
522
+ 'Set your API key using "Stripe.api_key = <API-KEY>". ' \
523
+ "You can generate API keys from the Stripe web interface. " \
524
+ "See https://stripe.com/api for details, or email " \
525
+ "support@stripe.com if you have any questions."
522
526
  end
523
527
 
524
528
  return unless api_key =~ /\s/
525
529
 
526
530
  raise AuthenticationError, "Your API key is invalid, as it contains " \
527
- "whitespace. (HINT: You can double-check your API key from the " \
528
- "Stripe web interface. See https://stripe.com/api for details, or " \
529
- "email support@stripe.com if you have any questions.)"
531
+ "whitespace. (HINT: You can double-check your API key from the " \
532
+ "Stripe web interface. See https://stripe.com/api for details, or " \
533
+ "email support@stripe.com if you have any questions.)"
530
534
  end
531
535
 
532
536
  # Encodes a set of body parameters using multipart if `Content-Type` is set
@@ -565,7 +569,7 @@ module Stripe
565
569
  http_status >= 400
566
570
  end
567
571
 
568
- private def execute_request_with_rescues(method, api_base, headers, context)
572
+ private def execute_request_with_rescues(api_base, headers, usage, context)
569
573
  num_retries = 0
570
574
 
571
575
  begin
@@ -582,9 +586,7 @@ module Stripe
582
586
  http_status = resp.code.to_i
583
587
  context = context.dup_from_response_headers(resp)
584
588
 
585
- if should_handle_as_error(http_status)
586
- handle_error_response(resp, context)
587
- end
589
+ handle_error_response(resp, context) if should_handle_as_error(http_status)
588
590
 
589
591
  log_response(context, request_start, http_status, resp.body, resp)
590
592
  notify_request_end(context, request_duration, http_status,
@@ -593,7 +595,7 @@ module Stripe
593
595
  if config.enable_telemetry? && context.request_id
594
596
  request_duration_ms = (request_duration * 1000).to_i
595
597
  @last_request_metrics =
596
- StripeRequestMetrics.new(context.request_id, request_duration_ms)
598
+ StripeRequestMetrics.new(context.request_id, request_duration_ms, usage: usage + @usage)
597
599
  end
598
600
 
599
601
  # We rescue all exceptions from a request so that we have an easy spot to
@@ -618,7 +620,6 @@ module Stripe
618
620
  user_data, resp, headers)
619
621
 
620
622
  if self.class.should_retry?(e,
621
- method: method,
622
623
  num_retries: num_retries,
623
624
  config: config)
624
625
  num_retries += 1
@@ -634,7 +635,7 @@ module Stripe
634
635
 
635
636
  # Only handle errors when we know we can do so, and re-raise otherwise.
636
637
  # This should be pretty infrequent.
637
- else
638
+ else # rubocop:todo Lint/DuplicateBranch
638
639
  raise
639
640
  end
640
641
  end
@@ -844,7 +845,7 @@ module Stripe
844
845
 
845
846
  if errors.nil?
846
847
  message = "Unexpected error #{error.class.name} communicating " \
847
- "with Stripe. Please let us know at support@stripe.com."
848
+ "with Stripe. Please let us know at support@stripe.com."
848
849
  end
849
850
 
850
851
  api_base ||= config.api_base
@@ -858,9 +859,7 @@ module Stripe
858
859
 
859
860
  private def request_headers(api_key, method)
860
861
  user_agent = "Stripe/v1 RubyBindings/#{Stripe::VERSION}"
861
- unless Stripe.app_info.nil?
862
- user_agent += " " + format_app_info(Stripe.app_info)
863
- end
862
+ user_agent += " " + format_app_info(Stripe.app_info) unless Stripe.app_info.nil?
864
863
 
865
864
  headers = {
866
865
  "User-Agent" => user_agent,
@@ -881,6 +880,7 @@ module Stripe
881
880
  end
882
881
 
883
882
  headers["Stripe-Version"] = config.api_version if config.api_version
883
+
884
884
  headers["Stripe-Account"] = config.stripe_account if config.stripe_account
885
885
 
886
886
  user_agent = @system_profiler.user_agent
@@ -963,15 +963,7 @@ module Stripe
963
963
  # that we can log certain information. It's useful because it means that we
964
964
  # don't have to pass around as many parameters.
965
965
  class RequestLogContext
966
- attr_accessor :body
967
- attr_accessor :account
968
- attr_accessor :api_key
969
- attr_accessor :api_version
970
- attr_accessor :idempotency_key
971
- attr_accessor :method
972
- attr_accessor :path
973
- attr_accessor :query
974
- attr_accessor :request_id
966
+ attr_accessor :body, :account, :api_key, :api_version, :idempotency_key, :method, :path, :query, :request_id
975
967
 
976
968
  # The idea with this method is that we might want to update some of
977
969
  # context information because a response that we've received from the API
@@ -1055,13 +1047,19 @@ module Stripe
1055
1047
  # Request duration in milliseconds
1056
1048
  attr_accessor :request_duration_ms
1057
1049
 
1058
- def initialize(request_id, request_duration_ms)
1050
+ # list of names of tracked behaviors associated with this request
1051
+ attr_accessor :usage
1052
+
1053
+ def initialize(request_id, request_duration_ms, usage: [])
1059
1054
  self.request_id = request_id
1060
1055
  self.request_duration_ms = request_duration_ms
1056
+ self.usage = usage
1061
1057
  end
1062
1058
 
1063
1059
  def payload
1064
- { request_id: request_id, request_duration_ms: request_duration_ms }
1060
+ ret = { request_id: request_id, request_duration_ms: request_duration_ms }
1061
+ ret[:usage] = usage if !usage.nil? && !usage.empty?
1062
+ ret
1065
1063
  end
1066
1064
  end
1067
1065
  end
@@ -25,26 +25,12 @@ module Stripe
25
25
  # If `.logger` is set, the value of `.log_level` is ignored. The decision on
26
26
  # what levels to print is entirely deferred to the logger.
27
27
  class StripeConfiguration
28
- attr_accessor :api_key
29
- attr_accessor :api_version
30
- attr_accessor :client_id
31
- attr_accessor :enable_telemetry
32
- attr_accessor :logger
33
- attr_accessor :stripe_account
34
-
35
- attr_reader :api_base
36
- attr_reader :uploads_base
37
- attr_reader :connect_base
38
- attr_reader :ca_bundle_path
39
- attr_reader :log_level
40
- attr_reader :initial_network_retry_delay
41
- attr_reader :max_network_retries
42
- attr_reader :max_network_retry_delay
43
- attr_reader :open_timeout
44
- attr_reader :read_timeout
45
- attr_reader :write_timeout
46
- attr_reader :proxy
47
- attr_reader :verify_ssl_certs
28
+ attr_accessor :api_key, :api_version, :client_id, :enable_telemetry, :logger, :stripe_account
29
+
30
+ attr_reader :api_base, :uploads_base, :connect_base, :ca_bundle_path, :log_level, :initial_network_retry_delay,
31
+ # rubocop:todo Layout/LineLength
32
+ :max_network_retries, :max_network_retry_delay, :open_timeout, :read_timeout, :write_timeout, :proxy, :verify_ssl_certs
33
+ # rubocop:enable Layout/LineLength
48
34
 
49
35
  def self.setup
50
36
  new.tap do |instance|
@@ -95,8 +81,8 @@ module Stripe
95
81
 
96
82
  if !val.nil? && !levels.include?(val)
97
83
  raise ArgumentError,
98
- "log_level should only be set to `nil`, `debug`, `info`," \
99
- " or `error`"
84
+ "log_level should only be set to `nil`, `debug`, `info`, " \
85
+ "or `error`"
100
86
  end
101
87
  @log_level = val
102
88
  end
@@ -124,9 +110,7 @@ module Stripe
124
110
  end
125
111
 
126
112
  def write_timeout=(write_timeout)
127
- unless Net::HTTP.instance_methods.include?(:write_timeout=)
128
- raise NotImplementedError
129
- end
113
+ raise NotImplementedError unless Net::HTTP.instance_methods.include?(:write_timeout=)
130
114
 
131
115
  @write_timeout = write_timeout
132
116
  StripeClient.clear_all_connection_managers(config: self)
@@ -177,10 +161,10 @@ module Stripe
177
161
  # and is itself not thread safe.
178
162
  def ca_store
179
163
  @ca_store ||= begin
180
- store = OpenSSL::X509::Store.new
181
- store.add_file(ca_bundle_path)
182
- store
183
- end
164
+ store = OpenSSL::X509::Store.new
165
+ store.add_file(ca_bundle_path)
166
+ store
167
+ end
184
168
  end
185
169
 
186
170
  def enable_telemetry?