Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ jobs:
- ubuntu-24.04
# https://docs.stripe.com/sdks/versioning?lang=ruby#stripe-sdk-language-version-support-policy
# https://endoflife.date/ruby
ruby-version: ['2.7', '3.0', '3.1', '3.2', '3.3', '3.4', jruby-9.4.7.0, truffleruby-25.0.0]
ruby-version: ['3.0', '3.1', '3.2', '3.3', '3.4', jruby-9.4.7.0, truffleruby-25.0.0]
include:
- os: windows-latest
# use any modern-ish version
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
title: Rename `Stripe::Reversal` to `Stripe::TransferReversal`
pr_url: https://github.com/stripe/stripe-ruby/pull/1971
semver_level: major
---

- Rename the `Stripe::Reversal` resource class to `Stripe::TransferReversal`. Update references and Sorbet type annotations to use `Stripe::TransferReversal`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
title: Drop support for Ruby 2.7
semver_level: major
Comment thread
jar-stripe marked this conversation as resolved.
---
39 changes: 39 additions & 0 deletions .hark/migration-guides/v20.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Migration guide for v20

<!-- This is the migration guide for the next major version!
If you're making breaking changes, add a new h2 header with a nice title and write a detailed guide to help users upgrade.
You will almost certainly need before/after code examples and information about which users this change affects.
See: https://github.com/stripe/hark#writing-a-great-migration-guide
-->

