Files
discourse-subscriptions/app/controllers/discourse_subscriptions/hooks_controller.rb
T
Blake Ericksonandspirobel 45754baa00 FEATURE: Add new stripe based pricing table (#202)
This commit adds an optional new stripe based pricing table.
If the user is logged in, the email field will be prepopulated with the users email.

The pricing table can be configured in the stripe dashboard.

Once the discourse_subscriptions_pricing_table setting is filled with the pricing table embed code from the stripe dashboard,
the pricing table will be displayed on /s/subscriptions

For more details see https://stripe.com/docs/payments/checkout/pricing-table
---------

Co-authored-by: spirobel <[email protected]>
2024-04-29 12:47:58 -06:00

110 lines
3.4 KiB
Ruby

# frozen_string_literal: true
module DiscourseSubscriptions
class HooksController < ::ApplicationController
include DiscourseSubscriptions::Group
include DiscourseSubscriptions::Stripe
requires_plugin DiscourseSubscriptions::PLUGIN_NAME
layout false
before_action :set_api_key
skip_before_action :check_xhr
skip_before_action :redirect_to_login_if_required
skip_before_action :verify_authenticity_token, only: [:create]
def create
begin
payload = request.body.read
sig_header = request.env["HTTP_STRIPE_SIGNATURE"]
webhook_secret = SiteSetting.discourse_subscriptions_webhook_secret
event = ::Stripe::Webhook.construct_event(payload, sig_header, webhook_secret)
rescue JSON::ParserError => e
return render_json_error e.message
rescue ::Stripe::SignatureVerificationError => e
return render_json_error e.message
end
case event[:type]
when "checkout.session.completed"
checkout_session = event[:data][:object]
email = checkout_session[:customer_email]
return head 200 if checkout_session[:status] != "complete"
return render_json_error "customer not found" if checkout_session[:customer].nil?
customer_id = checkout_session[:customer]
user = ::User.find_by_username_or_email(email)
discourse_customer = Customer.find_by(user_id: user.id)
if discourse_customer.nil?
discourse_customer = Customer.create(user_id: user.id, customer_id: customer_id)
end
Subscription.create(
customer_id: discourse_customer.id,
external_id: checkout_session[:subscription],
)
line_items =
::Stripe::Checkout::Session.list_line_items(checkout_session[:id], { limit: 1 })
item = line_items[:data].first
group = plan_group(item[:price])
group.add(user) unless group.nil?
discourse_customer.product_id = item[:price][:product]
discourse_customer.save!
::Stripe::Subscription.update(
checkout_session[:subscription],
{ metadata: { user_id: user.id, username: user.username } },
)
when "customer.subscription.created"
when "customer.subscription.updated"
customer =
Customer.find_by(
customer_id: event[:data][:object][:customer],
product_id: event[:data][:object][:plan][:product],
)
return render_json_error "customer not found" if !customer
return head 200 if event[:data][:object][:status] != "complete"
user = ::User.find_by(id: customer.user_id)
return render_json_error "user not found" if !user
if group = plan_group(event[:data][:object][:plan])
group.add(user)
end
when "customer.subscription.deleted"
customer =
Customer.find_by(
customer_id: event[:data][:object][:customer],
product_id: event[:data][:object][:plan][:product],
)
return render_json_error "customer not found" if !customer
Subscription.find_by(
customer_id: customer.id,
external_id: event[:data][:object][:id],
)&.destroy!
user = ::User.find(customer.user_id)
return render_json_error "user not found" if !user
if group = plan_group(event[:data][:object][:plan])
group.remove(user)
end
customer.destroy!
end
head 200
end
end
end