stripe 12.5.0 → 12.6.0.pre.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1342 -644
  3. data/OPENAPI_VERSION +1 -1
  4. data/VERSION +1 -1
  5. data/lib/stripe/api_operations/request.rb +2 -1
  6. data/lib/stripe/api_version.rb +1 -0
  7. data/lib/stripe/object_types.rb +19 -0
  8. data/lib/stripe/request_signing_authenticator.rb +79 -0
  9. data/lib/stripe/resources/account.rb +2 -2
  10. data/lib/stripe/resources/account_notice.rb +32 -0
  11. data/lib/stripe/resources/capital/financing_offer.rb +49 -0
  12. data/lib/stripe/resources/capital/financing_summary.rb +15 -0
  13. data/lib/stripe/resources/capital/financing_transaction.rb +27 -0
  14. data/lib/stripe/resources/customer_session.rb +4 -0
  15. data/lib/stripe/resources/file.rb +17 -13
  16. data/lib/stripe/resources/financial_connections/account.rb +3 -0
  17. data/lib/stripe/resources/financial_connections/account_inferred_balance.rb +14 -0
  18. data/lib/stripe/resources/financial_connections/institution.rb +26 -0
  19. data/lib/stripe/resources/gift_cards/card.rb +59 -0
  20. data/lib/stripe/resources/gift_cards/transaction.rb +93 -0
  21. data/lib/stripe/resources/invoice.rb +81 -0
  22. data/lib/stripe/resources/invoice_line_item.rb +3 -0
  23. data/lib/stripe/resources/invoice_payment.rb +12 -0
  24. data/lib/stripe/resources/issuing/credit_underwriting_record.rb +88 -0
  25. data/lib/stripe/resources/margin.rb +37 -0
  26. data/lib/stripe/resources/order.rb +120 -0
  27. data/lib/stripe/resources/payment_intent.rb +56 -0
  28. data/lib/stripe/resources/quote.rb +106 -2
  29. data/lib/stripe/resources/quote_phase.rb +39 -0
  30. data/lib/stripe/resources/quote_preview_invoice.rb +43 -0
  31. data/lib/stripe/resources/quote_preview_subscription_schedule.rb +11 -0
  32. data/lib/stripe/resources/subscription_schedule.rb +20 -0
  33. data/lib/stripe/resources/tax/association.rb +24 -0
  34. data/lib/stripe/resources/tax/form.rb +49 -0
  35. data/lib/stripe/resources/terminal/reader.rb +60 -0
  36. data/lib/stripe/resources/terminal/reader_collected_data.rb +14 -0
  37. data/lib/stripe/resources/treasury/inbound_transfer.rb +3 -1
  38. data/lib/stripe/resources/treasury/outbound_payment.rb +3 -1
  39. data/lib/stripe/resources/treasury/outbound_transfer.rb +3 -1
  40. data/lib/stripe/resources.rb +18 -0
  41. data/lib/stripe/stripe_client.rb +60 -28
  42. data/lib/stripe/stripe_configuration.rb +2 -1
  43. data/lib/stripe/util.rb +8 -1
  44. data/lib/stripe/version.rb +1 -1
  45. data/lib/stripe.rb +29 -0
  46. metadata +23 -4
@@ -0,0 +1,11 @@
1
+ # File generated from our OpenAPI spec
2
+ # frozen_string_literal: true
3
+
4
+ module Stripe
5
+ class QuotePreviewSubscriptionSchedule < APIResource
6
+ OBJECT_NAME = "quote_preview_subscription_schedule"
7
+ def self.object_name
8
+ "quote_preview_subscription_schedule"
9
+ end
10
+ end
11
+ end
@@ -15,6 +15,26 @@ module Stripe
15
15
  "subscription_schedule"
16
16
  end
17
17
 
