stripe 10.3.0 → 10.4.0.pre.beta.1

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 (41) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +247 -40
  3. data/OPENAPI_VERSION +1 -1
  4. data/README.md +11 -0
  5. data/VERSION +1 -1
  6. data/lib/stripe/api_operations/request.rb +2 -1
  7. data/lib/stripe/api_version.rb +1 -0
  8. data/lib/stripe/object_types.rb +21 -0
  9. data/lib/stripe/request_signing_authenticator.rb +79 -0
  10. data/lib/stripe/resources/account_notice.rb +14 -0
  11. data/lib/stripe/resources/capital/financing_offer.rb +32 -0
  12. data/lib/stripe/resources/capital/financing_summary.rb +12 -0
  13. data/lib/stripe/resources/capital/financing_transaction.rb +13 -0
  14. data/lib/stripe/resources/confirmation_token.rb +11 -0
  15. data/lib/stripe/resources/customer_session.rb +12 -0
  16. data/lib/stripe/resources/financial_connections/account.rb +39 -0
  17. data/lib/stripe/resources/financial_connections/account_inferred_balance.rb +13 -0
  18. data/lib/stripe/resources/financial_connections/transaction.rb +13 -0
  19. data/lib/stripe/resources/gift_cards/card.rb +25 -0
  20. data/lib/stripe/resources/gift_cards/transaction.rb +56 -0
  21. data/lib/stripe/resources/invoice.rb +21 -0
  22. data/lib/stripe/resources/invoice_payment.rb +11 -0
  23. data/lib/stripe/resources/issuing/credit_underwriting_record.rb +69 -0
  24. data/lib/stripe/resources/issuing/personalization_design.rb +77 -0
  25. data/lib/stripe/resources/issuing/physical_bundle.rb +13 -0
  26. data/lib/stripe/resources/margin.rb +14 -0
  27. data/lib/stripe/resources/order.rb +89 -0
  28. data/lib/stripe/resources/quote.rb +94 -0
  29. data/lib/stripe/resources/quote_phase.rb +29 -0
  30. data/lib/stripe/resources/quote_preview_invoice.rb +42 -0
  31. data/lib/stripe/resources/quote_preview_subscription_schedule.rb +10 -0
  32. data/lib/stripe/resources/subscription_schedule.rb +18 -0
  33. data/lib/stripe/resources/tax/form.rb +39 -0
  34. data/lib/stripe/resources/terminal/reader.rb +54 -0
  35. data/lib/stripe/resources.rb +20 -0
  36. data/lib/stripe/stripe_client.rb +62 -28
  37. data/lib/stripe/stripe_configuration.rb +2 -1
  38. data/lib/stripe/util.rb +8 -1
  39. data/lib/stripe/version.rb +1 -1
  40. data/lib/stripe.rb +46 -0
  41. metadata +25 -4
@@ -8,9 +8,13 @@ module Stripe
8
8
  extend Stripe::APIOperations::Create
9
9
  extend Stripe::APIOperations::List
10
10
  include Stripe::APIOperations::Save
11
+ extend Stripe::APIOperations::NestedResource
11
12
 
12
13
  OBJECT_NAME = "quote"
13
14
 
15
+ nested_resource_class_methods :preview_invoice, operations: %i[list]
16
+ nested_resource_class_methods :preview_subscription_schedule, operations: %i[list]
17
+
14
18
  def accept(params = {}, opts = {})
15
19
  request_stripe_object(
16
20
  method: :post,
@@ -56,6 +60,42 @@ module Stripe
56
60
  )
57
61
  end
58
62
 
