Files
discourse-subscriptions/app/controllers/discourse_subscriptions/user/payments_controller.rb
T
Blake Erickson f0b4984cee FIX: Pricing table for one-off purchases (#228)
When using the Stripe Pricing table for one-off purchases
(non-subscriptions) the webhook was encountering an error because it was
expecting subscription information which does not exist for one-off
purchases. This fix addresses that issue ensuring that no errors occur,
that users are added to the appropriate group, and that uses can see
their purchase on the billing page.
2024-08-20 13:32:32 -06:00

69 lines
2.4 KiB
Ruby

# frozen_string_literal: true
module DiscourseSubscriptions
module User
class PaymentsController < ::ApplicationController
include DiscourseSubscriptions::Stripe
requires_plugin DiscourseSubscriptions::PLUGIN_NAME
before_action :set_api_key
requires_login
def index
begin
customer = Customer.where(user_id: current_user.id)
customer_ids = customer.map { |c| c.customer_id } if customer
product_ids = Product.all.pluck(:external_id)
data = []
if customer_ids.present? && product_ids.present?
customer_ids.each do |customer_id|
# lots of matching because the Stripe API doesn't make it easy to match products => payments except from invoices
all_invoices = ::Stripe::Invoice.list(customer: customer_id)
invoices_with_products = parse_invoices(all_invoices, product_ids)
invoice_ids = invoices_with_products.map { |invoice| invoice[:id] }
payments = ::Stripe::PaymentIntent.list(customer: customer_id)
payments_from_invoices =
payments[:data].select { |payment| invoice_ids.include?(payment[:invoice]) }
# 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
data = data.sort_by { |pmt| pmt[:created] }.reverse
render_json_dump data
rescue ::Stripe::InvalidRequestError => e
render_json_error e.message
end
end
private
def parse_invoices(all_invoices, product_ids)
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)
invoice_product_id = invoice_lines[:price][:product] if invoice_lines[:price] &&
invoice_lines[:price][:product]
invoice_product_id = invoice_lines[:plan][:product] if invoice_lines[:plan] &&
invoice_lines[:plan][:product]
invoice_product_id
end
end
end
end