I have recently decided to learn how to write web applications with Ruby on Rails. I am working on a simple app for learning foreign languages called Repeto and a few days ago I wanted to implement Stripe payments. Basically, I want to sell courses and have a course model in the application. There are a few columns in the course table in the database, one of them is ‘price’ with a decimal value. I would like to display a buy button on course show page. Somebody could click the button, pay with a bank card and access the course.
I had some problems with implementing this. Although Stripe provides a good Ruby on Rails implementation guide, it is slightly too simple form my app. I will have a few different courses and want to pass the specific course price via params to the charges_controller.rb. In other words, if a course costs £5, I want the buyer pay £5, if a course costs £10, £10 and so on. The price of the course need to move from show page of the product to the Stripe.charge method in charges_controller.rb.
Now I am quite newbie when it comes to Rails but the code below does the trick. Incidently, I have put this code to show.html.rb file of the course. If you sell something else, you need to find the view file showing the product and put the code there. Here’s how it looks like:
<% if flash[:error].present? %>
<p><%= flash[:error] %></p>
<% end %>
<%= hidden_field_tag 'amount', @course.price %>
<script src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="<%= Rails.application.credentials.stripe[:stripe_publishable_key] %>"
data-description="<%= @course.title %>"
data-amount="<%= @course.price * 100 %>"
<% end %>
As you can see, I have added a hidden field with the amount and pass value from the table via params. I am not sure if this is a safe solution… Perhaps it is possible somehow to pass a different price like £0.00 and access the course for free 🙁 But I am not worried at the moment since these are early stages of the application and I am still learning.
Of course, you may use different instance variable name than @course.price.
After pasting this code, click the Stripe button and make the payment (4242…). Have a look in the console, if price of the product is passed via params.
If it does, you can access it in the charges_controller.rb and use it in Charge.create method. As a result, the buyer will be charged the correct amount. This is create action in charges_controller.rb:
@amount = (params[:amount].to_f*100).round
customer = Stripe::Customer.create(
:email => params[:stripeEmail],
:source => params[:stripeToken]
charge = Stripe::Charge.create(
:customer => customer.id,
:amount => @amount,
:description => 'Rails Stripe customer',
:currency => 'gbp'
rescue Stripe::CardError => e
flash[:error] = e.message
Because Stripe charges cents and pennies and so on, I had to use some extra formatting and conversion.
That is all really. If you want to pass more product information, you can use another hidden field. I also pass course_id so when the payment is done, I can grant access to this particular course.
I hope this will help somebody to use Stripe payments. Please let me know if you have any question regarding this topic. I am not an experienced programmer, but I will try to help 🙂