63
+ def list_lines(params = {}, opts = {})
64
+ request_stripe_object(
65
+ method: :get,
66
+ path: format("/v1/quotes/%<quote>s/lines", { quote: CGI.escape(self["id"]) }),
67
+ params: params,
68
+ opts: opts
69
+ )
70
+ end
71
+
72
+ def list_preview_invoice_lines(preview_invoice, params = {}, opts = {})
73
+ request_stripe_object(
74
+ method: :get,
75
+ path: format("/v1/quotes/%<quote>s/preview_invoices/%<preview_invoice>s/lines", { quote: CGI.escape(self["id"]), preview_invoice: CGI.escape(preview_invoice) }),
76
+ params: params,
77
+ opts: opts
78
+ )
79
+ end
80
+
81
+ def mark_draft(params = {}, opts = {})
82
+ request_stripe_object(
83
+ method: :post,
84
+ path: format("/v1/quotes/%<quote>s/mark_draft", { quote: CGI.escape(self["id"]) }),
85
+ params: params,
86
+ opts: opts
87
+ )
88
+ end
89
+
90
+ def mark_stale(params = {}, opts = {})
91
+ request_stripe_object(
92
+ method: :post,
93
+ path: format("/v1/quotes/%<quote>s/mark_stale", { quote: CGI.escape(self["id"]) }),
94
+ params: params,
95
+ opts: opts
96
+ )
97
+ end
98
+
59
99
  def pdf(params = {}, opts = {}, &read_body_chunk_block)
60
100
  config = opts[:client]&.config || Stripe.config
61
101
  opts = { api_base: config.uploads_base }.merge(opts)
@@ -68,6 +108,15 @@ module Stripe
68
108
  )
69
109
  end
70
110
 
111
+ def reestimate(params = {}, opts = {})
112
+ request_stripe_object(
113
+ method: :post,
114
+ path: format("/v1/quotes/%<quote>s/reestimate", { quote: CGI.escape(self["id"]) }),
115
+ params: params,
116
+ opts: opts
117
+ )
118
+ end
119
+
71
120
  def self.accept(quote, params = {}, opts = {})
72
121
  request_stripe_object(
73
122
  method: :post,
@@ -113,6 +162,42 @@ module Stripe
113
162
  )
114
163
  end
115
164
 
165
+ def self.list_lines(quote, params = {}, opts = {})
166
+ request_stripe_object(
167
+ method: :get,
168
+ path: format("/v1/quotes/%<quote>s/lines", { quote: CGI.escape(quote) }),
169
+ params: params,
170
+ opts: opts
171
+ )
172
+ end
173
+
174
+ def self.list_preview_invoice_lines(quote, preview_invoice, params = {}, opts = {})
175
+ request_stripe_object(
176
+ method: :get,
177
+ path: format("/v1/quotes/%<quote>s/preview_invoices/%<preview_invoice>s/lines", { quote: CGI.escape(quote), preview_invoice: CGI.escape(preview_invoice) }),
178
+ params: params,
179
+ opts: opts
180
+ )
181
+ end
182
+
183
+ def self.mark_draft(quote, params = {}, opts = {})
184
+ request_stripe_object(
185
+ method: :post,
186
+ path: format("/v1/quotes/%<quote>s/mark_draft", { quote: CGI.escape(quote) }),
187
+ params: params,
188
+ opts: opts
189
+ )
190
+ end
191
+
192
+ def self.mark_stale(quote, params = {}, opts = {})
193
+ request_stripe_object(
194
+ method: :post,
195
+ path: format("/v1/quotes/%<quote>s/mark_stale", { quote: CGI.escape(quote) }),
196
+ params: params,
197
+ opts: opts
198
+ )
199
+ end
200
+
116
201
  def self.pdf(quote, params = {}, opts = {}, &read_body_chunk_block)
117
202
  config = opts[:client]&.config || Stripe.config
118
203
  opts = { api_base: config.uploads_base }.merge(opts)
@@ -124,5 +209,14 @@ module Stripe
124
209
  &read_body_chunk_block
125
210
  )
126
211
  end
212
+
213
+ def self.reestimate(quote, params = {}, opts = {})
214
+ request_stripe_object(
215
+ method: :post,
216
+ path: format("/v1/quotes/%<quote>s/reestimate", { quote: CGI.escape(quote) }),
217
+ params: params,
218
+ opts: opts
219
+ )
220
+ end
127
221
  end
128
222
  end
