In my Rails 7 application, I am working with a Subscription model and therefore am implementing subscriptions through the Stripe API.
See below the payment method (subscriptions_controller.rb) which is triggered when user clicks a 'choose plan' button. The redirection worked, then didn't work, then worked again; me not changing a thing about how the subscription is created and how I am retrieving the URL.
def payment
@subscription = current_user.subscription
if @subscription
plan_id = params[:plan_id]
@subscription.update(id: @subscription.id, plan_id:, user_id: current_user.id, active: true)
else
subscription_id = SecureRandom.uuid
plan_id = params[:plan_id]
@subscription = Subscription.new(id: subscription_id, plan_id:, user_id: current_user.id)
end
@checkout_session = create_checkout_session(@subscription)
@subscription.checkout_session_id = @checkout_session.id
@subscription.save!
redirect_to @checkout_session.url, allow_other_host: true
end
private
def create_checkout_session(subscription)
Stripe::Checkout::Session.create({
customer: current_user.stripe_id,
payment_method_types: ['card'],
line_items: [{
price: subscription.plan.stripe_price_id,
quantity: 1
}],
mode: 'subscription',
success_url: subscription_url(subscription),
cancel_url: new_subscription_url
})
end
Error messages
"Something went wrong. The page you were looking for could not be found. Please check the URL or contact the merchant."
"CheckoutInitError: apiKey is not set".
Calling a raise before the redirection and taking the URL from there works. Taking the URL from the Stripe developer logs (meaning from the created checkout session) also works.
What is wrong with my redirect call?
I added a raise before the redirect_to call and checked whether the URLs are the same:
>> @checkout_session.url
"https://checkout.stripe.com/c/pay/cs_test_a1ayFdxprxmpwtZA9cyvECPG2bNaLnCN7e5UToqdr8oNrDxZKfm1BrFts9#fidkdWxOYHwnPyd1blpxYHZxWjA0SENmbjZOdzF0UWNqbkhndD1SY0l8TUxkR2B0fUZ9PH9MX0w2T05Bcz1Cb11taU1AcTxRQkhWTFZGdWo2Z1F1MXZJfENzcDdOYlxjM0NAV01nUlRsTkNDNTVLX0twf3FyQicpJ2N3amhWYHdzYHcnP3F3cGApJ2lkfGpwcVF8dWAnPyd2bGtiaWBabHFgaCcpJ2BrZGdpYFVpZGZgbWppYWB3dic%2FcXdwYHgl"
>> redirect_to @checkout_session.url, allow_other_host: true
"<html><body>You are being <a href=\"https://checkout.stripe.com/c/pay/cs_test_a1ayFdxprxmpwtZA9cyvECPG2bNaLnCN7e5UToqdr8oNrDxZKfm1BrFts9#fidkdWxOYHwnPyd1blpxYHZxWjA0SENmbjZOdzF0UWNqbkhndD1SY0l8TUxkR2B0fUZ9PH9MX0w2T05Bcz1Cb11taU1AcTxRQkhWTFZGdWo2Z1F1MXZJfENzcDdOYlxjM0NAV01nUlRsTkNDNTVLX0twf3FyQicpJ2N3amhWYHdzYHcnP3F3cGApJ2lkfGpwcVF8dWAnPyd2bGtiaWBabHFgaCcpJ2BrZGdpYFVpZGZgbWppYWB3dic%2FcXdwYHgl\">redirected</a>.</body></html>"
The first one works, the second one (the one it is redirected to) has a backslash at the end (which you can't even see when I post it in here). If I take it off and refresh, it works. Why is this added and how can I remove it?
I was just running into this exact issue today and found the problem. It looks like Turbo is messing with the redirect.
I was able to fix it by simply adding data: { turbo: false }
to the link to the payment route which redirects to Stripe.