18
+ # Amends an existing subscription schedule.
19
+ def amend(params = {}, opts = {})
20
+ request_stripe_object(
21
+ method: :post,
22
+ path: format("/v1/subscription_schedules/%<schedule>s/amend", { schedule: CGI.escape(self["id"]) }),
23
+ params: params,
24
+ opts: opts
25
+ )
26
+ end
27
+
28
+ # Amends an existing subscription schedule.
29
+ def self.amend(schedule, params = {}, opts = {})
30
+ request_stripe_object(
31
+ method: :post,
32
+ path: format("/v1/subscription_schedules/%<schedule>s/amend", { schedule: CGI.escape(schedule) }),
33
+ params: params,
34
+ opts: opts
35
+ )
36
+ end
37
+
18
38
  # Cancels a subscription schedule and its associated subscription immediately (if the subscription schedule has an active subscription). A subscription schedule can only be canceled if its status is not_started or active.
19
39
  def cancel(params = {}, opts = {})
20
40
  request_stripe_object(
@@ -0,0 +1,24 @@
1
+ # File generated from our OpenAPI spec
2
+ # frozen_string_literal: true
3
+
4
+ module Stripe
5
+ module Tax
6
+ # A Tax Association exposes the Tax Transactions that Stripe attempted to create on your behalf based on the PaymentIntent input
7
+ class Association < APIResource
8
+ OBJECT_NAME = "tax.association"
9
+ def self.object_name
10
+ "tax.association"
11
+ end
12
+
13
+ # Finds a tax association object by PaymentIntent id.
14
+ def self.find(params = {}, opts = {})
15
+ request_stripe_object(
16
+ method: :get,
17
+ path: "/v1/tax/associations/find",
18
+ params: params,
19
+ opts: opts
20
+ )
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,49 @@
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
+ def self.object_name
14
+ "tax.form"
15
+ end
16
+
17
+ # Returns a list of tax forms which were previously created. The tax forms are returned in sorted order, with the oldest tax forms appearing first.
18
+ def self.list(filters = {}, opts = {})
19
+ request_stripe_object(method: :get, path: "/v1/tax/forms", params: filters, opts: opts)
20
+ end
21
+
22
+ # Download the PDF for a tax form.
23
+ def pdf(params = {}, opts = {}, &read_body_chunk_block)
24
+ config = opts[:client]&.config || Stripe.config
25
+ opts = { api_base: config.uploads_base }.merge(opts)
26
+ request_stream(
27
+ method: :get,
28
+ path: format("/v1/tax/forms/%<id>s/pdf", { id: CGI.escape(self["id"]) }),
29
+ params: params,
30
+ opts: opts,
31
+ &read_body_chunk_block
32
+ )
33
+ end
34
+
35
+ # Download the PDF for a tax form.
36
+ def self.pdf(id, params = {}, opts = {}, &read_body_chunk_block)
37
+ config = opts[:client]&.config || Stripe.config
38
+ opts = { api_base: config.uploads_base }.merge(opts)
39
+ execute_resource_request_stream(
40
+ :get,
41
+ format("/v1/tax/forms/%<id>s/pdf", { id: CGI.escape(id) }),
42
+ params,
43
+ opts,
44
+ &read_body_chunk_block
45
+ )
46
+ end
47
+ end
48
+ end
49
+ end
@@ -37,6 +37,66 @@ module Stripe
37
37
  )
38
38
  end
39
39
 
