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.
This commit is contained in:
parent
52cae7b1a9
commit
f0b4984cee
|
@ -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]
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue