diff --git a/app/controllers/discourse_subscriptions/hooks_controller.rb b/app/controllers/discourse_subscriptions/hooks_controller.rb index 78bea0f..008aefc 100644 --- a/app/controllers/discourse_subscriptions/hooks_controller.rb +++ b/app/controllers/discourse_subscriptions/hooks_controller.rb @@ -44,23 +44,27 @@ module DiscourseSubscriptions discourse_customer = Customer.create(user_id: user.id, customer_id: customer_id) - Subscription.create( - customer_id: discourse_customer.id, - external_id: checkout_session[:subscription], - ) + subscription = checkout_session[:subscription] + + if !subscription.nil? + Subscription.create(customer_id: discourse_customer.id, external_id: subscription) + end 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 } }, - ) + if !subscription.nil? + ::Stripe::Subscription.update( + subscription, + { metadata: { user_id: user.id, username: user.username } }, + ) + end when "customer.subscription.created" when "customer.subscription.updated" subscription = event[:data][:object] diff --git a/app/controllers/discourse_subscriptions/user/payments_controller.rb b/app/controllers/discourse_subscriptions/user/payments_controller.rb index 9588d8d..b1acff7 100644 --- a/app/controllers/discourse_subscriptions/user/payments_controller.rb +++ b/app/controllers/discourse_subscriptions/user/payments_controller.rb @@ -27,7 +27,12 @@ module DiscourseSubscriptions payments = ::Stripe::PaymentIntent.list(customer: customer_id) payments_from_invoices = payments[:data].select { |payment| invoice_ids.include?(payment[:invoice]) } - data = data | payments_from_invoices + + # Pricing table one-off purchases do not have invoices + payments_without_invoices = + payments[:data].select { |payment| payment[:invoice].nil? } + + data = data | payments_from_invoices | payments_without_invoices end end @@ -42,14 +47,13 @@ module DiscourseSubscriptions private def parse_invoices(all_invoices, product_ids) - invoices_with_products = - all_invoices[:data].select do |invoice| - invoice_lines = invoice[:lines][:data][0] if invoice[:lines] && invoice[:lines][:data] - if invoice_lines - invoice_product_id = parse_invoice_lines(invoice_lines) - product_ids.include?(invoice_product_id) - end + all_invoices[:data].select do |invoice| + invoice_lines = invoice[:lines][:data][0] if invoice[:lines] && invoice[:lines][:data] + if invoice_lines + invoice_product_id = parse_invoice_lines(invoice_lines) + product_ids.include?(invoice_product_id) end + end end def parse_invoice_lines(invoice_lines) diff --git a/spec/requests/hooks_controller_spec.rb b/spec/requests/hooks_controller_spec.rb index b9acb62..ccb2ca2 100644 --- a/spec/requests/hooks_controller_spec.rb +++ b/spec/requests/hooks_controller_spec.rb @@ -83,6 +83,27 @@ RSpec.describe DiscourseSubscriptions::HooksController do } end + let(:checkout_session_completed_data_one_off) do + { + object: { + id: "cs_test_a1ENei5A9TGOaEketyV5qweiQR5CyJWHT5j8T3HheQY3uah3RxzKttVUKZ", + object: "checkout.session", + customer: customer.customer_id, + customer_email: user.email, + invoice: nil, + metadata: { + }, + mode: "subscription", + payment_status: "paid", + status: "complete", + submit_type: nil, + subscription: nil, + success_url: "http://localhost:4200/my/billing/subscriptions", + url: nil, + }, + } + end + let(:checkout_session_completed_bad_data) do { object: { @@ -184,6 +205,26 @@ RSpec.describe DiscourseSubscriptions::HooksController do end end + describe "checkout.session.completed for one-off purchase" do + before do + event = { + type: "checkout.session.completed", + data: checkout_session_completed_data_one_off, + } + ::Stripe::Checkout::Session + .stubs(:list_line_items) + .with(checkout_session_completed_data[:object][:id], { limit: 1 }) + .returns(list_line_items_data) + + ::Stripe::Webhook.stubs(:construct_event).returns(event) + end + + it "is returns 200" do + expect { post "/s/hooks.json" }.to change { user.groups.count }.by(1) + expect(response.status).to eq 200 + end + end + describe "checkout.session.completed with anonymous user" do before do checkout_session_completed_bad_data[:object][:customer_email] = "anonymous@example.com" diff --git a/spec/requests/user/payments_controller_spec.rb b/spec/requests/user/payments_controller_spec.rb index 5ad0563..7fe87d4 100644 --- a/spec/requests/user/payments_controller_spec.rb +++ b/spec/requests/user/payments_controller_spec.rb @@ -60,5 +60,20 @@ RSpec.describe DiscourseSubscriptions::User::PaymentsController do expect(invoice).to eq("inv_900007") expect(parsed_body.count).to eq(2) end + + it "gets pricing table one-off purchases" do + ::Stripe::Invoice.expects(:list).with(customer: "c_345678").returns(data: []) + + ::Stripe::PaymentIntent + .expects(:list) + .with(customer: "c_345678") + .returns(data: [{ id: "pi_900010", invoice: nil, created: Time.now }]) + + get "/s/user/payments.json" + + parsed_body = response.parsed_body + + expect(parsed_body.count).to eq(1) + end end end