40
+ # Initiates an input collection flow on a Reader.
41
+ def collect_inputs(params = {}, opts = {})
42
+ request_stripe_object(
43
+ method: :post,
44
+ path: format("/v1/terminal/readers/%<reader>s/collect_inputs", { reader: CGI.escape(self["id"]) }),
45
+ params: params,
46
+ opts: opts
47
+ )
48
+ end
49
+
50
+ # Initiates an input collection flow on a Reader.
51
+ def self.collect_inputs(reader, params = {}, opts = {})
52
+ request_stripe_object(
53
+ method: :post,
54
+ path: format("/v1/terminal/readers/%<reader>s/collect_inputs", { reader: CGI.escape(reader) }),
55
+ params: params,
56
+ opts: opts
57
+ )
58
+ end
59
+
60
+ # Initiates a payment flow on a Reader and updates the PaymentIntent with card details before manual confirmation.
61
+ def collect_payment_method(params = {}, opts = {})
62
+ request_stripe_object(
63
+ method: :post,
64
+ path: format("/v1/terminal/readers/%<reader>s/collect_payment_method", { reader: CGI.escape(self["id"]) }),
65
+ params: params,
66
+ opts: opts
67
+ )
68
+ end
69
+
70
+ # Initiates a payment flow on a Reader and updates the PaymentIntent with card details before manual confirmation.
71
+ def self.collect_payment_method(reader, params = {}, opts = {})
72
+ request_stripe_object(
73
+ method: :post,
74
+ path: format("/v1/terminal/readers/%<reader>s/collect_payment_method", { reader: CGI.escape(reader) }),
75
+ params: params,
76
+ opts: opts
77
+ )
78
+ end
79
+
80
+ # Finalizes a payment on a Reader.
81
+ def confirm_payment_intent(params = {}, opts = {})
82
+ request_stripe_object(
83
+ method: :post,
84
+ path: format("/v1/terminal/readers/%<reader>s/confirm_payment_intent", { reader: CGI.escape(self["id"]) }),
85
+ params: params,
86
+ opts: opts
87
+ )
88
+ end
89
+
90
+ # Finalizes a payment on a Reader.
91
+ def self.confirm_payment_intent(reader, params = {}, opts = {})
92
+ request_stripe_object(
93
+ method: :post,
94
+ path: format("/v1/terminal/readers/%<reader>s/confirm_payment_intent", { reader: CGI.escape(reader) }),
95
+ params: params,
96
+ opts: opts
97
+ )
98
+ end
99
+
40
100
  # Creates a new Reader object.
41
101
  def self.create(params = {}, opts = {})
