LaunchSchool - An Online School for Developers /

Blog

Stripe Payments in Rails, Part 1 - Stripe Checkout

Stripe is a popular payment processing service that makes online payments easy. In this tutorial series, we’ll guide you through how to use Stripe to process payments in Rails apps.

This is the first article in the “Process Payments with Stripe in Rails” tutorial series:

As an example we will have an imaginary “Cookery School” application to sell online cooking courses. For this tutorial, we will work on the checkout branch, to use Stripe Checkout to process payments:

1
2
3
4
5
6
7
8
git clone -b checkout git@github.com:gotealeaf/stripe-basics.git
cd stripe-basics
rake db:drop
rake db:create
rake db:migrate
rake db:seed
rails s
open http://localhost:3000

Step 1. Create Stripe Account

This step is really easy, but very important. You just need an email account to sign up for Stripe.

Step 2. Configure project

Add Stripe gem to your Gemfile and run bundle install:

1
gem 'stripe'

Create config/initializers/stripe.rb:

1
2
3
4
5
6
Rails.configuration.stripe = {
    :publishable_key => Rails.application.secrets.stripe_publishable_key,
    :secret_key      => Rails.application.secrets.stripe_secret_key
}

Stripe.api_key = Rails.application.secrets.stripe_secret_key

You can find these keys at your Stripe console: Your account > Account Settings > API keys:

We will use testing keys for the development environment. For production environment you need to configure with live keys to receive real payments.

Add these keys at config/secrets.yml:

1
2
3
development:
  stripe_publishable_key: pk_test_xxxxxxxxxxxxxxxxxxxxxxxx
  stripe_secret_key: sk_test_xxxxxxxxxxxxxxxxxxxxxxxx

For the development and test environments you can directly put your test keys in the secrets.yml file. For the production environment you will not want to have those keys in your code. You want to use environment variables instead:

1
2
3
production:
  stripe_publishable_key: ENV['stripe_publishable_key']
  stripe_secret_key: ENV['stripe_publishable_key']

If you want to use more comprehensive solutions to manage your environment environments, check out our tutorial on How to manage configueration variables in Rails.

Step 3. Create Registration form with Stripe Checkout

We will create our registration form app/views/registrations/new.html.haml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    = form_for @registration, html: { class: "basic-grey" } do |f|
      - if @registration.errors.any?
        #error_explanation
          %h2
            = pluralize(@registration.errors.count, "error")
            prohibited this registration from being saved:
          %ul
            - @registration.errors.full_messages.each do |message|
              %li= message
      .field
        = f.hidden_field :course_id, value: @course.id
      .field
        = f.label :full_name
        = f.text_field :full_name
      .field
        = f.label :company
        = f.text_field :company
      .field
        = f.label :telephone
        = f.text_field :telephone
      .actions
        %script.stripe-button{ src: "https://checkout.stripe.com/checkout.js",
              data: {amount: @course.price*100, description: @course.name, key: Rails.application.secrets.stripe_publishable_key}}

We are configuring the very basic ‘stripe-button’, but you can parameterize much more of it with the Checkout data options.

The checkout.js script creates a Submit button and a popup window to allow inputs for the customer payment data. When user submits this the form in this window, checkout.js sends the info to Stripe, which validates the card and sends a token back if the card number is valid. Before submitting the form to our controller, checkout.js inserts two hidden inputs in the form (stripeEmail and stripeToken). The stripeToken value represents a credit card number stored on Stripe’s server, and we can use that to charge a card card.

The reason for this 2-step process is such that the customer’s credit card information will never flow through our server – in other words, Stripe is taking over the PCI Compliance burden away from our app.

Step 4. Processing payments and creating registration

In our controller we will build our registration and process payments:

app/controller/registration_controller.rb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  def create
    @registration = Registration.new registration_params.merge(email: stripe_params["stripeEmail"],
                                                               card_token: stripe_params["stripeToken"])
    raise "Please, check registration errors" unless @registration.valid?
    @registration.process_payment
    @registration.save
    redirect_to @registration, notice: 'Registration was successfully created.'
  rescue e
    flash[:error] = e.message
    render :new
  end

  private
    def stripe_params
      params.permit :stripeEmail, :stripeToken
    end

Here we are handling a possible error with the user’s registration and payment data. If any error raises in the process, it will be thrown back again to client as an error, and the payment/registration will not be created.

We need to add the process_payment method in our model:

app/models/registration.rb:

1
2
3
4
5
6
7
8
9
10
  def process_payment
    customer = Stripe::Customer.create email: email,
                                       card: card_token

    Stripe::Charge.create customer: customer.id,
                          amount: course.price * 100,
                          description: course.name,
                          currency: 'usd'

  end

Note here we are passing course.price * 100 as the amount to Stripe, because Stripe expects the amount to be in cents, not dollars.

We also need to create the card_token column in the registrations table.

1
2
rails g migration add_stripe_card_token_to_registration card_token:string
rake db:migrate

Test the features

At this point we will test our code. First select a course in our application and fill the registration form:

You can use the test card number: 4242 4242 4242 4242, with any 3-digit CVV.

If the process finished successfully you will see the registration confirmation:

You can find the payment in your Stripe console:

You can also use the special card number 4000 0000 0000 0002 to trigger a “Card Declined” transaction to see how the app handles it. The Stripe documentation on testing gives you more valid and invalid test cards to check more specific use cases.

Conclusion

This is the easiest way with Stripe to pay with credit cards, and you don’t have to do much work. In the next tutorial of this series, Stripe Payments in Rails – Use Custom Forms with Stripe.js we’ll cover how to use Stripe to process payments with your own forms so you can control the look and feel.