@@ -0,0 +1,29 @@
1
+ # File generated from our OpenAPI spec
2
+ # frozen_string_literal: true
3
+
4
+ module Stripe
5
+ # A quote phase describes the line items, coupons, and trialing status of a subscription for a predefined time period.
6
+ class QuotePhase < APIResource
7
+ extend Stripe::APIOperations::List
8
+
9
+ OBJECT_NAME = "quote_phase"
10
+
11
+ def list_line_items(params = {}, opts = {})
12
+ request_stripe_object(
13
+ method: :get,
14
+ path: format("/v1/quote_phases/%<quote_phase>s/line_items", { quote_phase: CGI.escape(self["id"]) }),
15
+ params: params,
16
+ opts: opts
17
+ )
18
+ end
19
+
20
+ def self.list_line_items(quote_phase, params = {}, opts = {})
21
+ request_stripe_object(
22
+ method: :get,
23
+ path: format("/v1/quote_phases/%<quote_phase>s/line_items", { quote_phase: CGI.escape(quote_phase) }),
24
+ params: params,
25
+ opts: opts
26
+ )
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,42 @@
1
+ # File generated from our OpenAPI spec
2
+ # frozen_string_literal: true
3
+
4
+ module Stripe
5
+ # Invoices are statements of amounts owed by a customer, and are either
6
+ # generated one-off, or generated periodically from a subscription.
7
+ #
8
+ # They contain [invoice items](https://stripe.com/docs/api#invoiceitems), and proration adjustments
9
+ # that may be caused by subscription upgrades/downgrades (if necessary).
10
+ #
11
+ # If your invoice is configured to be billed through automatic charges,
12
+ # Stripe automatically finalizes your invoice and attempts payment. Note
13
+ # that finalizing the invoice,
14
+ # [when automatic](https://stripe.com/docs/invoicing/integration/automatic-advancement-collection), does
15
+ # not happen immediately as the invoice is created. Stripe waits
16
+ # until one hour after the last webhook was successfully sent (or the last
17
+ # webhook timed out after failing). If you (and the platforms you may have
18
+ # connected to) have no webhooks configured, Stripe waits one hour after
19
+ # creation to finalize the invoice.
20
+ #
21
+ # If your invoice is configured to be billed by sending an email, then based on your
22
+ # [email settings](https://dashboard.stripe.com/account/billing/automatic),
23
+ # Stripe will email the invoice to your customer and await payment. These
24
+ # emails can contain a link to a hosted page to pay the invoice.
25
+ #
26
+ # Stripe applies any customer credit on the account before determining the
27
+ # amount due for the invoice (i.e., the amount that will be actually
28
+ # charged). If the amount due for the invoice is less than Stripe's [minimum allowed charge
29
+ # per currency](https://stripe.com/docs/currencies#minimum-and-maximum-charge-amounts), the
30
+ # invoice is automatically marked paid, and we add the amount due to the
31
+ # customer's credit balance which is applied to the next invoice.
32
+ #
33
+ # More details on the customer's credit balance are
34
+ # [here](https://stripe.com/docs/billing/customer/balance).
35
+ #
36
+ # Related guide: [Send invoices to customers](https://stripe.com/docs/billing/invoices/sending)
37
+ class QuotePreviewInvoice < APIResource
38
+ extend Stripe::APIOperations::List
39
+
40
+ OBJECT_NAME = "quote_preview_invoice"
41
+ end
42
+ end
@@ -0,0 +1,10 @@
1
+ # File generated from our OpenAPI spec
2
+ # frozen_string_literal: true
3
+
4
+ module Stripe
5
+ class QuotePreviewSubscriptionSchedule < APIResource
6
+ extend Stripe::APIOperations::List
7
+
8
+ OBJECT_NAME = "quote_preview_subscription_schedule"
9
+ end
10
+ end
@@ -12,6 +12,15 @@ module Stripe
12
12
 
13
13
  OBJECT_NAME = "subscription_schedule"
14
14
 