42
102
  request_stripe_object(
@@ -0,0 +1,14 @@
1
+ # File generated from our OpenAPI spec
2
+ # frozen_string_literal: true
3
+
4
+ module Stripe
5
+ module Terminal
6
+ # Returns data collected by Terminal readers. This data is only stored for 24 hours.
7
+ class ReaderCollectedData < APIResource
8
+ OBJECT_NAME = "terminal.reader_collected_data"
9
+ def self.object_name
10
+ "terminal.reader_collected_data"
11
+ end
12
+ end
13
+ end
14
+ end
@@ -3,7 +3,9 @@
3
3
 
4
4
  module Stripe
5
5
  module Treasury
6
- # Use [InboundTransfers](https://stripe.com/docs/treasury/moving-money/financial-accounts/into/inbound-transfers) to add funds to your [FinancialAccount](https://stripe.com/docs/api#financial_accounts) via a PaymentMethod that is owned by you. The funds will be transferred via an ACH debit.
6
+ # Use [InboundTransfers](https://docs.stripe.com/docs/treasury/moving-money/financial-accounts/into/inbound-transfers) to add funds to your [FinancialAccount](https://stripe.com/docs/api#financial_accounts) via a PaymentMethod that is owned by you. The funds will be transferred via an ACH debit.
7
+ #
8
+ # Related guide: [Moving money with Treasury using InboundTransfer objects](https://docs.stripe.com/docs/treasury/moving-money/financial-accounts/into/inbound-transfers)
7
9
  class InboundTransfer < APIResource
8
10
  extend Stripe::APIOperations::Create
9
11
  extend Stripe::APIOperations::List
@@ -3,9 +3,11 @@
3
3
 
4
4
  module Stripe
5
5
  module Treasury
6
- # Use OutboundPayments to send funds to another party's external bank account or [FinancialAccount](https://stripe.com/docs/api#financial_accounts). To send money to an account belonging to the same user, use an [OutboundTransfer](https://stripe.com/docs/api#outbound_transfers).
6
+ # Use [OutboundPayments](https://docs.stripe.com/docs/treasury/moving-money/financial-accounts/out-of/outbound-payments) to send funds to another party's external bank account or [FinancialAccount](https://stripe.com/docs/api#financial_accounts). To send money to an account belonging to the same user, use an [OutboundTransfer](https://stripe.com/docs/api#outbound_transfers).
7
7
  #
8
8
  # Simulate OutboundPayment state changes with the `/v1/test_helpers/treasury/outbound_payments` endpoints. These methods can only be called on test mode objects.
9
+ #
10
+ # Related guide: [Moving money with Treasury using OutboundPayment objects](https://docs.stripe.com/docs/treasury/moving-money/financial-accounts/out-of/outbound-payments)
9
11
  class OutboundPayment < APIResource
10
12
  extend Stripe::APIOperations::Create
11
13
  extend Stripe::APIOperations::List
@@ -3,9 +3,11 @@
3
3
 
4
4
  module Stripe
5
5
  module Treasury
6
- # Use OutboundTransfers to transfer funds from a [FinancialAccount](https://stripe.com/docs/api#financial_accounts) to a PaymentMethod belonging to the same entity. To send funds to a different party, use [OutboundPayments](https://stripe.com/docs/api#outbound_payments) instead. You can send funds over ACH rails or through a domestic wire transfer to a user's own external bank account.
6
+ # Use [OutboundTransfers](https://docs.stripe.com/docs/treasury/moving-money/financial-accounts/out-of/outbound-transfers) to transfer funds from a [FinancialAccount](https://stripe.com/docs/api#financial_accounts) to a PaymentMethod belonging to the same entity. To send funds to a different party, use [OutboundPayments](https://stripe.com/docs/api#outbound_payments) instead. You can send funds over ACH rails or through a domestic wire transfer to a user's own external bank account.
7
7
  #
8
8
  # Simulate OutboundTransfer state changes with the `/v1/test_helpers/treasury/outbound_transfers` endpoints. These methods can only be called on test mode objects.
9
+ #
10
+ # Related guide: [Moving money with Treasury using OutboundTransfer objects](https://docs.stripe.com/docs/treasury/moving-money/financial-accounts/out-of/outbound-transfers)
9
11
  class OutboundTransfer < APIResource
10
12
  extend Stripe::APIOperations::Create
11
13
  extend Stripe::APIOperations::List
@@ -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"
@@ -19,6 +20,9 @@ require "stripe/resources/billing/meter_event_summary"
19
20
  require "stripe/resources/billing_portal/configuration"
20
21
  require "stripe/resources/billing_portal/session"
21
22
  require "stripe/resources/capability"
23
+ require "stripe/resources/capital/financing_offer"
24
+ require "stripe/resources/capital/financing_summary"
25
+ require "stripe/resources/capital/financing_transaction"
22
26
  require "stripe/resources/card"
23
27
  require "stripe/resources/cash_balance"
24
28
  require "stripe/resources/charge"
@@ -45,20 +49,26 @@ require "stripe/resources/exchange_rate"
45
49
  require "stripe/resources/file"
46
50
  require "stripe/resources/file_link"
47
51
  require "stripe/resources/financial_connections/account"
52
+ require "stripe/resources/financial_connections/account_inferred_balance"
48
53
  require "stripe/resources/financial_connections/account_owner"
49
54
  require "stripe/resources/financial_connections/account_ownership"
55
+ require "stripe/resources/financial_connections/institution"
50
56
  require "stripe/resources/financial_connections/session"
51
57
  require "stripe/resources/financial_connections/transaction"
52
58
  require "stripe/resources/forwarding/request"
53
59
  require "stripe/resources/funding_instructions"
60
+ require "stripe/resources/gift_cards/card"
61
+ require "stripe/resources/gift_cards/transaction"
54
62
  require "stripe/resources/identity/verification_report"
55
63
  require "stripe/resources/identity/verification_session"
56
64
  require "stripe/resources/invoice"
57
65
  require "stripe/resources/invoice_item"
58
66
  require "stripe/resources/invoice_line_item"
67
+ require "stripe/resources/invoice_payment"
59
68
  require "stripe/resources/issuing/authorization"
60
69
  require "stripe/resources/issuing/card"
61
70
  require "stripe/resources/issuing/cardholder"
71
+ require "stripe/resources/issuing/credit_underwriting_record"
62
72
  require "stripe/resources/issuing/dispute"
63
73
  require "stripe/resources/issuing/personalization_design"
64
74
  require "stripe/resources/issuing/physical_bundle"
@@ -67,6 +77,8 @@ require "stripe/resources/issuing/transaction"
67
77
  require "stripe/resources/line_item"
68
78
  require "stripe/resources/login_link"
69
79
  require "stripe/resources/mandate"
80
+ require "stripe/resources/margin"
81
+ require "stripe/resources/order"
70
82
  require "stripe/resources/payment_intent"
71
83
  require "stripe/resources/payment_link"
72
84
  require "stripe/resources/payment_method"
@@ -80,6 +92,9 @@ require "stripe/resources/product"
80
92
  require "stripe/resources/product_feature"
81
93
  require "stripe/resources/promotion_code"
82
94
  require "stripe/resources/quote"
95
+ require "stripe/resources/quote_phase"
96
+ require "stripe/resources/quote_preview_invoice"
97
+ require "stripe/resources/quote_preview_subscription_schedule"
83
98
  require "stripe/resources/radar/early_fraud_warning"
84
99
  require "stripe/resources/radar/value_list"
85
100
  require "stripe/resources/radar/value_list_item"
@@ -97,8 +112,10 @@ require "stripe/resources/source_transaction"
97
112
  require "stripe/resources/subscription"
98
113
  require "stripe/resources/subscription_item"
99
114
  require "stripe/resources/subscription_schedule"
115
+ require "stripe/resources/tax/association"
100
116
  require "stripe/resources/tax/calculation"
101
117
  require "stripe/resources/tax/calculation_line_item"
118
+ require "stripe/resources/tax/form"
102
119
  require "stripe/resources/tax/registration"
103
120
  require "stripe/resources/tax/settings"
104
121
  require "stripe/resources/tax/transaction"
@@ -110,6 +127,7 @@ require "stripe/resources/terminal/configuration"
110
127
  require "stripe/resources/terminal/connection_token"
111
128
  require "stripe/resources/terminal/location"
112
129
  require "stripe/resources/terminal/reader"
130
+ require "stripe/resources/terminal/reader_collected_data"
113
131
  require "stripe/resources/test_helpers/test_clock"
114
132
  require "stripe/resources/token"
115
133
  require "stripe/resources/topup"
@@ -217,9 +217,10 @@ module Stripe
217
217
  "for usage examples)", 2024, 6
218
218
 
219
219
  def execute_request(method, path,
220
- api_base: nil, api_key: nil, headers: {}, params: {}, usage: [])
220
+ api_base: nil, api_key: nil,
221
+ headers: {}, params: {}, api_mode: nil, usage: [])
221
222
  http_resp, api_key = execute_request_internal(
222
- method, path, api_base, api_key, headers, params, usage
223
+ method, path, api_base, api_key, headers, params, api_mode, usage
223
224
  )
