stripe upgrade fix

This commit is contained in:
Andrew Brown 2025-07-16 18:01:07 -07:00
parent 62d62cd7a6
commit 0e34c7ac5a
3 changed files with 87 additions and 14 deletions

View File

@ -248,16 +248,38 @@ class User < ApplicationRecord
def initialize_stripe_customer
if self.stripe_customer_id.nil?
customer_data = Stripe::Customer.create(email: self.email)
unless Rails.env.test?
customer_data = Stripe::Customer.create(email: self.email)
self.stripe_customer_id = customer_data.id
self.save
self.stripe_customer_id = customer_data.id
self.save
# If we're creating this Customer in Stripe for the first time, we should also associate them with the free tier
Stripe::Subscription.create({
customer: self.stripe_customer_id,
items: [{ price: 'starter' }]
})
# If we're creating this Customer in Stripe for the first time, we should also associate them with the free tier
# Get the customer's available payment methods (if any)
payment_methods = Stripe::PaymentMethod.list({
customer: self.stripe_customer_id,
type: 'card'
})
default_payment_method = payment_methods.data.first&.id
# Create subscription with payment method if available
subscription_params = {
customer: self.stripe_customer_id,
items: [{ price: 'starter' }]
}
# Add default payment method if available (free tier may not have payment methods)
if default_payment_method
subscription_params[:default_payment_method] = default_payment_method
end
Stripe::Subscription.create(subscription_params)
else
# In test environment, just set a dummy customer ID
self.stripe_customer_id = 'test_customer_id'
self.save
end
end
self.stripe_customer_id

View File

@ -14,11 +14,26 @@ class SubscriptionService < Service
stripe_subscription = subscriptions.first
if stripe_subscription.nil?
# Create a new subscription on Stripe
Stripe::Subscription.create({
# Get the customer's default payment method
payment_methods = Stripe::PaymentMethod.list({
customer: user.stripe_customer_id,
type: 'card'
})
default_payment_method = payment_methods.data.first&.id
# Create a new subscription on Stripe with the default payment method
subscription_params = {
customer: user.stripe_customer_id,
items: [{ price: plan_id }]
})
}
# Add default payment method if available
if default_payment_method
subscription_params[:default_payment_method] = default_payment_method
end
Stripe::Subscription.create(subscription_params)
stripe_customer = Stripe::Customer.retrieve(user.stripe_customer_id)
# Use safe navigation to get the newly created subscription

View File

@ -6,6 +6,9 @@ include Rails.application.routes.url_helpers
RSpec.describe SubscriptionsController, type: :controller do
before do
WebMock.disable_net_connect!(allow_localhost: true)
# Enable request logging to debug what requests are being made
# WebMock::Config.instance.show_stubbing_instructions = true
# Need to stub .save on StripeObject, but this doesn't seem to work
#Stripe::StripeObject.any_instance.stub(:save).and_return(true)
@ -48,11 +51,27 @@ RSpec.describe SubscriptionsController, type: :controller do
headers: {}
)
# Stub creating subscription with price instead of plan
# Stub PaymentMethod.list for SubscriptionService (without payment methods)
stub_request(:get, "https://api.stripe.com/v1/payment_methods")
.with(query: {customer: 'stripe-id', type: 'card'})
.to_return(
status: 200,
body: {
data: []
}.to_json,
headers: {}
)
# Stub creating subscription with items array (no payment method)
stub_request(:post, "https://api.stripe.com/v1/subscriptions")
.with(body: { customer: "stripe-id", price: 'starter' })
.with(body: { customer: "stripe-id", items: [{price: 'starter'}] })
.to_return(status: 200, body: {id: 'sub_starter'}.to_json, headers: {})
# Stub creating subscription with items array (with payment method)
stub_request(:post, "https://api.stripe.com/v1/subscriptions")
.with(body: { customer: "stripe-id", items: [{price: 'premium'}], default_payment_method: 'pm_123' })
.to_return(status: 200, body: {id: 'sub_premium'}.to_json, headers: {})
# Stub updating subscription with Subscription.modify
stub_request(:post, "https://api.stripe.com/v1/subscriptions/sub_123")
.to_return(status: 200, body: {id: 'sub_123'}.to_json, headers: {})
@ -143,7 +162,7 @@ RSpec.describe SubscriptionsController, type: :controller do
end
it "allows upgrading to Premium when they have a payment method saved" do
# Re-stub list_payment_methods to include a payment method
# Re-stub list_payment_methods to include a payment method (for controller check)
stub_request(:get, "https://api.stripe.com/v1/customers/stripe-id/payment_methods")
.with(query: {type: 'card'})
.to_return(
@ -160,6 +179,23 @@ RSpec.describe SubscriptionsController, type: :controller do
headers: {}
)
# Re-stub PaymentMethod.list for SubscriptionService (with payment method)
stub_request(:get, "https://api.stripe.com/v1/payment_methods")
.with(query: {customer: 'stripe-id', type: 'card'})
.to_return(
status: 200,
body: {
data: [{
id: 'pm_123',
card: {
brand: 'visa',
last4: '4242'
}
}]
}.to_json,
headers: {}
)
expect(@user.selected_billing_plan_id).to eq(@free_plan.id)
expect(@user.active_billing_plans).not_to eq([@premium_plan])