15
+ def amend(params = {}, opts = {})
16
+ request_stripe_object(
17
+ method: :post,
18
+ path: format("/v1/subscription_schedules/%<schedule>s/amend", { schedule: CGI.escape(self["id"]) }),
19
+ params: params,
20
+ opts: opts
21
+ )
22
+ end
23
+
15
24
  def cancel(params = {}, opts = {})
16
25
  request_stripe_object(
17
26
  method: :post,
@@ -30,6 +39,15 @@ module Stripe
30
39
  )
31
40
  end
32
41
 
42
+ def self.amend(schedule, params = {}, opts = {})
43
+ request_stripe_object(
44
+ method: :post,
45
+ path: format("/v1/subscription_schedules/%<schedule>s/amend", { schedule: CGI.escape(schedule) }),
46
+ params: params,
47
+ opts: opts
48
+ )
49
+ end
50
+
33
51
  def self.cancel(schedule, params = {}, opts = {})
34
52
  request_stripe_object(
35
53
  method: :post,
@@ -0,0 +1,39 @@
1
+ # File generated from our OpenAPI spec
2
+ # frozen_string_literal: true
3
+
4
+ module Stripe
5
+ module Tax
6
+ # Tax forms are legal documents which are delivered to one or more tax authorities for information reporting purposes.
7
+ #
8
+ # Related guide: [US tax reporting for Connect platforms](https://stripe.com/docs/connect/tax-reporting)
9
+ class Form < APIResource
10
+ extend Stripe::APIOperations::List
11
+
12
+ OBJECT_NAME = "tax.form"
13
+
14
+ def pdf(params = {}, opts = {}, &read_body_chunk_block)
15
+ config = opts[:client]&.config || Stripe.config
16
+ opts = { api_base: config.uploads_base }.merge(opts)
17
+ request_stream(
18
+ method: :get,
19
+ path: format("/v1/tax/forms/%<id>s/pdf", { id: CGI.escape(self["id"]) }),
20
+ params: params,
21
+ opts: opts,
22
+ &read_body_chunk_block
23
+ )
24
+ end
25
+
26
+ def self.pdf(id, params = {}, opts = {}, &read_body_chunk_block)
27
+ config = opts[:client]&.config || Stripe.config
28
+ opts = { api_base: config.uploads_base }.merge(opts)
29
+ execute_resource_request_stream(
30
+ :get,
31
+ format("/v1/tax/forms/%<id>s/pdf", { id: CGI.escape(id) }),
32
+ params,
33
+ opts,
34
+ &read_body_chunk_block
35
+ )
36
+ end
37
+ end
38
+ end
39
+ end
@@ -23,6 +23,33 @@ module Stripe
23
23
  )
24
24
  end
25
25
 
26
+ def collect_inputs(params = {}, opts = {})
27
+ request_stripe_object(
28
+ method: :post,
29
+ path: format("/v1/terminal/readers/%<reader>s/collect_inputs", { reader: CGI.escape(self["id"]) }),
30
+ params: params,
31
+ opts: opts
32
+ )
33
+ end
34
+
35
+ def collect_payment_method(params = {}, opts = {})
36
+ request_stripe_object(
37
+ method: :post,
38
+ path: format("/v1/terminal/readers/%<reader>s/collect_payment_method", { reader: CGI.escape(self["id"]) }),
39
+ params: params,
40
+ opts: opts
41
+ )
42
+ end
43
+
44
+ def confirm_payment_intent(params = {}, opts = {})
45
+ request_stripe_object(
46
+ method: :post,
47
+ path: format("/v1/terminal/readers/%<reader>s/confirm_payment_intent", { reader: CGI.escape(self["id"]) }),
48
+ params: params,
49
+ opts: opts
50
+ )
51
+ end
52
+
26
53
  def process_payment_intent(params = {}, opts = {})
27
54
  request_stripe_object(
28
55
  method: :post,
@@ -68,6 +95,33 @@ module Stripe
68
95
  )
69
96
  end
70
97
 