224
225
 
225
226
  begin
@@ -250,6 +251,7 @@ module Stripe
250
251
  def execute_request_stream(method, path,
251
252
  api_base: nil, api_key: nil, usage: [],
252
253
  headers: {}, params: {},
254
+ api_mode: nil,
253
255
  &read_body_chunk_block)
254
256
  unless block_given?
255
257
  raise ArgumentError,
@@ -257,7 +259,8 @@ module Stripe
257
259
  end
258
260
 
259
261
  http_resp, api_key = execute_request_internal(
260
- method, path, api_base, api_key, headers, params, usage, &read_body_chunk_block
262
+ method, path, api_base, api_key,
263
+ headers, params, api_mode, usage, &read_body_chunk_block
261
264
  )
262
265
 
263
266
  # When the read_body_chunk_block is given, we no longer have access to the
@@ -436,8 +439,8 @@ module Stripe
436
439
  end
437
440
 
438
441
  private def execute_request_internal(method, path,
439
- api_base, api_key, headers, params, usage,
440
- &read_body_chunk_block)
442
+ api_base, api_key, headers, params,
443
+ api_mode, usage, &read_body_chunk_block)
441
444
  raise ArgumentError, "method should be a symbol" \
442
445
  unless method.is_a?(Symbol)
443
446
  raise ArgumentError, "path should be a string" \
@@ -445,9 +448,10 @@ module Stripe
445
448
 
446
449
  api_base ||= config.api_base
447
450
  api_key ||= config.api_key
451
+ authenticator ||= config.authenticator
448
452
  params = Util.objects_to_ids(params)
