Skip to content
This repository was archived by the owner on Mar 10, 2023. It is now read-only.

Samurai Rails Demo Instructions

jkrall edited this page Aug 29, 2011 · 14 revisions

Get started with a basic blog-style app...

Prerequisites

git clone https://github.com/FeeFighters/samurai-rails-demo.git
cd samurai-rails-demo

gem install bundler
bundle install
rake db:setup

This is a basic blog rails app, borrowed from an excellent Ryan Bates's Railscasts episode, and modified to make it appropriate for demoing Samurai.

The app is structured to require a user to pay for an article before being able to read it. It accomplishes this through a simple Order join model, and a new OrdersController that has a dummy method representing the start of the Samurai payments process. These instructions will take you step-by-step through adding Samurai to this app so that you can charge a visitor's credit card to accept payment for a given article.

Start up server, test out "before" app

rails s
  1. Open: http://127.0.0.1:3000
  2. Click on an article
  3. You should see the sample OrdersController#samurai view

Prepare for adding Samurai payment processing...

Stub out OrdersController before Samurai integration

class OrdersController < ApplicationController
  # Create/Update a payment method via Samurai Transparent Redirect
  def new_payment_method
  end

  # Show the payment confirmation page
  def payment_confirmation
  end

  # Create the new order, and redirect to the article
  def create
  end
end

Rearrange the routes so that orders are nested under articles:

resources :articles do
  resources :orders, :only=>[:create] do
    collection do
      get 'new_payment_method'
      get 'payment_confirmation'
    end
  end
end    

Change the path that the OrdersController redirects to if user hasn't purchased yet

Modify articles_controller.rb:

def show
  @article = current_user.articles.find_by_id params[:id]
  if @article.nil?
    @article = Article.find params[:id]
    redirect_to payment_confirmation_article_orders_path(@article), 
                :alert=>'You must purchase this article in order to view it' and return
  end    
...

Time to add Samurai!

Add Samurai to your Gemfile:

gem 'samurai'

Then, run bundler:

bundle install

Add Samurai initializer

Add the following (with these demo credentials or your own) to a samurai initializer (ex - config/initializers/init-samurai.rb):

require 'samurai'
Samurai.options = {
  :site => 'https://samurai.feefighters.com/v1/',
  :merchant_key => '197199ef0872afd92c39ceb0',
  :merchant_password => '663b6c16fe50179d7f771c5d',
  :processor_token => '6e340c55559335bf73c8de29'
}

Hook up Samurai

PaymentMethod form

Modify orders_controller.rb:

include Samurai::Rails::Helpers

before_filter do
  @article = Article.find(params[:article_id])
end

Setup PaymentMethod form for transparent redirect:

def new_payment_method
  setup_for_transparent_redirect(params)
end

Modify new_payment_method.html.erb:

<h1>Purchase article: <%= @article.name %></h1>
<%= render Samurai::Rails::Views.errors %>
<%= render Samurai::Rails::Views.payment_method_form :redirect_url => payment_confirmation_article_orders_url(@article),
                                                     :sandbox => true %>

<%= link_to 'Back to the Articles', articles_path %>  

Transaction confirmation form

Setup purchase confirmation in orders_controller.rb:

def purchase_confirmation
  load_and_verify_payment_method(params)
  redirect_to new_payment_method_article_orders_path(@article, payment_method_params) and return unless @payment_method
end

Modify purchase_confirmation.html.erb:

<h1>Confirm Your Purchase</h1>
<h2><%= @article.name %></h2>

<p>
  <strong>Amount:</strong>
  <%= number_to_currency @article.amount %>
</p>
<p>
  <strong>Credit Card:</strong>
  <em>XXXX XXXX XXXX</em> <%= @payment_method.last_four_digits %>
  (<%= "%02d" % @payment_method.expiry_month %> / <%= "%04d" % @payment_method.expiry_year %>)
</p>

<%= link_to 'Submit This Purchase', article_orders_path(@article, :payment_method_token=>@payment_method.token), :method=>:post %>

Transaction #create action

Create the transaction! orders_controller.rb:

def create
  load_and_verify_payment_method(params)
  @order = current_user.orders.create :article=>@article

  @transaction = Samurai::Processor.the_processor.purchase(
    @payment_method.token,
    @article.amount,
    {:descriptor => @article.name, :customer_reference => current_user.id, :billing_reference => @order.id}
  )

  if @transaction.failed?
    @order.destroy
    redirect_to new_payment_method_article_orders_path(@article, payment_method_params) and return
  end

  redirect_to article_path(@article), :notice=>'Thanks for purchase this article!'
end

Test it out!

Restart the server and hit http://127.0.0.1:3000

rails s

Store the PaymentMethod with the User

Generate a new migration:

rails g migration add_payment_method_token_to_users payment_method_token:string

Run the migration:

rake db:migrate

Modify the OrdersController#payment_method action to pre-load a PaymentMethod:

def new_payment_method
  params[:payment_method_token] ||= current_user.payment_method_token
  setup_for_transparent_redirect(params)
end

Store the PaymentMethod on the user after the transparent redirect:

def purchase_confirmation
  ...
  current_user.update_attributes :payment_method_token=>@payment_method.token
end

Redirect directly to the transaction confirmation, if the user already has a card. Modify articles_controller.rb:

def show
  @article = current_user.articles.find_by_id params[:id]
  if @article.nil?
    @article = Article.find params[:id]
    redirect_to payment_confirmation_article_orders_path(@article, :payment_method_token=>current_user.payment_method_token),
                :alert=>'You must purchase this article in order to view it' and return if current_user.payment_method_token
    redirect_to new_payment_method_article_orders_path(@article),
                :alert=>'You must purchase this article in order to view it' and return
  end
  ...
end

Add link on transaction confirmation (views/orders/purchase_confirmation.html.erb) to change the credit card:

<%= link_to 'Use a different credit card', new_payment_method_article_orders_path(@article) %>

Test it out!

Restart the server and hit http://127.0.0.1:3000

rails s

Samurai is now successfully processing transactions for your app!