Stripe?
Let’s check Stripe’s About page:
Stripe is a technology company that builds economic infrastructure for the internet. Businesses of every size-from new startups to public companies-use our software to accept payments and manage their businesses online.
Documentation
Main website:
API:
Demo:
Stripe Ruby
https://github.com/stripe/stripe-ruby
The Stripe Ruby library provides convenient access to the Stripe API from applications written in the Ruby language. It includes a pre-defined set of classes for API resources that initialize themselves dynamically from API responses which makes it compatible with a wide range of versions of the Stripe API.
The library also provides other features. For example:
-
Easy configuration path for fast setup and use.
-
Helpers for pagination.
-
Built-in mechanisms for the serialization of parameters according to the expectations of Stripe’s API.
Installation
Let’s start from Gemfile:
gem 'stripe'
Configuration
development.rb / production.rb
config.stripe.secret_key = Rails.application.credentials.stripe[:development][:secret_key]
config.stripe.publishable_key = Rails.application.credentials.stripe[:development][:publishable_key]
Implementation
Let’s modify our routes.rb file first:
get '/card/new' => 'charges#new', as: :add_payment
And add some logic to the StripeChargesService class:
class StripeChargesService
DEFAULT_CURRENCY = 'usd'.freeze
def initialize(params, user, order_id, plan_id)
@stripe_email = params[:stripeEmail]
@stripe_token = params[:stripeToken]
@order = order_id
@plan_id = plan_id
@user = user
end
def call
create_charge(find_customer)
end
private
attr_accessor :user, :stripe_email, :stripe_token, :order
def find_customer
if user.stripe_token
retrieve_customer(user.stripe_token)
else
create_customer
end
end
def retrieve_customer(stripe_token)
Stripe::Customer.retrieve(stripe_token)
end
def create_customer
customer = Stripe::Customer.create(
email: stripe_email,
source: stripe_token
)
# set stripe token
user.update(stripe_token: customer.id)
customer
end
def create_charge(customer)
Stripe::Charge.create(
customer: customer.id,
amount: order_amount,
description: @order,
currency: DEFAULT_CURRENCY
)
# update user's subscription
user.update(subscription_plan_end_date: Time.zone.now + SubscriptionPlan::LENGTH.days, subscription_plan_id: @plan_id)
end
def order_amount
# order amount in cents
Order.find_by(id: order).amount * 100
end
end
Charges controller implementation:
class ChargesController < ApplicationController
before_action :authenticate_user!
rescue_from Stripe::CardError, with: :catch_exception
before_action :set_subscription_plan
def new
@order = Order.create(user_id: current_user.id, price: @plan&.price, amount: @plan&.price)
session[:order] = @order.to_param
end
def create
result = ::StripeChargesService.new(charges_params, current_user, session[:order], @plan&.id).call
redirect_to cabinet_path, flash: { success: "Thanks for your order" }
end
private
def set_subscription_plan
@plan = SubscriptionPlan.default
end
def charges_params
params.permit(:stripeEmail, :stripeToken, :order_id)
end
def catch_exception(exception)
flash[:error] = exception.message
end
end
View for our route: charges/new.html.erb:
<section class="section section--hero contact" id="contact">
<h1 class='text-center'>Plan purchase page</h1>
<div class="container center">
<%= 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: $<%= @order.price %></span>
</label>
</article>
<script src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="<%= Rails.configuration.stripe[:publishable_key] %>"
data-description="A month's subscription"
data-amount="<%= @order.price * 100 %>"
data-locale="auto"></script>
<% end %>
</div>
</section>
Testing
Navigate to the /card/new page in your app:

Make payment with test card:

Conclusion
That’s it - super simple, just a few files, configuration changes and your payments are ready to go!