449
453
 
450
- check_api_key!(api_key)
454
+ check_keys!(api_key, authenticator)
451
455
 
452
456
  body_params = nil
453
457
  query_params = nil
@@ -460,7 +464,7 @@ module Stripe
460
464
 
461
465
  query_params, path = merge_query_params(query_params, path)
462
466
 
463
- headers = request_headers(api_key, method)
467
+ headers = request_headers(api_key, method, api_mode)
464
468
  .update(Util.normalize_headers(headers))
465
469
 
466
470
  url = api_url(path, api_base)
@@ -473,13 +477,16 @@ module Stripe
473
477
  # a log-friendly variant of the encoded form. File objects are displayed
474
478
  # as such instead of as their file contents.
475
479
  body, body_log =
476
- body_params ? encode_body(body_params, headers) : [nil, nil]
480
+ body_params ? encode_body(body_params, headers, api_mode) : [nil, nil]
481
+
482
+ authenticator.authenticate(method, headers, body) unless api_key
477
483
 
478
484
  # stores information on the request we're about to make so that we don't
479
485
  # have to pass as many parameters around for logging.
480
486
  context = RequestLogContext.new
481
487
  context.account = headers["Stripe-Account"]
482
488
  context.api_key = api_key
489
+ context.authenticator = authenticator
483
490
  context.api_version = headers["Stripe-Version"]
484
491
  context.body = body_log
485
492
  context.idempotency_key = headers["Idempotency-Key"]
@@ -516,8 +523,16 @@ module Stripe
516
523
  (api_base || config.api_base) + url
517
524
  end
518
525
 
519
- private def check_api_key!(api_key)
520
- unless api_key
526
+ private def check_keys!(api_key, authenticator)
527
+ if api_key && authenticator
528
+ raise AuthenticationError, "Can't specify both API key " \
529
+ "and authenticator. Either set your API key" \
530
+ 'using "Stripe.api_key = <API-KEY>", or set your authenticator ' \
531
+ 'using "Stripe.authenticator = <AUTHENTICATOR>"' \
532
+ end
533
+
534
+ unless api_key || authenticator
535
+ # Default to missing API key error message for general users.
521
536
  raise AuthenticationError, "No API key provided. " \
522
537
  'Set your API key using "Stripe.api_key = <API-KEY>". ' \
523
538
  "You can generate API keys from the Stripe web interface. " \
@@ -536,7 +551,7 @@ module Stripe
536
551
  # Encodes a set of body parameters using multipart if `Content-Type` is set
537
552
  # for that, or standard form-encoding otherwise. Returns the encoded body
538
553
  # and a version of the encoded body that's safe to be logged.
539
- private def encode_body(body_params, headers)
554
+ private def encode_body(body_params, headers, api_mode)
540
555
  body = nil
541
556
  flattened_params = Util.flatten_params(body_params)
542
557
 
@@ -552,15 +567,22 @@ module Stripe
552
567
  flattened_params =
553
568
  flattened_params.map { |k, v| [k, v.is_a?(String) ? v : v.to_s] }.to_h
554
569
 
570
+ elsif api_mode == :preview
571
+ body = JSON.generate(body_params)
572
+ headers["Content-Type"] = "application/json"
555
573
  else
556
574
  body = Util.encode_parameters(body_params)
557
575
  end
558
576
 
559
- # We don't use `Util.encode_parameters` partly as an optimization (to not
560
- # redo work we've already done), and partly because the encoded forms of
561
- # certain characters introduce a lot of visual noise and it's nice to
562
- # have a clearer format for logs.
563
- body_log = flattened_params.map { |k, v| "#{k}=#{v}" }.join("&")
577
+ body_log = if api_mode == :preview
578
+ body
579
+ else
580
+ # We don't use `Util.encode_parameters` partly as an optimization (to
581
+ # not redo work we've already done), and partly because the encoded
582
+ # forms of certain characters introduce a lot of visual noise and it's
583
+ # nice to have a clearer format for logs.
584
+ flattened_params.map { |k, v| "#{k}=#{v}" }.join("&")
585
+ end
564
586
 
