Skip to content

Commit

Permalink
Merge changes from stripe/stripe-ruby master and fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
helenye-stripe committed Oct 3, 2024
2 parents be974ad + 540c7f7 commit eff7ad9
Show file tree
Hide file tree
Showing 272 changed files with 18,540 additions and 3,424 deletions.
26 changes: 25 additions & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,14 @@ Layout/FirstHashElementIndentation:
Layout/LineLength:
Exclude:
- "lib/stripe/object_types.rb"
- "lib/stripe/stripe_client.rb"
- "lib/stripe/resources/**/*.rb"
- "lib/stripe/services/**/*.rb"
- "test/**/*.rb"

Metrics/AbcSize:
Enabled: false

Metrics/BlockLength:
Max: 40
Exclude:
Expand All @@ -29,18 +34,37 @@ Metrics/BlockLength:
Metrics/ClassLength:
Enabled: false

# There are several methods with many branches in api_requestor due to
# request logic.
Metrics/CyclomaticComplexity:
Exclude:
- "lib/stripe/api_requestor.rb"
- "lib/stripe/util.rb"

Metrics/PerceivedComplexity:
Exclude:
- "lib/stripe/api_requestor.rb"
- "lib/stripe/util.rb"

Metrics/MethodLength:
# There's ~2 long methods in `StripeClient` and one in `NestedResource`. If
# There's ~2 long methods in `APIRequestor` and one in `NestedResource`. If
# we want to truncate those a little, we could move this to be closer to ~30
# (but the default of 10 is probably too short).
Max: 55
Exclude:
- "lib/stripe/services/v1_services.rb"

Metrics/ModuleLength:
Enabled: false

Metrics/ParameterLists:
# There's 2 methods in `StripeClient` that have long parameter lists.
Max: 8
# Optional parameters should be consistent across libraries, we need not be
# concerned about this. Was introduced with adding `base_address`
Exclude:
- "lib/stripe/api_operations/request.rb"
- "lib/stripe/stripe_object.rb"

Style/AccessModifierDeclarations:
EnforcedStyle: inline
Expand Down
8 changes: 4 additions & 4 deletions .rubocop_todo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
# Offense count: 2
Lint/HashCompareByIdentity:
Exclude:
- 'lib/stripe/stripe_client.rb'
- 'lib/stripe/api_requestor.rb'

# Offense count: 27
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
Expand Down Expand Up @@ -42,7 +42,7 @@ Style/CaseLikeIf:
# This cop supports unsafe autocorrection (--autocorrect-all).
Style/CombinableLoops:
Exclude:
- 'lib/stripe/stripe_client.rb'
- 'lib/stripe/api_requestor.rb'

# Offense count: 44
# Configuration parameters: AllowedConstants.
Expand All @@ -54,7 +54,7 @@ Style/Documentation:
# Configuration parameters: AllowSplatArgument.
Style/HashConversion:
Exclude:
- 'lib/stripe/stripe_client.rb'
- 'lib/stripe/api_requestor.rb'

# Offense count: 3
# This cop supports unsafe autocorrection (--autocorrect-all).
Expand All @@ -76,7 +76,7 @@ Style/StringConcatenation:
- 'lib/stripe/oauth.rb'
- 'lib/stripe/resources/bank_account.rb'
- 'lib/stripe/resources/source.rb'
- 'lib/stripe/stripe_client.rb'
- 'lib/stripe/api_requestor.rb'
- 'test/stripe/api_resource_test.rb'
- 'test/stripe/stripe_client_test.rb'
- 'test/stripe/webhook_test.rb'
86 changes: 77 additions & 9 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,73 @@
# Changelog