98
+ def self.collect_inputs(reader, params = {}, opts = {})
99
+ request_stripe_object(
100
+ method: :post,
101
+ path: format("/v1/terminal/readers/%<reader>s/collect_inputs", { reader: CGI.escape(reader) }),
102
+ params: params,
103
+ opts: opts
104
+ )
105
+ end
106
+
107
+ def self.collect_payment_method(reader, params = {}, opts = {})
108
+ request_stripe_object(
109
+ method: :post,
110
+ path: format("/v1/terminal/readers/%<reader>s/collect_payment_method", { reader: CGI.escape(reader) }),
111
+ params: params,
112
+ opts: opts
113
+ )
114
+ end
115
+
116
+ def self.confirm_payment_intent(reader, params = {}, opts = {})
117
+ request_stripe_object(
118
+ method: :post,
119
+ path: format("/v1/terminal/readers/%<reader>s/confirm_payment_intent", { reader: CGI.escape(reader) }),
120
+ params: params,
121
+ opts: opts
122
+ )
123
+ end
124
+
71
125
  def self.process_payment_intent(reader, params = {}, opts = {})
72
126
  request_stripe_object(
73
127
  method: :post,
@@ -3,6 +3,7 @@
3
3
 
4
4
  require "stripe/resources/account"
5
5
  require "stripe/resources/account_link"
6
+ require "stripe/resources/account_notice"
6
7
  require "stripe/resources/account_session"
7
8
  require "stripe/resources/apple_pay_domain"
8
9
  require "stripe/resources/application_fee"
@@ -14,6 +15,9 @@ require "stripe/resources/bank_account"
14
15
  require "stripe/resources/billing_portal/configuration"
15
16
  require "stripe/resources/billing_portal/session"
16
17
  require "stripe/resources/capability"
18
+ require "stripe/resources/capital/financing_offer"
19
+ require "stripe/resources/capital/financing_summary"
20
+ require "stripe/resources/capital/financing_transaction"
17
21
  require "stripe/resources/card"
18
22
  require "stripe/resources/cash_balance"
19
23
  require "stripe/resources/charge"
@@ -21,6 +25,7 @@ require "stripe/resources/checkout/session"
21
25
  require "stripe/resources/climate/order"
22
26
  require "stripe/resources/climate/product"
23
27
  require "stripe/resources/climate/supplier"
28
+ require "stripe/resources/confirmation_token"
24
29
  require "stripe/resources/country_spec"
25
30
  require "stripe/resources/coupon"
26
31
  require "stripe/resources/credit_note"
@@ -28,6 +33,7 @@ require "stripe/resources/credit_note_line_item"
28
33
  require "stripe/resources/customer"
29
34
  require "stripe/resources/customer_balance_transaction"
30
35
  require "stripe/resources/customer_cash_balance_transaction"
36
+ require "stripe/resources/customer_session"
31
37
  require "stripe/resources/discount"
32
38
  require "stripe/resources/dispute"
33
39
  require "stripe/resources/ephemeral_key"
@@ -36,24 +42,34 @@ require "stripe/resources/exchange_rate"
36
42
  require "stripe/resources/file"
37
43
  require "stripe/resources/file_link"
38
44
  require "stripe/resources/financial_connections/account"
45
+ require "stripe/resources/financial_connections/account_inferred_balance"
39
46
  require "stripe/resources/financial_connections/account_owner"
40
47
  require "stripe/resources/financial_connections/account_ownership"
41
48
  require "stripe/resources/financial_connections/session"
49
+ require "stripe/resources/financial_connections/transaction"
42
50
  require "stripe/resources/funding_instructions"
51
+ require "stripe/resources/gift_cards/card"
52
+ require "stripe/resources/gift_cards/transaction"
43
53
  require "stripe/resources/identity/verification_report"
44
54
  require "stripe/resources/identity/verification_session"
45
55
  require "stripe/resources/invoice"
46
56
  require "stripe/resources/invoice_item"
47
57
  require "stripe/resources/invoice_line_item"
58
+ require "stripe/resources/invoice_payment"
48
59
  require "stripe/resources/issuing/authorization"
49
60
  require "stripe/resources/issuing/card"
50
61
  require "stripe/resources/issuing/cardholder"
62
+ require "stripe/resources/issuing/credit_underwriting_record"
51
63
  require "stripe/resources/issuing/dispute"
64
+ require "stripe/resources/issuing/personalization_design"
65
+ require "stripe/resources/issuing/physical_bundle"
52
66
  require "stripe/resources/issuing/token"
53
67
  require "stripe/resources/issuing/transaction"
54
68
  require "stripe/resources/line_item"
55
69
  require "stripe/resources/login_link"
56
70
  require "stripe/resources/mandate"
71
+ require "stripe/resources/margin"
72
+ require "stripe/resources/order"
57
73
  require "stripe/resources/payment_intent"
58
74
  require "stripe/resources/payment_link"
59
75
  require "stripe/resources/payment_method"
@@ -66,6 +82,9 @@ require "stripe/resources/price"
66
82
  require "stripe/resources/product"
67
83
  require "stripe/resources/promotion_code"
68
84
  require "stripe/resources/quote"
85
+ require "stripe/resources/quote_phase"
86
+ require "stripe/resources/quote_preview_invoice"
87
+ require "stripe/resources/quote_preview_subscription_schedule"
69
88
  require "stripe/resources/radar/early_fraud_warning"
70
89
  require "stripe/resources/radar/value_list"
71
90
  require "stripe/resources/radar/value_list_item"
@@ -85,6 +104,7 @@ require "stripe/resources/subscription_item"
85
104
  require "stripe/resources/subscription_schedule"
86
105
  require "stripe/resources/tax/calculation"
87
106
  require "stripe/resources/tax/calculation_line_item"
107
+ require "stripe/resources/tax/form"
88
108
  require "stripe/resources/tax/registration"
89
109
  require "stripe/resources/tax/settings"
90
110
  require "stripe/resources/tax/transaction"
@@ -209,9 +209,10 @@ module Stripe
209
209
  end
210
210
 
211
211
  def execute_request(method, path,
212
- api_base: nil, api_key: nil, headers: {}, params: {}, usage: [])
212
+ api_base: nil, api_key: nil,
213
+ headers: {}, params: {}, api_mode: nil, usage: [])
213
214
  http_resp, api_key = execute_request_internal(
214
- method, path, api_base, api_key, headers, params, usage
215
+ method, path, api_base, api_key, headers, params, api_mode, usage
215
216
  )