565
587
  [body, body_log]
566
588
  end
@@ -746,10 +768,11 @@ module Stripe
746
768
  end
747
769
 
748
770
  private def specific_api_error(resp, error_data, context)
771
+ message = error_data[:message]
749
772
  Util.log_error("Stripe API error",
750
773
  status: resp.http_status,
751
774
  error_code: error_data[:code],
752
- error_message: error_data[:message],
775
+ error_message: message,
753
776
  error_param: error_data[:param],
754
777
  error_type: error_data[:type],
755
778
  idempotency_key: context.idempotency_key,
@@ -770,26 +793,26 @@ module Stripe
770
793
  when 400, 404
771
794
  case error_data[:type]
772
795
  when "idempotency_error"
773
- IdempotencyError.new(error_data[:message], **opts)
796
+ IdempotencyError.new(message, **opts)
774
797
  else
775
798
  InvalidRequestError.new(
776
- error_data[:message], error_data[:param],
799
+ message, error_data[:param],
777
800
  **opts
778
801
  )
779
802
  end
780
803
  when 401
781
- AuthenticationError.new(error_data[:message], **opts)
804
+ AuthenticationError.new(message, **opts)
782
805
  when 402
783
806
  CardError.new(
784
- error_data[:message], error_data[:param],
807
+ message, error_data[:param],
785
808
  **opts
786
809
  )
787
810
  when 403
788
- PermissionError.new(error_data[:message], **opts)
811
+ PermissionError.new(message, **opts)
789
812
  when 429
790
- RateLimitError.new(error_data[:message], **opts)
813
+ RateLimitError.new(message, **opts)
791
814
  else
792
- APIError.new(error_data[:message], **opts)
815
+ APIError.new(message, **opts)
793
816
  end
794
817
  end
795
818
 
@@ -857,16 +880,20 @@ module Stripe
857
880
  message + "\n\n(Network error: #{error.message})"
858
881
  end
859
882
 
860
- private def request_headers(api_key, method)
883
+ private def request_headers(api_key, method, api_mode)
861
884
  user_agent = "Stripe/v1 RubyBindings/#{Stripe::VERSION}"
862
885
  user_agent += " " + format_app_info(Stripe.app_info) unless Stripe.app_info.nil?
863
886
 
864
887
  headers = {
865
888
  "User-Agent" => user_agent,
866
889
  "Authorization" => "Bearer #{api_key}",
867
- "Content-Type" => "application/x-www-form-urlencoded",
868
890
  }
869
891
 
892
+ if api_mode != :preview
893
+ # TODO: (major) don't set Content-Type if method is not post
894
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
895
+ end
896
+
870
897
  if config.enable_telemetry? && !@last_request_metrics.nil?
871
898
  headers["X-Stripe-Client-Telemetry"] = JSON.generate(
872
899
  last_request_metrics: @last_request_metrics.payload
@@ -879,7 +906,11 @@ module Stripe
879
906
  headers["Idempotency-Key"] ||= SecureRandom.uuid
880
907
  end
881
908
 
882
- headers["Stripe-Version"] = config.api_version if config.api_version
909
+ if api_mode == :preview
910
+ headers["Stripe-Version"] = ApiVersion::PREVIEW
911
+ elsif config.api_version
912
+ headers["Stripe-Version"] = config.api_version
913
+ end
883
914
 
884
915
  headers["Stripe-Account"] = config.stripe_account if config.stripe_account
885
916
 
@@ -963,7 +994,8 @@ module Stripe
963
994
  # that we can log certain information. It's useful because it means that we
964
995
  # don't have to pass around as many parameters.
965
996
  class RequestLogContext
966
- attr_accessor :body, :account, :api_key, :api_version, :idempotency_key, :method, :path, :query, :request_id
997
+ attr_accessor :body, :account, :api_key, :authenticator, :api_version, :idempotency_key, :method, :path, :query,
998
+ :request_id
967
999
 
968
1000
  # The idea with this method is that we might want to update some of
969
1001
  # context information because a response that we've received from the API
@@ -25,7 +25,7 @@ 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, :api_version, :client_id, :enable_telemetry, :logger, :stripe_account
28
+ attr_accessor :api_key, :api_version, :authenticator, :client_id, :enable_telemetry, :logger, :stripe_account
29
29
 
30
30
  attr_reader :api_base, :uploads_base, :connect_base, :ca_bundle_path, :log_level, :initial_network_retry_delay,
31
31
  # rubocop:todo Layout/LineLength
@@ -50,6 +50,7 @@ module Stripe
50
50
 
51
51
  def initialize
52
52
  @api_version = ApiVersion::CURRENT
53
+
53
54
  @ca_bundle_path = Stripe::DEFAULT_CA_BUNDLE_PATH
54
55
  @enable_telemetry = true
55
56
  @verify_ssl_certs = true
data/lib/stripe/util.rb CHANGED
@@ -7,6 +7,7 @@ module Stripe
7
7
  # Options that a user is allowed to specify.
8
8
  OPTS_USER_SPECIFIED = Set[
9
9
  :api_key,
10
+ :authenticator,
10
11
  :idempotency_key,
11
12
  :stripe_account,
12
13
  :stripe_version
@@ -279,7 +280,13 @@ module Stripe
279
280
  when String
280
281
  { api_key: opts }
281
282
  when Hash
282
- check_api_key!(opts.fetch(:api_key)) if opts.key?(:api_key)
283
+ # If the user is using request signing for authentication,
284
+ # no need to check the api_key per request.
285
+ if !(opts.key?(:client) &&
286
+ opts.fetch(:client).config.authenticator) &&
287
+ opts.key?(:api_key)
288
+ check_api_key!(opts.fetch(:api_key))
289
+ end
283
290
  # Explicitly use dup here instead of clone to avoid preserving freeze
284
291
  # state on input params.
285
292
  opts.dup
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Stripe
4
- VERSION = "12.5.0"
4
+ VERSION = "12.6.0-beta.1"
5
5
  end
data/lib/stripe.rb CHANGED
@@ -13,6 +13,7 @@ require "set"
13
13
  require "socket"
14
14
  require "uri"
15
15
  require "forwardable"
16
+ require "base64"
16
17
 
17
18
  # Version
18
19
  require "stripe/api_version"
@@ -45,6 +46,7 @@ require "stripe/api_resource_test_helpers"
45
46
  require "stripe/singleton_api_resource"
46
47
  require "stripe/webhook"
47
48
  require "stripe/stripe_configuration"
49
+ require "stripe/request_signing_authenticator"
48
50
 
49
51
  # Named API resources
50
52
  require "stripe/resources"
@@ -71,6 +73,7 @@ module Stripe
71
73
 
72
74
  # User configurable options
73
75
  def_delegators :@config, :api_key, :api_key=
76
+ def_delegators :@config, :authenticator, :authenticator=
74
77
  def_delegators :@config, :api_version, :api_version=
75
78
  def_delegators :@config, :stripe_account, :stripe_account=
76
79
  def_delegators :@config, :api_base, :api_base=
@@ -118,6 +121,32 @@ module Stripe
118
121
  }
119
122
  end
120
123
 
124
+ def self.add_beta_version(beta_name, version)
125
+ if api_version.include?("; #{beta_name}=")
126
+ raise "Stripe version header #{api_version} already contains entry for beta #{beta_name}"
127
+ end
128
+
129
+ self.api_version = "#{api_version}; #{beta_name}=#{version}"
130
+ end
131
+
132
+ class Preview
133
+ def self._get_default_opts(opts)
134
+ { api_mode: :preview }.merge(opts)
135
+ end
136
+
137
+ def self.get(url, opts = {})
138
+ Stripe.raw_request(:get, url, {}, _get_default_opts(opts))
139
+ end
140
+
141
+ def self.post(url, params = {}, opts = {})
142
+ Stripe.raw_request(:post, url, params, _get_default_opts(opts))
143
+ end
144
+
145
+ def self.delete(url, opts = {})
146
+ Stripe.raw_request(:delete, url, {}, _get_default_opts(opts))
147
+ end
148
+ end
149
+
121
150
  class RawRequest
122
151
  include Stripe::APIOperations::Request
123
152