Your New Condo Specialist. Guiding you every step For Free Consult, Call Clara 416-930-3063

5.4 Payments with Stripe


Lesson 29: Processing Payments with Stripe

In the previous lessons, we added the ability for students to enroll in courses. Currently, users now need to be enrolled in a course in order to view the lesson detail page. In this lesson, we will integrate with a payment processor (Stripe) and charge a user's credit card when enrolling in a premium course.

 

For a very long time, credit card processing was something that was notoriously hard and painful. As soon as credit card details enter your web application's server there are very strict PCI Compliance Regulations that you are legally obligated to comply with, which add complexity to your application. PCI Compliance Regulations make sure your customer's credit card data is safe, but adds restrictions to how your application can work. PCI Compliance makes things like encryption, and professional security audits required.

Since we don't want to be burdened with the restrictions and pains of having credit card data enter our server directly, we will integrate with a service called Stripe. Stripe is a payment processor that allows all the sensitive credit card information to live on their servers, but gives us control to trigger payments on the credit card as we need. Once the user(student) sends their credit card data to Stripe, Stripe will provide us with a token, which we can use to make credit card transactions on behalf of the user(student) without needing to worry about PCI compliance.

In short: Stripe is a service that gives us the power to charge a user's credit card. Since Stripe complies with all the legislation and our server never receives sensitive data, they do all the hard work, but we get the full power of credit card payments.

Setting up your application with Stripe

Before we start collecting credit card payments, we need to create an account on the Stripe website. Visit Stripe.comand click the "Sign in" button in the top navigation. Click the link to "Sign Up" that is presented underneath the login form. Enter your account details, such as email address, password and password confirmation, and then press the Create your Stripe account button.

Once you create an account it will display a modal dialog that presents you with links to guides to getting started with Stripe. Since our lesson will run you through integrating with Stripe, click the "x" in the top right of the modal to dismiss it, which brings you to your Stripe dashboard.

Quickly look at the dashboard that Stripe presents to you now. This is the page you will see as soon as you log into your Stripe account. You should notice that Stripe allows you to charge credit cards in both Test and Live modes, and also will give you statistics about the charges that have gone through your account.

We now want to find the documentation that explains how to integrate our Stripe account with payments in our Ruby on Rails application. Click the link labeled Documentation in the top navigation. On the left-hand panel of the web page, underneath Payments, click the link to Checkout and then Reference. Finally, scroll down till you see Example integrations on the right side and click the link to Rails on the right-hand side of the page.

This page gives us in-depth instructions on how to integrate our Ruby on Rails application with the Stripe service. Let's follow along with the steps it specifies.

Setting up the Stripe gem

According to the documentation, the first step is to add the stripe gem to the Gemfile:

gem 'stripe'

Save the file.

The documentation tells us to run the bundle install command, which seems logical. Run that command:

$ bundle install
 

bundle install may fail at this step!

 

There's a chance that running the bundle install command will fail with an error message. The error message may look something like this:

Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.

/home/vagrant/.rbenv/versions/2.0.0-p353/bin/ruby extconf.rb
checking for main() in -lstdc++... no
checking for ruby/encoding.h... yes
creating Makefile

make "DESTDIR="
compiling unf.cc
make: g++: Command not found
make: *** [unf.o] Error 127

This error message indicates that there was a problem building the native extensions for the gem. I know what you're thinking: what the heck are native extensions?

Sometimes ruby programs need to run code that was written in a different programming language. Native extensions help connect ruby programs with some non-ruby programs that are on your machine. This blog post walks you through a lot of intricacies of native extensions.

Most of the time the programming language that is used for native extensions is either the C programming language or the C++ language. These programming languages give the programmer more fine-grained control of aspects of their program at the trade-off of being difficult to code in.

This error message indicates a problem with g++.

gcc is the executable for the gnu c compiler, which 95% of native extensions use.

g++ is the executable for the gnu c++ compiler, which is what about 4% of native extensions use.

This error message indicates our web development environment doesn't contain the g++ program and therefore can't build the native extension. To install the program you can use that apt-get tool we taught you about in Lesson 23.

So this problem indicates we don't have the g++ program installed. Run this command in your web development environment to install the program.

[Web Dev] /vagrant/src/flixter: $ sudo apt-get install g++

When it asks you if you're sure enter Y. Once it finishes, run the bundle install command and this time it should work like a charm.

[Web Dev] /vagrant/src/flixter: $ bundle install

Remember that after each time you run the bundle install command you will need to restart your server. Restart your server now.

The next step in the documentation tells us to generate a new controller called charges and set up the routes file. These instructions would be spot on if we wanted to build a new action to deal with the credit card transactions. In our case, we want to hook up our existing enrollments controller and create action rather than building things from scratch.