216
217
 
217
218
  begin
@@ -242,6 +243,7 @@ module Stripe
242
243
  def execute_request_stream(method, path,
243
244
  api_base: nil, api_key: nil, usage: [],
244
245
  headers: {}, params: {},
246
+ api_mode: nil,
245
247
  &read_body_chunk_block)
246
248
  unless block_given?
247
249
  raise ArgumentError,
@@ -249,7 +251,8 @@ module Stripe
249
251
  end
250
252
 
251
253
  http_resp, api_key = execute_request_internal(
252
- method, path, api_base, api_key, headers, params, usage, &read_body_chunk_block
254
+ method, path, api_base, api_key,
255
+ headers, params, api_mode, usage, &read_body_chunk_block
253
256
  )
254
257
 
255
258
  # When the read_body_chunk_block is given, we no longer have access to the
@@ -428,8 +431,8 @@ module Stripe
428
431
  end
429
432
 
430
433
  private def execute_request_internal(method, path,
431
- api_base, api_key, headers, params, usage,
432
- &read_body_chunk_block)
434
+ api_base, api_key, headers, params,
435
+ api_mode, usage, &read_body_chunk_block)
433
436
  raise ArgumentError, "method should be a symbol" \
434
437
  unless method.is_a?(Symbol)
435
438
  raise ArgumentError, "path should be a string" \
@@ -437,9 +440,10 @@ module Stripe
437
440
 
438
441
  api_base ||= config.api_base
439
442
  api_key ||= config.api_key
443
+ authenticator ||= config.authenticator
440
444
  params = Util.objects_to_ids(params)
441
445
 
442
- check_api_key!(api_key)
446
+ check_keys!(api_key, authenticator)
443
447
 
444
448
  body_params = nil
