Stripe is a very popular payment solution that integrates really well into a Rails application. There are probably many ways to get up and running, including sophisticated gems such as Payola. Here you’ll find a step-by-step tutorial to get you started collecting payments that worked for us.
Integrating Stripe to your Rails project is really simple and follows the usual practices:
The Stripe ruby gem page in GitHub advises to make sure you use the https RubyGems source in your Gemfile (which is the default when you create a new Rails app):
source 'https://rubygems.org'
And including the gem as follows:
gem 'stripe'
But then, the Ruby on Rails integration tutorial suggests?it should look like this:
gem 'stripe', git: 'https://github.com/stripe/stripe-ruby'
So let’s go with the latter, and let’s run bundler:
bundle install
It’s a good idea?to commit the changes at this point.
We’ll need a controller (and the proper routes) to handle two tasks:
Let’s generate the controller first:
bundle exec rails g controller charges
Once the file exists, you need to add the two methods:
class ChargesController < ApplicationController def new # this will remain empty unless you need to set some instance variables to pass on end def create # your charge code will live here end end
And now you want to add the routes for your controller:
resources :charges
Stripe provides a set of two keys: ‘Publishable key’ and ‘Secret key’ and they strongly advise to keep them out of source control (at least the ones for production). At Still River Software we use a YML file to read Settings from, and the Stripe sections look like this:
general: &general stripe: secret_key: your_test_secret_key publishable_key: your_test_publishable_key development: &development <<: *general test: &test <<: *general production: &production <<: *general
And for the production keys, we need to create an initializer as follows:
Rails.configuration.stripe = { :publishable_key => ENV['PUBLISHABLE_KEY'], :secret_key => ENV['SECRET_KEY'] }
The relevant step here is to setup your Stripe class object with the secret key:
Stripe.api_key = Rails.env.production? ? Rails.configuration.stripe[:secret_key] : Settings[Rails.env]['stripe']['secret_key']
Your initializer file should be called stripe.rb and has to be located under config/initializers.
And we’re good to start working on the user interface…
If you want to implement your payment page with a minimal user interface, or just want to make it look different to the user, then you can add a layout, and following Rails conventions, you should name it charges.html.erb and place it under app/views/layouts:
<!DOCTYPE html> <html> <head> </head> <body> <%= yield %> </body> </html>
This is where the?new action comes in; you need to create?new.html.erb within you?app/views/charges folder. Now, the best payment flow Stripe has for you is Checkout?(there are other paths, such as?Stripe.js); using?this library (checkout.js) you have two options:
This implementation displays a credit card overlay with all the functionality you need, including validation and error handling. All you have to do is to create a form and include a script tag to enable the?functionality from Stripe:
<%= form_tag charges_path do -%> <article> <%= label_tag 'amount', 'To Pay', class: 'amount' %> <%= label_tag 'amount', "$#{@amount}.00", class: 'amount-figure' %> </article> <script src="https://checkout.stripe.com/checkout.js" class="stripe-button" data-key="<%= Settings[Rails.env]['stripe']['publishable_key'] %>" data-description="Your payment description" data-amount="<%= @amount * 100 %>"> </script> <% end %>
The previous code?submits the form with a?stripeToken along with any other input tags?within the form. This will not create any charges, but a token instead. The tokens will be used in your?create action to create the actual charge server-side. Other use cases include saving the card for later charges or signing up the user for subscription recurring charges.
(Note that in this example we’re using??development/test publishable key.)
With this implementation you can use your own styled button or enable any?element in your DOM or JavaScript event to trigger a Checkout payment. The key here is to create a handler object (StripeCheckout.configure()) for you to call it later with the?open() function in response to any event, and, if you need to abort the?Checkout process, then you can call?close() on the the handler.
Keep in mind that the?publishable key and the?token parameters must be specified in the?configure() function. You can pass any other parameters to either?configure() or?open().
Using jQuery makes it easier to implement, but?not required, here’s the way to do it with selectors:
?<%= form_tag charges_path, id: 'stripeForm' do -%> <script src="https://checkout.stripe.com/checkout.js"></script> <article> <%= label_tag 'amount', 'To Pay', class: 'amount' %> <%= label_tag 'amount', "$#{@amount}.00", class: "amount-figure" %> </article> <br> <button id="stripe-button"> </button> <%= hidden_field_tag 'stripeToken' %> <%= hidden_field_tag 'stripeEmail' %> <%= hidden_field_tag 'stripeAmount' %> <script> var handler = StripeCheckout.configure({ key: "<%= Settings[Rails.env]['stripe']['publishable_key'] %>", token: function (token, args) { $("#stripeToken").value = token.id; $("#stripeEmail").value = token.email; $("#stripeAmount").value = <%= @amount %>; $("#stripeForm").submit(); } }); $('#stripe-button').on('click', function (e) { // Open Checkout with further options handler.open({ name: 'Your customer name', description: 'Your description goes here', amount: <%= @amount * 100 %> }); e.preventDefault(); }); $(window).on('popstate', function() { handler.close(); }); </script> <% end %>
Stripe publishes a full set of configuration options that you can use.
Once the customer has interacted with the Stripe payment form, a POST request will be sent to your?charges_controller so this is the time??to go through the code to handle the request:
class ChargesController < ApplicationController def new # this will remain empty unless you need to set some instance variables to pass on end def create # Amount in cents amount = params[:stripeAmount].to_i * 100 # Create the customer in Stripe customer = Stripe::Customer.create( email: params[:stripeEmail], card: params[:stripeToken] ) # Create the charge using the customer data returned by Stripe API charge = Stripe::Charge.create( customer: customer.id, amount: amount, description: 'Rails Stripe customer', currency: 'usd' ) # place more code upon successfully creating the charge rescue Stripe::CardError => e flash[:error] = e.message redirect_to charges_path flash[:notice] = "Please try again" end end
You can either create a view to show your users a success message or just redirect with a flash message.
And that’s it! Now you’re set with all you need to start collecting payments and explore the docs to extend the functionality in your app to take full advantage of Stripe.
Enjoy.
Tags: ruby, ruby on rails, stripe
4 Comments
1p ? Integrating Stripe into Your Ruby on Rails Application | OnAdvertise.com
[…] http://stillriver.wpengine.com/blog/integrating-stripe-into-your-ruby-on-rails-app/ […]
1p ? Integrating Stripe into Your Ruby on Rails Application – Exploding Ads
[…] http://stillriver.wpengine.com/blog/integrating-stripe-into-your-ruby-on-rails-app/ […]
1p ? Integrating Stripe into Your Ruby on Rails Application | Profit Goals
[…] http://stillriver.wpengine.com/blog/integrating-stripe-into-your-ruby-on-rails-app/ […]
1p ? Integrating Stripe into Your Ruby on Rails Application | blog.offeryour.com
[…] http://stillriver.wpengine.com/blog/integrating-stripe-into-your-ruby-on-rails-app/ […]