0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-14 13:58:53 +08:00
discourse/plugins/discourse-subscriptions/app/controllers/discourse_subscriptions/user/subscriptions_controller.rb
Jarek Radosz fbb3bf3fe8
DEV: Enable Style/RedundantBegin rubocop rule (#40096)
(to be enabled in the shared config)

best reviewed with whitespace disabled
2026-05-19 18:44:54 +02:00

119 lines
3.7 KiB
Ruby
Vendored

# frozen_string_literal: true
module DiscourseSubscriptions
module User
class SubscriptionsController < ::ApplicationController
include DiscourseSubscriptions::Stripe
include DiscourseSubscriptions::Group
requires_plugin PLUGIN_NAME
before_action :find_subscription, only: %i[update destroy]
requires_login
def index
customer = Customer.where(user_id: current_user.id)
customer_ids = customer.map { |c| c.id } if customer
stripe_customer_ids = customer.map { |c| c.customer_id }.uniq if customer
subscription_ids =
Subscription.where("customer_id in (?)", customer_ids).pluck(:external_id) if customer_ids
subscriptions = []
if subscription_ids
prices = []
price_params = { limit: 100, expand: ["data.product"] }
loop do
response = ::Stripe::Price.list(price_params, stripe_request_opts)
prices.concat(response[:data])
break unless response[:has_more]
price_params[:starting_after] = response[:data].last.id
end
all_subscriptions = []
stripe_customer_ids.each do |stripe_customer_id|
customer_subscriptions =
::Stripe::Subscription.list(
{ customer: stripe_customer_id, status: "all" },
stripe_request_opts,
)
all_subscriptions.concat(customer_subscriptions[:data])
end
subscriptions = all_subscriptions.select { |sub| subscription_ids.include?(sub[:id]) }
subscriptions.map! do |subscription|
plan = prices.find { |p| p[:id] == subscription[:items][:data][0][:price][:id] }
subscription.to_h.except!(:plan)
subscription.to_h.merge(plan: plan, product: plan[:product].to_h.slice(:id, :name))
end
end
render_json_dump subscriptions
rescue ::Stripe::InvalidRequestError => e
render_json_error e.message
end
def destroy
# we cancel but don't remove until the end of the period
# full removal is done via webhooks
subscription =
::Stripe::Subscription.update(
params[:id],
{ cancel_at_period_end: true },
stripe_request_opts,
)
if subscription
render_json_dump subscription
else
render_json_error I18n.t("discourse_subscriptions.customer_not_found")
end
rescue ::Stripe::InvalidRequestError => e
render_json_error e.message
end
def update
params.require(:payment_method)
begin
attach_method_to_customer(@subscription.customer_id, params[:payment_method])
::Stripe::Subscription.update(
params[:id],
{ default_payment_method: params[:payment_method] },
stripe_request_opts,
)
render json: success_json
rescue ::Stripe::InvalidRequestError
render_json_error I18n.t("discourse_subscriptions.card.invalid")
end
end
private
def attach_method_to_customer(customer_id, method)
customer = Customer.find(customer_id)
::Stripe::PaymentMethod.attach(
method,
{ customer: customer.customer_id },
stripe_request_opts,
)
end
def find_subscription
@subscription ||=
Subscription.joins(:customer).find_by(
external_id: params[:id],
customer: {
user_id: current_user.id,
},
)
if @subscription.nil?
render_json_error I18n.t("discourse_subscriptions.subscription_not_found"),
status: 404 and return
end
end
end
end
end