445
449
  query_params = nil
@@ -452,8 +456,9 @@ module Stripe
452
456
 
453
457
  query_params, path = merge_query_params(query_params, path)
454
458
 
455
- headers = request_headers(api_key, method)
459
+ headers = request_headers(api_key, method, api_mode)
456
460
  .update(Util.normalize_headers(headers))
461
+
457
462
  url = api_url(path, api_base)
458
463
 
459
464
  # Merge given query parameters with any already encoded in the path.
@@ -464,13 +469,16 @@ module Stripe
464
469
  # a log-friendly variant of the encoded form. File objects are displayed
465
470
  # as such instead of as their file contents.
466
471
  body, body_log =
467
- body_params ? encode_body(body_params, headers) : [nil, nil]
472
+ body_params ? encode_body(body_params, headers, api_mode) : [nil, nil]
473
+
474
+ authenticator.authenticate(method, headers, body) unless api_key
468
475
 
469
476
  # stores information on the request we're about to make so that we don't
470
477
  # have to pass as many parameters around for logging.
471
478
  context = RequestLogContext.new
472
479
  context.account = headers["Stripe-Account"]
473
480
  context.api_key = api_key
481
+ context.authenticator = authenticator
474
482
  context.api_version = headers["Stripe-Version"]
475
483
  context.body = body_log
476
484
  context.idempotency_key = headers["Idempotency-Key"]
@@ -507,8 +515,16 @@ module Stripe
507
515
  (api_base || config.api_base) + url
508
516
  end
509
517
 
510
- private def check_api_key!(api_key)
511
- unless api_key
518
+ private def check_keys!(api_key, authenticator)
519
+ if api_key && authenticator
520
+ raise AuthenticationError, "Can't specify both API key " \
521
+ "and authenticator. Either set your API key" \
522
+ 'using "Stripe.api_key = <API-KEY>", or set your authenticator ' \
523
+ 'using "Stripe.authenticator = <AUTHENTICATOR>"' \
524
+ end
525
+
526
+ unless api_key || authenticator
527
+ # Default to missing API key error message for general users.
512
528
  raise AuthenticationError, "No API key provided. " \
513
529
  'Set your API key using "Stripe.api_key = <API-KEY>". ' \
514
530
  "You can generate API keys from the Stripe web interface. " \
@@ -527,7 +543,7 @@ module Stripe
527
543
  # Encodes a set of body parameters using multipart if `Content-Type` is set
528
544
  # for that, or standard form-encoding otherwise. Returns the encoded body
529
545
  # and a version of the encoded body that's safe to be logged.
530
- private def encode_body(body_params, headers)
546
+ private def encode_body(body_params, headers, api_mode)
531
547
  body = nil
532
548
  flattened_params = Util.flatten_params(body_params)
533
549
 
@@ -543,15 +559,22 @@ module Stripe
543
559
  flattened_params =
544
560
  flattened_params.map { |k, v| [k, v.is_a?(String) ? v : v.to_s] }.to_h
545
561
 
562
+ elsif api_mode == :preview
563
+ body = JSON.generate(body_params)
564
+ headers["Content-Type"] = "application/json"
546
565
  else
547
566
  body = Util.encode_parameters(body_params)
548
567
  end
549
568
 
550
- # We don't use `Util.encode_parameters` partly as an optimization (to not
551
- # redo work we've already done), and partly because the encoded forms of
552
- # certain characters introduce a lot of visual noise and it's nice to
553
- # have a clearer format for logs.
554
- body_log = flattened_params.map { |k, v| "#{k}=#{v}" }.join("&")
569
+ body_log = if api_mode == :preview
570
+ body
571
+ else
572
+ # We don't use `Util.encode_parameters` partly as an optimization (to
573
+ # not redo work we've already done), and partly because the encoded
574
+ # forms of certain characters introduce a lot of visual noise and it's
575
+ # nice to have a clearer format for logs.
576
+ flattened_params.map { |k, v| "#{k}=#{v}" }.join("&")
577
+ end
555
578
 
556
579
  [body, body_log]
