As I was launching my first French online course, I needed to use Stripe to process payments. The course was built using Ruby on Rails as it's the technology I am most proficient with.
However, I felt it was hard to create a simple experience for the end-user:
- The user visits the Devise Registration page to create an account
- When he/she clicks on the button to submit the form, he/she is redirected to Stripe Checkout to perform the payment
If you follow Stripe's logic, an event listener in Javascript will listen to the submission of the form, perform an Ajax call to create the Stripe session, and then redirect to Checkout.
However, this will prevent the normal submission of Devise's registration form. You will have to submit the Devise form using Ajax, which is not the easiest.
Here are a few steps to implement a simpler solution, using no Javascript. The whole Stripe logic is managed in a Rails controller.
Move Stripe's logic to Devise's Registration controller
After setting up Devise, you will have to generate Devise's controllers to be able to customize them. Just run the following command in your terminal:
rails generate devise:controllers users
Then, change the controllers to the devise_for
routes:
devise_for :users, controllers: { registrations: 'users/registrations' }
Now we are all set to customize the after_sign_up_path_for
method of the Registration controller.
First, we initialize the Stripe API Key.
Then, we create a session with our product's parameters.
Finally, we return the session URL. This will make the page to be automatically redirected to the Checkout generated URL.
def after_sign_up_path_for(resource)
super(resource)
Stripe.api_key = "#{ENV['STRIPE_API_KEY']}"
# See https://stripe.com/docs/api/checkout/sessions/create
# for additional parameters to pass.
# {CHECKOUT_SESSION_ID} is a string literal; do not change it!
# the actual Session ID is returned in the query parameter when your customer
# is redirected to the success page.
session = Stripe::Checkout::Session.create(
success_url: "success_url",
cancel_url: "cancel_url",
payment_method_types: ['card'],
mode: 'payment',
line_items: [{
# For metered billing, do not pass quantity
quantity: 1,
price: ENV['STRIPE_PRICE_ID']
}],
locale: "fr",
customer_email: current_user.email
)
return session.url
end
Listen to Stripe's webhook
After setting up the logic to redirect the user to Checkout, we need to listen to Stripe's events to make sure he/she completed the payment of the product.
Stripe has a comprehensive documentation about setting up webhooks so I won't enter into details here.
In our routes, we add the following line (assuming you have created a Stripe controller):
post 'webhook', to: "stripe#webhook"
In order to make it work, you need to initialize Stripe's API key. Add the following method to your Stripe controller, with a before action so it's called before the webhook
method:
before_action :set_stripe_api, only: [:webhook]
...
private
def set_stripe_api
Stripe.api_key = "#{ENV['STRIPE_API_KEY']}"
end
Then, we add the webhook
method to the Stripe controller. We use here a case / when loop to process the events we are listening to (don't forget to register them in Stripe's webhook dashboard):
def webhook
payload = request.body.read
event = nil
begin
event = Stripe::Event.construct_from(
JSON.parse(payload, symbolize_names: true)
)
rescue JSON::ParserError => e
# Invalid payload
respond_to do |format|
format.json { render json: { error: e }, :status => :bad_request }
end
rescue Stripe::SignatureVerificationError => e
# Invalid signature
respond_to do |format|
format.json { render json: { error: e }, :status => :bad_request }
end
end
data_object = event.data.object
case event.type
when 'charge.succeeded'
# get the data (see doc)
customer_id = data_object["customer"]
email = data_object["billing_details"]["email"]
# do something with the customer_id and email
# ...
else
puts "Unhandled event type: #{event.type}"
end
respond_to do |format|
format.json { render json: {}, :status => 200 }
end
end
Voilà ! You have a working Stripe Checkout implementation without using any Javascript. When the user will submit the Devise registration form, he/she will be redirected automatically to Stripe Checkout!
Top comments (1)
our prebuilt UI components, to create a payment form that lets you securely collect a customer's card details without handling . جلب الحبيب بالصورة
Some comments have been hidden by the post's author - find out more