## 13.0.0 - 2024-10-01
* [#1458](https://github.com/stripe/stripe-ruby/pull/1458) Support for APIs in the new API version 2024-09-30.acacia

This release changes the pinned API version to `2024-09-30.acacia`. Please read the [API Upgrade Guide](https://stripe.com/docs/upgrades#2024-09-30.acacia) and carefully review the API changes before upgrading.

### ⚠️ Breaking changes

Please refer to our [migration guide for v13](https://github.com/stripe/stripe-ruby/wiki/Migration-guide-for-v13) for more information about the backwards incompatible changes.

#### `StripeClient` and related changes
* Move `StripeClient` and requestor logic to `APIRequestor`.
* `StripeClient#request` is still available, but is deprecated and will be removed. We encourage `StripeClient#raw_request` as a replacement (see other breaking changes for more detail).
* Repurpose and introduce `StripeClient` as the the entry-point to the service-based pattern, a new interface for calling the Stripe API with many benefits over the existing resource-based paradigm. Services are available under the `v1` and `v2` accessors.
* No global config: you can simultaneously use multiple clients with different configuration options (such as API keys)
* No extra API calls. All API endpoints can be accessed with a single method call. You don't have to call `retrieve` before doing an `update`.
* No static methods. Much easier mocking.

#### Other breaking changes

* Adjust default values around retries for HTTP requests. You can use the old defaults by setting them explicitly. New values are:
- max retries: `0` -> `2`
- max retry delay (seconds) `2` -> `5`
* Remove `StripeClient#connection_manager`. This was a legacy method from years ago.
* Singleton `retrieve` method now requires `params` to be passed as the first argument. Existing calls to singleton `retrieve` method with only `opts` argument will have to be updated to account for the addition of `params` argument.
```ruby
params = { expand: ["available"] }
opts = { stripe_account: "acct_123" }

# ❌ No longer works
Stripe::Balance.retrieve(opts)

# ✅ Correct way to call retrieve method
Stripe::Balance.retrieve(params, opts)
```
* Moved the `Stripe.raw_request()` method that was recently added to `StripeClient`. This will use the configuration set on the StripeClient instead of the global configuration used before.
* Remove `APIResource.request`. Instead, use `StripeClient#raw_request` now.
```ruby
# Instead of
Stripe::APIResource.request(:get, "/v1/endpoint", params, opts)
# do
client = Stripe::StripeClient.new(...)
resp = client.raw_request(:get, "/v1/endpoint", params: params, opts: opts)
```
* Add an additional parameter to `APIResource.execute_resource_request`. However, we discourage use of this in favor of `StripeClient#raw_request`.
```ruby
APIResource.execute_resource_request(method, url, params = {}, opts = {}, usage = [])
# is now, with base_address being one of [:api, :files, :connect, :meter_events]
APIResource.execute_resource_request(method, url, base_address = :api, params = {}, opts = {}, usage = [])
```
* Change parameters to `APIRequestor.execute_request` (previously `StripeClient.execute_request`). It now returns all request options from our internal request framework as the second value in the returned tuple, instead of only the API key used:
```ruby
# Before
obj, api_key = StripeClient.execute_request(method, path, api_base: nil,
api_key: nil, headers: {}, params: {}, usage: [])
# is now, with base_address being one of [:api, :files, :connect, :meter_events]
obj, opts = APIRequestor.execute_request(method, path, base_address,
params: {}, opts: {}, usage: [])
puts(opts) # will output {api_key: "sk_test_123", stripe_account: "acct_123"}
```


### Additions
* Add support for new Usage Billing APIs `Billing.MeterEvent`, `Billing.MeterEventAdjustments`, `Billing.MeterEventSession`, `Billing.MeterEventStream` and the new Events API `Core.Events` in the [v2 namespace ](https://docs.corp.stripe.com/api-v2-overview)
* Add method `parse_thin_event()` on the `StripeClient` class to parse [thin events](https://docs.corp.stripe.com/event-destinations#events-overview).

## 12.7.0-beta.2 - 2024-09-18
* [#1449](https://github.com/stripe/stripe-ruby/pull/1449) Update generated code for beta
* Remove support for resource `QuotePhase`
Expand Down Expand Up @@ -52,7 +120,7 @@

* [#1433](https://github.com/stripe/stripe-ruby/pull/1433) Add usage to raw_request call
* [#1431](https://github.com/stripe/stripe-ruby/pull/1431) Add `raw_request`


- Adds the ability to make raw requests to the Stripe API, by providing an HTTP method and url. This is an alternative to using `Stripe::APIResource.request(...)` to make custom requests, which is discouraged and will be broken in a future major version.

## 12.2.0-beta.1 - 2024-07-05
Expand All @@ -65,14 +133,14 @@
* [#1425](https://github.com/stripe/stripe-ruby/pull/1425) Update generated code
* Add support for `add_lines`, `remove_lines`, and `update_lines` methods on resource `Invoice`
* [#1420](https://github.com/stripe/stripe-ruby/pull/1420) Update static methods for delete/list on BankAccount/Card to throw NotImplementedError
* The below methods have been throwing `InvalidRequestError` because the urls used to make the requests have been buggy. Updating them to throw `NotImplementedError` instead just like their counterparts for update & retrieve because they cannot be implemented without the parent id.

Methods affected | Use these instead in the context of payment method | Use these in the context of external accounts
------ | ------ | ----
Stripe:: BankAccount.delete | Stripe::Customer.delete_source | Stripe::Account.delete_external_account
Stripe:: BankAccount.list | Stripe::Customer.list_sources | Stripe::Customer.list_external_accounts
Stripe:: Card.delete | Stripe::Customer.delete_source | Stripe::Account.delete_external_account
Stripe:: Card.list | Stripe::Customer.list_sources | Stripe::Customer.list_external_accounts
* The below methods have been throwing `InvalidRequestError` because the urls used to make the requests have been buggy. Updating them to throw `NotImplementedError` instead just like their counterparts for update & retrieve because they cannot be implemented without the parent id.

Methods affected | Use these instead in the context of payment method | Use these in the context of external accounts
------ | ------ | ----
Stripe:: BankAccount.delete | Stripe::Customer.delete_source | Stripe::Account.delete_external_account
Stripe:: BankAccount.list | Stripe::Customer.list_sources | Stripe::Customer.list_external_accounts
Stripe:: Card.delete | Stripe::Customer.delete_source | Stripe::Account.delete_external_account
Stripe:: Card.list | Stripe::Customer.list_sources | Stripe::Customer.list_external_accounts
* [#1427](https://github.com/stripe/stripe-ruby/pull/1427) Regenerate rbis
* [#1426](https://github.com/stripe/stripe-ruby/pull/1426) Remove coveralls and re-added JRuby

Expand Down
2 changes: 1 addition & 1 deletion OPENAPI_VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v1267
v1267
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -346,13 +346,14 @@ If you:
- prefer to bypass the method definitions in the library and specify your request details directly,
- used the method `Stripe::APIResource.request(...)` to specify your own requests, which will soon be broken

you can now use the `raw_request` method on `Stripe`.
you can now use the `raw_request` method on `StripeClient`.

```ruby
resp = Stripe.raw_request(:post, "/v1/beta_endpoint", {param: 123}, {stripe_version: "2022-11-15; feature_beta=v3"})
client = Stripe::StripeClient.new(...)
resp = client.raw_request(:post, "/v1/beta_endpoint", {param: 123}, {stripe_version: "2022-11-15; feature_beta=v3"})
# (Optional) resp is a StripeResponse. You can use `Stripe.deserialize` to get a StripeObject.
deserialized_resp = Stripe.deserialize(resp.http_body)
deserialized_resp = client.deserialize(resp.http_body)
```

## Support
Expand Down
11 changes: 11 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## Running an example

From the examples folder, run:
`RUBYLIB=../lib ruby your_example.rb`

## Adding a new example

1. Clone new_example.rb
2. Implement your example
3. Run it (as per above)
4. 👍
47 changes: 47 additions & 0 deletions examples/meter_event_stream.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# frozen_string_literal: true

require "stripe"
require "date"

class MeterEventManager
attr_accessor :api_key, :meter_event_session

def initialize(api_key)
@api_key = api_key
@meter_event_session = nil
end

def refresh_meter_event_session
return unless @meter_event_session.nil? || DateTime.parse(@meter_event_session.expires_at) <= DateTime.now

# Create a new meter event session in case the existing session expired
client = Stripe::StripeClient.new(api_key)
@meter_event_session = client.v2.billing.meter_event_session.create
end

def send_meter_event(meter_event)
# Refresh the meter event session if necessary
refresh_meter_event_session

# Create a meter event with the current session's authentication token
client = Stripe::StripeClient.new(meter_event_session.authentication_token)
client.v2.billing.meter_event_stream.create(
events: [meter_event]
)
end
end

# Send meter events
api_key = "{{API_KEY}}"
customer_id = "{{CUSTOMER_ID}}"

manager = MeterEventManager.new(api_key)
manager.send_meter_event(
{
event_name: "alpaca_ai_tokens",
payload: {
"stripe_customer_id" => customer_id,
"value" => "25",
},
}
)
24 changes: 24 additions & 0 deletions examples/new_example.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# frozen_string_literal: true

require "stripe"
require "date"

class NewExample
attr_accessor :api_key

def initialize(api_key)
@api_key = api_key
end

def do_something_great
puts "Hello World"
# client = Stripe::StripeClient.new(api_key)
# client.v1
end
end

# Send meter events
api_key = "{{API_KEY}}"

example = NewExample.new(api_key)
example.do_something_great
28 changes: 28 additions & 0 deletions examples/stripe_webhook_handler.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# frozen_string_literal: true
# typed: false

require "stripe"
require "sinatra"

api_key = ENV.fetch("STRIPE_API_KEY", nil)
# Retrieve the webhook secret from the environment variable
webhook_secret = ENV.fetch("WEBHOOK_SECRET", nil)

client = Stripe::StripeClient.new(api_key)

post "/webhook" do
webhook_body = request.body.read
sig_header = request.env["HTTP_STRIPE_SIGNATURE"]
thin_event = client.parse_thin_event(webhook_body, sig_header, webhook_secret)

# Fetch the event data to understand the failure
event = client.v2.core.events.retrieve(thin_event.id)
if event.instance_of? Stripe::V1BillingMeterErrorReportTriggeredEvent
meter = event.fetch_related_object
meter_id = meter.id
puts "Success!", meter_id
end

# Record the failures and alert your team
status 200
end
Loading

0 comments on commit eff7ad9

Please sign in to comment.