557
580
  end
@@ -738,10 +761,11 @@ module Stripe
738
761
  end
739
762
 
740
763
  private def specific_api_error(resp, error_data, context)
764
+ message = error_data[:message]
741
765
  Util.log_error("Stripe API error",
742
766
  status: resp.http_status,
743
767
  error_code: error_data[:code],
744
- error_message: error_data[:message],
768
+ error_message: message,
745
769
  error_param: error_data[:param],
746
770
  error_type: error_data[:type],
747
771
  idempotency_key: context.idempotency_key,
@@ -762,26 +786,26 @@ module Stripe
762
786
  when 400, 404
763
787
  case error_data[:type]
764
788
  when "idempotency_error"
765
- IdempotencyError.new(error_data[:message], **opts)
789
+ IdempotencyError.new(message, **opts)
766
790
  else
767
791
  InvalidRequestError.new(
768
- error_data[:message], error_data[:param],
792
+ message, error_data[:param],
769
793
  **opts
770
794
  )
771
795
  end
772
796
  when 401
773
- AuthenticationError.new(error_data[:message], **opts)
797
+ AuthenticationError.new(message, **opts)
774
798
  when 402
775
799
  CardError.new(
776
- error_data[:message], error_data[:param],
800
+ message, error_data[:param],
777
801
  **opts
778
802
  )
779
803
  when 403
780
- PermissionError.new(error_data[:message], **opts)
804
+ PermissionError.new(message, **opts)
781
805
  when 429
782
- RateLimitError.new(error_data[:message], **opts)
806
+ RateLimitError.new(message, **opts)
783
807
  else
784
- APIError.new(error_data[:message], **opts)
808
+ APIError.new(message, **opts)
785
809
  end
786
810
  end
787
811
 
@@ -849,16 +873,20 @@ module Stripe
849
873
  message + "\n\n(Network error: #{error.message})"
850
874
  end
851
875
 
852
- private def request_headers(api_key, method)
876
+ private def request_headers(api_key, method, api_mode)
853
877
  user_agent = "Stripe/v1 RubyBindings/#{Stripe::VERSION}"
854
878
  user_agent += " " + format_app_info(Stripe.app_info) unless Stripe.app_info.nil?
855
879
 
856
880
  headers = {
857
881
  "User-Agent" => user_agent,
858
882
  "Authorization" => "Bearer #{api_key}",
859
- "Content-Type" => "application/x-www-form-urlencoded",
860
883
  }
861
884
 
885
+ if api_mode != :preview
886
+ # TODO: (major) don't set Content-Type if method is not post
887
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
888
+ end
889
+
862
890
  if config.enable_telemetry? && !@last_request_metrics.nil?
863
891
  headers["X-Stripe-Client-Telemetry"] = JSON.generate(
864
892
  last_request_metrics: @last_request_metrics.payload
@@ -871,7 +899,12 @@ module Stripe
871
899
  headers["Idempotency-Key"] ||= SecureRandom.uuid
872
900
  end
873
901
 
874
- headers["Stripe-Version"] = config.api_version if config.api_version
902
+ if api_mode == :preview
903
+ headers["Stripe-Version"] = ApiVersion::PREVIEW
904
+ elsif config.api_version
905
+ headers["Stripe-Version"] = config.api_version
906
+ end
907
+
875
908
  headers["Stripe-Account"] = config.stripe_account if config.stripe_account
876
909
 
877
910
  user_agent = @system_profiler.user_agent
@@ -954,7 +987,8 @@ module Stripe
954
987
  # that we can log certain information. It's useful because it means that we
955
988
  # don't have to pass around as many parameters.
956
989
  class RequestLogContext
957
- attr_accessor :body, :account, :api_key, :api_version, :idempotency_key, :method, :path, :query, :request_id
990
+ attr_accessor :body, :account, :api_key, :authenticator, :api_version, :idempotency_key, :method, :path, :query,
991
+ :request_id
958
992
 
959
993
  # The idea with this method is that we might want to update some of
960
994
  # context information because a response that we've received from the API