diff --git a/app/services/discourse_subscriptions/campaign.rb b/app/services/discourse_subscriptions/campaign.rb index 16aec62..365a9d9 100644 --- a/app/services/discourse_subscriptions/campaign.rb +++ b/app/services/discourse_subscriptions/campaign.rb @@ -154,26 +154,30 @@ module DiscourseSubscriptions all_invoices = ::Stripe::Invoice.list(limit: 100, starting_after: current_set[:last_record]) - current_set[:last_record] = all_invoices[:data].last[:id] if all_invoices[:data].present? - current_set[:has_more] = all_invoices[:has_more] + if all_invoices[:data].present? + current_set[:last_record] = all_invoices[:data].last[:id] + current_set[:has_more] = all_invoices[:has_more] - all_invoices[:data].each do |invoice| - customer_id = invoice[:customer] - next if invoice[:paid] != true - line_item = invoice[:lines][:data][0] if invoice[:lines] && invoice[:lines][:data] # Discourse only makes single-line item charges - # check if non-subscription and that the plan is active - if line_item[:plan] == nil && line_item[:price] && - line_item[:price][:recurring] == nil && line_item[:price][:active] == true - product_id = line_item[:price][:product] - if product_ids.include? product_id - line_data = { - customer_id: customer_id, - product_id: product_id, - price: line_item[:price][:unit_amount], - } - one_time_payments << line_data + all_invoices[:data].each do |invoice| + customer_id = invoice[:customer] + next if invoice[:paid] != true + line_item = invoice[:lines][:data][0] if invoice[:lines] && invoice[:lines][:data] # Discourse only makes single-line item charges + # check if non-subscription and that the plan is active + if line_item && line_item[:plan] == nil && line_item[:price] && + line_item[:price][:recurring] == nil && line_item[:price][:active] == true + product_id = line_item[:price][:product] + if product_ids.include? product_id + line_data = { + customer_id: customer_id, + product_id: product_id, + price: line_item[:price][:unit_amount], + } + one_time_payments << line_data + end end end + else + current_set[:has_more] = false end end end diff --git a/spec/services/campaign_spec.rb b/spec/services/campaign_spec.rb index 116439a..241d9ae 100644 --- a/spec/services/campaign_spec.rb +++ b/spec/services/campaign_spec.rb @@ -62,6 +62,10 @@ describe DiscourseSubscriptions::Campaign do }, } end + let(:invoice_with_nil_lines) { { id: "in_1236", paid: true, lines: nil } } + let(:invoice_with_nil_price) do + { id: "in_1237", paid: true, lines: { data: [{ plan: nil, price: nil }] } } + end before do Fabricate(:product, external_id: "prodct_23456") @@ -104,6 +108,20 @@ describe DiscourseSubscriptions::Campaign do DiscourseSubscriptions::Campaign.new.refresh_data expect(Discourse.redis.get("subscriptions_goal_met_date")).to be_blank end + + it "handles invoices with nil lines gracefully" do + ::Stripe::Subscription.expects(:list).returns(data: [subscription], has_more: false) + ::Stripe::Invoice.expects(:list).returns(data: [invoice_with_nil_lines], has_more: false) + + expect { DiscourseSubscriptions::Campaign.new.refresh_data }.not_to raise_error + end + + it "handles invoices with nil price gracefully" do + ::Stripe::Subscription.expects(:list).returns(data: [subscription], has_more: false) + ::Stripe::Invoice.expects(:list).returns(data: [invoice_with_nil_price], has_more: false) + + expect { DiscourseSubscriptions::Campaign.new.refresh_data }.not_to raise_error + end end context "with a campaign product set" do