Files
MatchLiveTv/backend/app/services/billing/stripe/finalize_subscription.rb
Emiliano Frascaro a5e781729c Billing: fatture manuali, profilo obbligatorio e piani Stripe mensile/annuale.
Rimuove link al portale Stripe in area cliente, aggiunge flusso admin per PDF
fattura e email, blocca checkout senza dati di fatturazione, allinea prezzi
a €4,90/€39,90 e €9,90/€69,90, locale italiano e documentazione deploy.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 17:10:12 +02:00

66 lines
1.7 KiB
Ruby

module Billing
module Stripe
# Passa a Free se il periodo pagato è scaduto (es. disdetta o webhook mancato in locale).
class FinalizeSubscription
def self.call(club:)
new(club: club).call
end
def initialize(club:)
@club = club
end
def call
sub = @club.subscription
return false unless sub&.stripe_subscription_id.present?
return false if sub.free?
stripe_sub = ::Stripe::Subscription.retrieve(sub.stripe_subscription_id)
if stripe_sub.status.in?(%w[canceled incomplete_expired])
downgrade!(sub)
return true
end
period_end = period_end_time(sub, stripe_sub)
return false if period_end.blank? || period_end > Time.current
if sub.cancel_at_period_end? || stripe_sub.cancel_at_period_end
downgrade!(sub)
return true
end
false
rescue ::Stripe::InvalidRequestError => e
downgrade!(sub) if e.message.include?("No such subscription")
false
end
private
def period_end_time(sub, stripe_sub)
local = sub.current_period_end
return local if local.present?
start_at, end_at = SubscriptionPeriod.times(stripe_sub)
end_at
end
def downgrade!(sub)
Billing::AssignPlan.call(
club: @club,
plan_slug: "free",
status: "active",
stripe_attrs: {
stripe_subscription_id: nil,
current_period_start: nil,
current_period_end: nil,
cancel_at_period_end: false,
billing_interval: nil
}
)
end
end
end
end