This version uses API version `2026-09-30.endive`. If the format of this API version looks new to you, see our new [API release process](https://stripe.com/blog/introducing-stripes-new-api-release-process).
Comment thread
jar-stripe marked this conversation as resolved.

Please review our API changelog for `2026-09-30.endive` to understand all the breaking changes to the Stripe API, the reasons behind them and potential alternatives.

The Ruby SDK specific [changelog for v20](https://github.com/stripe/stripe-ruby/blob/master/CHANGELOG.md) has the corresponding changes in the SDKs as well as SDK specific breaking changes.

## Minimum Ruby version raised to 3.0

Ruby 2.7 is no longer supported. The gem now requires Ruby >= 3.0.0.

**Action required**: Upgrade to Ruby 3.0 or later before updating to the latest SDK version. For more information, see our [language version support policy](https://docs.stripe.com/sdks/versioning?lang=ruby#stripe-sdk-language-version-support-policy).

Note that this is the last major release that supports Ruby `3.0`. Please make plans to update to a higher version before March 2027.

## Rename `Stripe::Reversal` to `Stripe::TransferReversal`

The class representing a transfer reversal has been renamed from `Stripe::Reversal` to `Stripe::TransferReversal`

This change affects integrations that reference `Stripe::Reversal` directly, including class comparisons, `is_a?` checks, and Sorbet type annotations. Replace those references with `Stripe::TransferReversal`:

```ruby
# Before
reversal = Stripe::Transfer.retrieve_reversal("tr_123", "trr_123")
reversal.is_a?(Stripe::Reversal)

# After
reversal = Stripe::Transfer.retrieve_reversal("tr_123", "trr_123")
reversal.is_a?(Stripe::TransferReversal)
```

The methods for creating, retrieving, updating, and listing transfer reversals have not changed. Code that only calls those methods and reads attributes from the returned object does not require an update.
2 changes: 1 addition & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ inherit_from: .rubocop_todo.yml

AllCops:
DisplayCopNames: true
TargetRubyVersion: 2.7
TargetRubyVersion: 3.0
SuggestExtensions: false

Layout/CaseIndentation:
Expand Down
7 changes: 3 additions & 4 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ group :development do

gem "test-unit"

# Version doesn't matter that much, but this one contains some fixes for Ruby
# 2.7 warnings that add noise to the test suite.
# Version doesn't matter that much, but this one contains fixes that reduce
# warning noise in the test suite.
gem "webmock", ">= 3.8.0"

# Rubocop changes pretty quickly: new cops get added and old cops change
Expand All @@ -24,8 +24,7 @@ group :development do
# bad, pin to a specific version number here. Try to keep this relatively
# up-to-date, but it's not the end of the world if it's not.
#
# The latest version of rubocop is only compatible with Ruby 2.7+
gem "rubocop", "1.75.2" if RUBY_VERSION >= "2.7"
gem "rubocop", "1.75.2"

unless RUBY_PLATFORM =~ /mingw|mswin/
gem "sorbet"
Expand Down
8 changes: 1 addition & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,6 @@ codegen-format:

ci-test:
bundle install && bundle exec rake test
@version=$$(ruby -e "puts RUBY_VERSION.split('.')[0..1].join.to_i"); \
if [ $$version -ge 27 ]; then \
echo "Ruby version >= 2.7, continue with srb tc"; \
bundle exec srb tc; \
else \
echo "Ruby version < 2.7, skipping srb tc"; \
fi
bundle exec srb tc

test: ci-test
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ gem build stripe.gemspec

### Requirements

Per our [Language Version Support Policy](https://docs.stripe.com/sdks/versioning?lang=ruby#stripe-sdk-language-version-support-policy), we currently support **Ruby 2.7+**.
Per our [Language Version Support Policy](https://docs.stripe.com/sdks/versioning?lang=ruby#stripe-sdk-language-version-support-policy), we currently support **Ruby 3.0+**.

Support for Ruby 2.7 is deprecated and will be removed in upcoming major versions. Read more and see the full schedule in the docs: https://docs.stripe.com/sdks/versioning?lang=ruby#stripe-sdk-language-version-support-policy
Support for Ruby 3.0 is deprecated and will be removed in upcoming major versions. Read more and see the full schedule in the docs: https://docs.stripe.com/sdks/versioning?lang=ruby#stripe-sdk-language-version-support-policy

### Bundler

Expand Down
6 changes: 1 addition & 5 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,7 @@ update-certs: install

# run sorbet to check type definitions
typecheck: install
{{ if semver_matches(`ruby -e "puts RUBY_VERSION"`, ">=2.7") == "true" { \
"bundle exec srb tc" \
} else { \
"echo \"Ruby version < 2.7, skipping srb tc\"" \
} }}
bundle exec srb tc

# called by tooling
[private]
Expand Down
2 changes: 1 addition & 1 deletion lib/stripe/object_types.rb
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def self.object_names_to_classes
Reserve::Plan.object_name => Reserve::Plan,
Reserve::Release.object_name => Reserve::Release,
ReserveTransaction.object_name => ReserveTransaction,
Reversal.object_name => Reversal,
TransferReversal.object_name => TransferReversal,
Review.object_name => Review,
SetupAttempt.object_name => SetupAttempt,
SetupIntent.object_name => SetupIntent,
Expand Down
4 changes: 2 additions & 2 deletions lib/stripe/resources.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ module Stripe
autoload :Quote, "stripe/resources/quote"
autoload :Refund, "stripe/resources/refund"
autoload :ReserveTransaction, "stripe/resources/reserve_transaction"
autoload :Reversal, "stripe/resources/reversal"
autoload :Review, "stripe/resources/review"
autoload :SetupAttempt, "stripe/resources/setup_attempt"
autoload :SetupIntent, "stripe/resources/setup_intent"
Expand All @@ -79,6 +78,7 @@ module Stripe
autoload :Token, "stripe/resources/token"
autoload :Topup, "stripe/resources/topup"
autoload :Transfer, "stripe/resources/transfer"
autoload :TransferReversal, "stripe/resources/transfer_reversal"
autoload :WebhookEndpoint, "stripe/resources/webhook_endpoint"

module Apps
Expand Down Expand Up @@ -424,7 +424,6 @@ module Stripe
stripe/resources/reserve/plan
stripe/resources/reserve/release
stripe/resources/reserve_transaction
stripe/resources/reversal
stripe/resources/review
stripe/resources/setup_attempt
stripe/resources/setup_intent
Expand Down Expand Up @@ -456,6 +455,7 @@ module Stripe
stripe/resources/token
stripe/resources/topup
stripe/resources/transfer
stripe/resources/transfer_reversal
stripe/resources/treasury/credit_reversal
stripe/resources/treasury/debit_reversal
stripe/resources/treasury/financial_account
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ module Stripe
# reversal.
#
# Related guide: [Reverse transfers](https://docs.stripe.com/connect/separate-charges-and-transfers#reverse-transfers)
class Reversal < APIResource
class TransferReversal < APIResource
include Stripe::APIOperations::Save

OBJECT_NAME = "transfer_reversal"
Expand Down
4 changes: 2 additions & 2 deletions lib/stripe/stripe_object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,8 @@ def inspect
# ==== Attributes
#
# * +values+ - Hash of values to use to update the current attributes of
# the object. If you are on ruby 2.7 or higher make sure to wrap in curly
# braces to be ruby 3 compatible.
# the object. Make sure to wrap values in curly braces for Ruby 3
# compatibility.
# * +opts+ - Options for +StripeObject+ like an API key that will be reused
# on subsequent API calls.
#
Expand Down
16 changes: 8 additions & 8 deletions rbi/stripe.rbi
Original file line number Diff line number Diff line change
Expand Up @@ -5808,7 +5808,7 @@ module Stripe
def reporting_category; end
# This transaction relates to the Stripe object.
sig {
returns(T.nilable(T.any(String, T.any(::Stripe::ApplicationFee, ::Stripe::Charge, ::Stripe::ConnectCollectionTransfer, ::Stripe::CustomerCashBalanceTransaction, ::Stripe::Dispute, ::Stripe::ApplicationFeeRefund, ::Stripe::Issuing::Authorization, ::Stripe::Issuing::Dispute, ::Stripe::Issuing::Transaction, ::Stripe::Payout, ::Stripe::Refund, ::Stripe::ReserveTransaction, ::Stripe::TaxDeductedAtSource, ::Stripe::Topup, ::Stripe::Transfer, ::Stripe::Reversal))))
returns(T.nilable(T.any(String, T.any(::Stripe::ApplicationFee, ::Stripe::Charge, ::Stripe::ConnectCollectionTransfer, ::Stripe::CustomerCashBalanceTransaction, ::Stripe::Dispute, ::Stripe::ApplicationFeeRefund, ::Stripe::Issuing::Authorization, ::Stripe::Issuing::Dispute, ::Stripe::Issuing::Transaction, ::Stripe::Payout, ::Stripe::Refund, ::Stripe::ReserveTransaction, ::Stripe::TaxDeductedAtSource, ::Stripe::Topup, ::Stripe::Transfer, ::Stripe::TransferReversal))))
}
def source; end
# The transaction's net funds status in the Stripe balance, which are either `available` or `pending`.
Expand Down Expand Up @@ -39307,13 +39307,13 @@ module Stripe
sig { returns(T.nilable(String)) }
def receipt_number; end
# The transfer reversal that's associated with the refund. Only present if the charge came from another Stripe account.
sig { returns(T.nilable(T.any(String, ::Stripe::Reversal))) }
sig { returns(T.nilable(T.any(String, ::Stripe::TransferReversal))) }
def source_transfer_reversal; end
# Status of the refund. This can be `pending`, `requires_action`, `succeeded`, `failed`, or `canceled`. Learn more about [failed refunds](https://docs.stripe.com/refunds#failed-refunds).
sig { returns(T.nilable(String)) }
def status; end
# This refers to the transfer reversal object if the accompanying transfer reverses. This is only applicable if the charge was created using the destination parameter.
sig { returns(T.nilable(T.any(String, ::Stripe::Reversal))) }
sig { returns(T.nilable(T.any(String, ::Stripe::TransferReversal))) }
def transfer_reversal; end
# Cancels a refund with a status of requires_action.
#
Expand Down Expand Up @@ -50102,7 +50102,7 @@ module Stripe
# reversal.
#
# Related guide: [Reverse transfers](https://docs.stripe.com/connect/separate-charges-and-transfers#reverse-transfers)
class Reversal < APIResource
class TransferReversal < APIResource
# Amount, in cents (or local equivalent).
sig { returns(Integer) }
def amount; end
Expand Down Expand Up @@ -61417,7 +61417,7 @@ module Stripe
#
# Once entirely reversed, a transfer can't be reversed again. This method will return an error when called on an already-reversed transfer, or when trying to reverse more money than is left on a transfer.
sig {
params(id: String, params: T.any(::Stripe::TransferReversalCreateParams, T::Hash[T.untyped, T.untyped]), opts: T.untyped).returns(::Stripe::Reversal)
params(id: String, params: T.any(::Stripe::TransferReversalCreateParams, T::Hash[T.untyped, T.untyped]), opts: T.untyped).returns(::Stripe::TransferReversal)
}
def create(id, params = {}, opts = {}); end

Expand All @@ -61429,15 +61429,15 @@ module Stripe

# By default, you can see the 10 most recent reversals stored directly on the transfer object, but you can also retrieve details about a specific reversal stored on the transfer.
sig {
params(transfer: String, id: String, params: T.any(::Stripe::TransferReversalRetrieveParams, T::Hash[T.untyped, T.untyped]), opts: T.untyped).returns(::Stripe::Reversal)
params(transfer: String, id: String, params: T.any(::Stripe::TransferReversalRetrieveParams, T::Hash[T.untyped, T.untyped]), opts: T.untyped).returns(::Stripe::TransferReversal)
}
def retrieve(transfer, id, params = {}, opts = {}); end

# Updates the specified reversal by setting the values of the parameters passed. Any parameters not provided will be left unchanged.
#
# This request only accepts metadata and description as arguments.
sig {
params(transfer: String, id: String, params: T.any(::Stripe::TransferReversalUpdateParams, T::Hash[T.untyped, T.untyped]), opts: T.untyped).returns(::Stripe::Reversal)
params(transfer: String, id: String, params: T.any(::Stripe::TransferReversalUpdateParams, T::Hash[T.untyped, T.untyped]), opts: T.untyped).returns(::Stripe::TransferReversal)
}
def update(transfer, id, params = {}, opts = {}); end
end
Expand Down Expand Up @@ -173643,4 +173643,4 @@ module Stripe
class EventDestinationPingParams < ::Stripe::RequestParams; end
end
end
end
end
4 changes: 2 additions & 2 deletions rbi/stripe/resources/balance_transaction.rbi
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ module Stripe
def reporting_category; end
# This transaction relates to the Stripe object.
sig {
returns(T.nilable(T.any(String, T.any(::Stripe::ApplicationFee, ::Stripe::Charge, ::Stripe::ConnectCollectionTransfer, ::Stripe::CustomerCashBalanceTransaction, ::Stripe::Dispute, ::Stripe::ApplicationFeeRefund, ::Stripe::Issuing::Authorization, ::Stripe::Issuing::Dispute, ::Stripe::Issuing::Transaction, ::Stripe::Payout, ::Stripe::Refund, ::Stripe::ReserveTransaction, ::Stripe::TaxDeductedAtSource, ::Stripe::Topup, ::Stripe::Transfer, ::Stripe::Reversal))))
returns(T.nilable(T.any(String, T.any(::Stripe::ApplicationFee, ::Stripe::Charge, ::Stripe::ConnectCollectionTransfer, ::Stripe::CustomerCashBalanceTransaction, ::Stripe::Dispute, ::Stripe::ApplicationFeeRefund, ::Stripe::Issuing::Authorization, ::Stripe::Issuing::Dispute, ::Stripe::Issuing::Transaction, ::Stripe::Payout, ::Stripe::Refund, ::Stripe::ReserveTransaction, ::Stripe::TaxDeductedAtSource, ::Stripe::Topup, ::Stripe::Transfer, ::Stripe::TransferReversal))))
}
def source; end
# The transaction's net funds status in the Stripe balance, which are either `available` or `pending`.
Expand All @@ -89,4 +89,4 @@ module Stripe
}
def self.list(params = {}, opts = {}); end
end
end
end
6 changes: 3 additions & 3 deletions rbi/stripe/resources/refund.rbi
Original file line number Diff line number Diff line change
Expand Up @@ -672,13 +672,13 @@ module Stripe
sig { returns(T.nilable(String)) }
def receipt_number; end
# The transfer reversal that's associated with the refund. Only present if the charge came from another Stripe account.
sig { returns(T.nilable(T.any(String, ::Stripe::Reversal))) }
sig { returns(T.nilable(T.any(String, ::Stripe::TransferReversal))) }
def source_transfer_reversal; end
# Status of the refund. This can be `pending`, `requires_action`, `succeeded`, `failed`, or `canceled`. Learn more about [failed refunds](https://docs.stripe.com/refunds#failed-refunds).
sig { returns(T.nilable(String)) }
def status; end
# This refers to the transfer reversal object if the accompanying transfer reverses. This is only applicable if the charge was created using the destination parameter.
sig { returns(T.nilable(T.any(String, ::Stripe::Reversal))) }
sig { returns(T.nilable(T.any(String, ::Stripe::TransferReversal))) }
def transfer_reversal; end
# Cancels a refund with a status of requires_action.
#
Expand Down Expand Up @@ -726,4 +726,4 @@ module Stripe
}
def self.update(refund, params = {}, opts = {}); end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ module Stripe
# reversal.
#
# Related guide: [Reverse transfers](https://docs.stripe.com/connect/separate-charges-and-transfers#reverse-transfers)
class Reversal < APIResource
class TransferReversal < APIResource
# Amount, in cents (or local equivalent).
sig { returns(Integer) }
def amount; end
Expand Down Expand Up @@ -48,4 +48,4 @@ module Stripe
sig { returns(T.any(String, ::Stripe::Transfer)) }
def transfer; end
end
end
end
8 changes: 4 additions & 4 deletions rbi/stripe/services/transfer_reversal_service.rbi
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ module Stripe
#
# Once entirely reversed, a transfer can't be reversed again. This method will return an error when called on an already-reversed transfer, or when trying to reverse more money than is left on a transfer.
sig {
params(id: String, params: T.any(::Stripe::TransferReversalCreateParams, T::Hash[T.untyped, T.untyped]), opts: T.untyped).returns(::Stripe::Reversal)
params(id: String, params: T.any(::Stripe::TransferReversalCreateParams, T::Hash[T.untyped, T.untyped]), opts: T.untyped).returns(::Stripe::TransferReversal)
}
def create(id, params = {}, opts = {}); end

Expand All @@ -22,16 +22,16 @@ module Stripe

# By default, you can see the 10 most recent reversals stored directly on the transfer object, but you can also retrieve details about a specific reversal stored on the transfer.
sig {
params(transfer: String, id: String, params: T.any(::Stripe::TransferReversalRetrieveParams, T::Hash[T.untyped, T.untyped]), opts: T.untyped).returns(::Stripe::Reversal)
params(transfer: String, id: String, params: T.any(::Stripe::TransferReversalRetrieveParams, T::Hash[T.untyped, T.untyped]), opts: T.untyped).returns(::Stripe::TransferReversal)
}
def retrieve(transfer, id, params = {}, opts = {}); end

# Updates the specified reversal by setting the values of the parameters passed. Any parameters not provided will be left unchanged.
#
# This request only accepts metadata and description as arguments.
sig {
params(transfer: String, id: String, params: T.any(::Stripe::TransferReversalUpdateParams, T::Hash[T.untyped, T.untyped]), opts: T.untyped).returns(::Stripe::Reversal)
params(transfer: String, id: String, params: T.any(::Stripe::TransferReversalUpdateParams, T::Hash[T.untyped, T.untyped]), opts: T.untyped).returns(::Stripe::TransferReversal)
}
def update(transfer, id, params = {}, opts = {}); end
end
end
end
2 changes: 1 addition & 1 deletion stripe.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ require "stripe/version"
Gem::Specification.new do |s|
s.name = "stripe"
s.version = Stripe::VERSION
s.required_ruby_version = ">= 2.7.0"
s.required_ruby_version = ">= 3.0.0"
s.summary = "Ruby bindings for the Stripe API"
s.description = "Stripe is the easiest way to accept payments online. " \
"See https://stripe.com for details."
Expand Down
Loading
Loading