DEV: Fetch related guest payments (#234)

This commit is contained in:
Blake Erickson 2024-08-28 21:51:34 -06:00 committed by GitHub
parent 700c5e7727
commit fa5e95860b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 103 additions and 9 deletions

View File

@ -57,13 +57,9 @@ module DiscourseSubscriptions
discourse_customer = Customer.create(user_id: user.id, customer_id: customer_id)
subscription = checkout_session[:subscription]
payment_intent_id = checkout_session[:payment_intent]
if subscription.present?
Subscription.create(customer_id: discourse_customer.id, external_id: subscription)
elsif payment_intent_id
# Attach the payment intent to the customer for one-off purchases
::Stripe::PaymentIntent.update(payment_intent_id, { customer: customer_id })
end
line_items =

View File

@ -44,6 +44,14 @@ module DiscourseSubscriptions
end
end
if SiteSetting.discourse_subscriptions_pricing_table_enabled && current_user.email
related_guest_payments = fetch_guest_payments(current_user.email)
if SiteSetting.discourse_subscriptions_enable_verbose_logging
Rails.logger.warn("Related guest payments: #{related_guest_payments}")
end
data = data | related_guest_payments
end
data = data.sort_by { |pmt| pmt[:created] }.reverse
render_json_dump data
@ -71,6 +79,41 @@ module DiscourseSubscriptions
invoice_lines[:plan][:product]
invoice_product_id
end
def fetch_guest_payments(email)
guest_payments = []
starting_after = nil
begin
loop do
# Fetch charges in batches of 100, using pagination with starting_after
charges =
::Stripe::Charge.list(
limit: 100,
starting_after: starting_after,
expand: ["data.payment_intent"],
)
charges[:data].each do |charge|
# Check if the charge is associated with the given email and has no customer ID
if charge[:billing_details][:email] == email && charge[:customer].nil?
guest_payments << charge
end
end
# Check if there are more charges to fetch
break if charges[:data].empty?
break if charges[:data].count < 100
# Set starting_after to the last charge's ID for the next batch
starting_after = charges[:data].last[:id]
end
rescue ::Stripe::StripeError => e
Rails.logger.error("Stripe API error: #{e.message}")
end
guest_payments
end
end
end
end

View File

@ -220,11 +220,6 @@ RSpec.describe DiscourseSubscriptions::HooksController do
::Stripe::Webhook.stubs(:construct_event).returns(event)
::Stripe::Customer.stubs(:create).returns(id: "cus_1234")
::Stripe::PaymentIntent
.expects(:update)
.with("pi_3PsohkGHcn", { customer: "cus_1234" })
.returns({ id: "pi_3PsohkGHcn" })
end
it "is returns 200" do

View File

@ -75,5 +75,65 @@ RSpec.describe DiscourseSubscriptions::User::PaymentsController do
expect(parsed_body.count).to eq(1)
end
it "gets pricing table one-off purchases that show up as related guest payments" do
SiteSetting.discourse_subscriptions_pricing_table_enabled = true
::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 }])
::Stripe::Charge
.expects(:list)
.with(limit: 100, starting_after: nil, expand: ["data.payment_intent"])
.returns(
data: [
{
id: "ch_1HtGz2GHcn71qeAp4YjA2oB4",
amount: 2000,
currency: "usd",
billing_details: {
email: user.email,
},
customer: nil, # guest payment
payment_intent: "pi_1HtGz1GHcn71qeApT9N2Cjln",
created: Time.now.to_i,
},
{
id: "ch_2HtGz2GHcn71qeAp4YjA2oB4",
amount: 2000,
currency: "usd",
billing_details: {
email: "zxcv@example.com",
},
customer: nil, # different guest
payment_intent: "pi_2HtGz1GHcn71qeApT9N2Cjln",
created: Time.now.to_i,
},
{
id: "ch_1HtGz3GHcn71qeAp5YjA2oC5",
amount: 3000,
currency: "usd",
billing_details: {
email: "fdsa@example.com",
},
customer: "cus_1234", # This is not a guest payment
payment_intent: "pi_3HtGz2GHcn71qeApT9N2Cjln",
created: Time.now.to_i,
},
],
)
get "/s/user/payments.json"
parsed_body = response.parsed_body
# Validate that only guest payments with the specified email are returned
expect(parsed_body.count).to eq(2)
expect(parsed_body.first["id"]).to eq("ch_1HtGz2GHcn71qeAp4YjA2oB4")
expect(parsed_body.first["customer"]).to be_nil
end
end
end