better_auth-stripe 0.2.0 → 0.2.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/lib/better_auth/plugins/stripe.rb +42 -6
- data/lib/better_auth/stripe/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 48af5990d2d12e5e32d5393e5af619a69e0bb6a1f8c4c1d12c092eb75486279b
|
|
4
|
+
data.tar.gz: 3fcb40459ec56c1ec7dfaabfd9a4063b1399140b2c9e95704f332dc1acc2ce14
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '019497cea0a84e06440b5405fd220f0da1507a500b4e42c95a7b31e8d8befd2e1636750232d6268b3a80a4302de84b5ee84695fd8e311cb32f4c6b6b80147565'
|
|
7
|
+
data.tar.gz: b5cd4a313e2480e6e2f7420242840dccf1a3081a2f535b123c07f6c55a20220e3313930463bb4221eb23dd7838bf062c673c1330a3e82af3d5b8f6b37ee92685
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.2.1] - 2026-04-30
|
|
6
|
+
|
|
7
|
+
- Fixed Stripe checkout and subscription parity edge cases for reused customer IDs, plugin-owned schedule releases, missing checkout sessions, plan limits, and organization reference validation.
|
|
8
|
+
- Expanded Stripe organization and subscription parity coverage.
|
|
9
|
+
|
|
5
10
|
## [0.2.0] - 2026-04-29
|
|
6
11
|
|
|
7
12
|
- Aligned Stripe subscription, checkout, portal, webhook, customer, and organization flows with upstream Better Auth behavior.
|
|
@@ -257,13 +257,14 @@ module BetterAuth
|
|
|
257
257
|
raise APIError.new("BAD_REQUEST", message: STRIPE_ERROR_CODES.fetch("SUBSCRIPTION_NOT_FOUND")) unless subscription_to_update && subscription_to_update["referenceId"] == reference_id
|
|
258
258
|
end
|
|
259
259
|
|
|
260
|
+
subscriptions = subscription_to_update ? [subscription_to_update] : ctx.context.adapter.find_many(model: "subscription", where: [{field: "referenceId", value: reference_id}])
|
|
261
|
+
reference_customer_id = subscriptions.find { |entry| entry["stripeCustomerId"] }&.fetch("stripeCustomerId", nil)
|
|
260
262
|
customer_id = if customer_type == "organization"
|
|
261
|
-
subscription_to_update&.fetch("stripeCustomerId", nil) || stripe_organization_customer(config, ctx, reference_id, body[:metadata])
|
|
263
|
+
subscription_to_update&.fetch("stripeCustomerId", nil) || reference_customer_id || stripe_organization_customer(config, ctx, reference_id, body[:metadata])
|
|
262
264
|
else
|
|
263
|
-
subscription_to_update&.fetch("stripeCustomerId", nil) || user["stripeCustomerId"] || stripe_create_customer(config, ctx, user, body[:metadata])
|
|
265
|
+
subscription_to_update&.fetch("stripeCustomerId", nil) || reference_customer_id || user["stripeCustomerId"] || stripe_create_customer(config, ctx, user, body[:metadata])
|
|
264
266
|
end
|
|
265
267
|
|
|
266
|
-
subscriptions = subscription_to_update ? [subscription_to_update] : ctx.context.adapter.find_many(model: "subscription", where: [{field: "referenceId", value: reference_id}])
|
|
267
268
|
active_or_trialing = subscriptions.find { |entry| stripe_active_or_trialing?(entry) }
|
|
268
269
|
active_stripe_subscriptions = stripe_active_subscriptions(config, customer_id)
|
|
269
270
|
active_stripe = active_stripe_subscriptions.find do |entry|
|
|
@@ -295,6 +296,8 @@ module BetterAuth
|
|
|
295
296
|
end
|
|
296
297
|
|
|
297
298
|
if active_stripe
|
|
299
|
+
stripe_release_plugin_schedule(ctx, config, customer_id, active_stripe, active_or_trialing || subscription_to_update)
|
|
300
|
+
|
|
298
301
|
if body[:schedule_at_period_end]
|
|
299
302
|
url = stripe_schedule_plan_change(ctx, config, active_stripe, active_or_trialing, plan, price_id, requested_seats, seat_only_plan, body)
|
|
300
303
|
next ctx.json({url: url, redirect: stripe_redirect?(body)})
|
|
@@ -517,7 +520,13 @@ module BetterAuth
|
|
|
517
520
|
subscription_id = query[:subscription_id]
|
|
518
521
|
if checkout_session_id
|
|
519
522
|
callback = callback.to_s.gsub("{CHECKOUT_SESSION_ID}", checkout_session_id.to_s)
|
|
520
|
-
checkout_session =
|
|
523
|
+
checkout_session = begin
|
|
524
|
+
stripe_client(config || {}).checkout.sessions.retrieve(checkout_session_id)
|
|
525
|
+
rescue
|
|
526
|
+
nil
|
|
527
|
+
end
|
|
528
|
+
raise ctx.redirect(stripe_url(ctx, callback)) unless checkout_session
|
|
529
|
+
|
|
521
530
|
metadata = normalize_hash(stripe_fetch(checkout_session || {}, "metadata") || {})
|
|
522
531
|
subscription_id = metadata[:subscription_id]
|
|
523
532
|
end
|
|
@@ -814,7 +823,12 @@ module BetterAuth
|
|
|
814
823
|
def stripe_plans(config)
|
|
815
824
|
plans = stripe_subscription_options(config)[:plans] || []
|
|
816
825
|
plans = plans.call if plans.respond_to?(:call)
|
|
817
|
-
Array(plans).map
|
|
826
|
+
Array(plans).map do |plan|
|
|
827
|
+
normalized = normalize_hash(plan)
|
|
828
|
+
limits = stripe_fetch(plan, "limits")
|
|
829
|
+
normalized[:limits] = limits if limits
|
|
830
|
+
normalized
|
|
831
|
+
end
|
|
818
832
|
end
|
|
819
833
|
|
|
820
834
|
def stripe_plan_by_name(config, name)
|
|
@@ -844,7 +858,7 @@ module BetterAuth
|
|
|
844
858
|
raise APIError.new("BAD_REQUEST", message: STRIPE_ERROR_CODES.fetch("ORGANIZATION_SUBSCRIPTION_NOT_ENABLED")) unless config.dig(:organization, :enabled)
|
|
845
859
|
|
|
846
860
|
reference_id = explicit_reference_id || session.fetch(:session)["activeOrganizationId"]
|
|
847
|
-
raise APIError.new("BAD_REQUEST", message: STRIPE_ERROR_CODES.fetch("
|
|
861
|
+
raise APIError.new("BAD_REQUEST", message: STRIPE_ERROR_CODES.fetch("ORGANIZATION_REFERENCE_ID_REQUIRED")) if reference_id.to_s.empty?
|
|
848
862
|
reference_id
|
|
849
863
|
end
|
|
850
864
|
|
|
@@ -1023,6 +1037,28 @@ module BetterAuth
|
|
|
1023
1037
|
stripe_url(ctx, body[:return_url] || "/")
|
|
1024
1038
|
end
|
|
1025
1039
|
|
|
1040
|
+
def stripe_release_plugin_schedule(ctx, config, customer_id, active_stripe, db_subscription)
|
|
1041
|
+
return unless stripe_schedule_id(active_stripe)
|
|
1042
|
+
return unless stripe_client(config).respond_to?(:subscription_schedules)
|
|
1043
|
+
|
|
1044
|
+
schedules = stripe_client(config).subscription_schedules.list(customer: customer_id)
|
|
1045
|
+
active_subscription_id = stripe_fetch(active_stripe, "id")
|
|
1046
|
+
existing = Array(stripe_fetch(schedules, "data")).find do |schedule|
|
|
1047
|
+
subscription = stripe_fetch(schedule, "subscription")
|
|
1048
|
+
schedule_subscription_id = subscription.is_a?(Hash) ? stripe_id(subscription) : subscription
|
|
1049
|
+
metadata = stripe_fetch(schedule, "metadata") || {}
|
|
1050
|
+
schedule_subscription_id == active_subscription_id &&
|
|
1051
|
+
stripe_fetch(schedule, "status") == "active" &&
|
|
1052
|
+
stripe_metadata_fetch(metadata, "source") == "@better-auth/stripe"
|
|
1053
|
+
end
|
|
1054
|
+
return unless existing
|
|
1055
|
+
|
|
1056
|
+
stripe_client(config).subscription_schedules.release(stripe_id(existing))
|
|
1057
|
+
if db_subscription
|
|
1058
|
+
ctx.context.adapter.update(model: "subscription", where: [{field: "id", value: db_subscription.fetch("id")}], update: {stripeScheduleId: nil})
|
|
1059
|
+
end
|
|
1060
|
+
end
|
|
1061
|
+
|
|
1026
1062
|
def stripe_direct_subscription_update?(old_plan, plan, auto_managed_seats)
|
|
1027
1063
|
return true if auto_managed_seats && old_plan && old_plan[:seat_price_id] != plan[:seat_price_id]
|
|
1028
1064
|
|