For now, let's skip down to the Configuration step in the documentation, to continue installing the Stripe gem. Once we finish the other steps we will return to the code they suggest we put inside the controller, which in our case will be the enrollments_controller rather than the charges_controller.

Configuring the API Keys

Under the configuration section of the Stripe API documentation it describes how to pull the API keys into our web application. The API keys will allow our web application to securely communicate with the Stripe servers. These API keys are very similar to the Amazon AWS API keys that we used to store images on the Amazon AWS S3 server. Before we write code to integrate our API keys, let's see what their values are.

To determine your API keys, return to your dashboard and click API in the left-hand margin. A modal dialog should be displayed to you. You may be prompted to enter your password again. If you are, enter your password and continue. From there click the API keys tab, and it will display the API keys specific to your account.

Common Gotcha

Important:

Make sure to be extra careful not to share the API keys by accident with anyone. If you ever use this Stripe account to collect real payments in the future, which you may do, you will need to connect your bank account information to your Stripe account. That means keeping the Stripe API keys secure is very important. Because of this, make sure you don't include your Stripe API keys in any files that get pushed up to GitHub.

We are now going to include the Stripe API keys in the application.yml file that Figaro uses to pull in sensitive data in our application. Remember that this file will not be sent to GitHub.

To get started find the Test Secret Key in the Stripe API key dashboard, and copy the value inside the textbox into your clipboard. Then adjust config/application.yml and paste the value in, so the file looks like this (although, make sure the value you paste in your file is your own secret key, do not use the value sk_test_1111xxxxxxxx1111, because that will not work):

SECRET_KEY: 'sk_test_1111xxxxxxxx1111'

Follow the same pattern and set the Test Publishable Key in the application.yml file. In the Stripe API key dashboard, copy the value of the Test Publishable Key into your clipboard. Then adjust config/application.yml and paste the value in, so the file looks like this (and again, make sure the value you paste in your file is your own public key, do not use the value pk_test_1111xxxxxxxx1111, because that will not work):

SECRET_KEY: 'sk_test_1111xxxxxxxx1111'
PUBLISHABLE_KEY: 'pk_test_1111xxxxxxxx1111'

Save this file.

Next continue reading the documentation. It indicates that we should create a new initializer and gives us the code we should place in the file. Create a file in config/initializers/stripe.rb and copy and paste the code from the Stripe documentation:

Rails.configuration.stripe = {
  publishable_key: ENV['PUBLISHABLE_KEY'],
  secret_key: ENV['SECRET_KEY']
}

Stripe.api_key = Rails.configuration.stripe[:secret_key]

Save the file.

You might have noticed the code is slightly different in our example then the one in the Stripe documents. The code is functionally identical but we made a few small syntax adjustments to the code in the Stripe documents so it follows the pattern we've used elsewhere in the lessons.

Remember, whenever anything changes inside the config/initializers folder, we need to restart our server. Do that now.

We just configured our application with the API keys that will allow it to connect to the Stripe API server. Now that we have the Stripe gem installed and the ability to communicate with it established, we can begin adding the functionality into our web application!

Adding the Pay Button to the Course Detail Page View

Return to the Stripe documentation page and scroll down to the Views section where they describe how to add a pay button to a page.

The Stripe documentation instructs us to build a new app/views/layout file, called charges.html.erb. This would allow us to add a new layout instead of app/views/layouts/application.html.erb. If we followed this step, our web application would lose the top navigation, footer, etc., so skip this step.

Scroll down a little lower. The documentation shows us the code that we can add to our view file to add a payment button. Copy the code they show you. Edit app/views/courses/show.html.erb by pasting the code in your clipboard into this file.

<br />

<div class="booyah-box col-10 offset-1">
  <h1><%= @course.title %>h1>
  <%= image_tag @course.image, class: 'img-fluid' %>
  <br />
  <div class="row">
    <div class="col-sm-4 col-12">
      <span class="badge badge-default">
        <%= number_to_currency @course.cost %>
      span>

      <% if current_user && current_user == @course.user %>
        <br />
        <br />
        <%= link_to 'Administer', instructor_course_path(@course), class: 'btn btn-danger btn-large' %>
      <% end %>

      <br />
      <br />

      <% if current_user && current_user.enrolled_in?(@course) %>
        <h3 class="badge badge-info">You Are Enrolled!h3>
      <% else %>
        <%= link_to 'Enroll', course_enrollments_path(@course), class: 'btn btn-primary', method: :post %>
        <%= form_tag charges_path do %>
          <article>
            <% if flash[:error].present? %>
              <div id="error_explanation">
                <p><%= flash[:error] %>p>
              div>
            <% end %>
            <label class="amount">
              <span>Amount: $5.00span>
            label>
          article>