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 24, 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 epidode, 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

Open: http://127.0.0.1:3000

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 payment_method
  end

  # Transparent Redirect callback, setup new transaction with the PaymentMethod
  def transaction
  end

  # Create the transaction & handle the result
  def create
  end
end

Rearrange the routes so that orders are nested under articles:

resources :articles do
  get 'payment_method' => "orders#payment_method"
  get 'transaction' => "orders#transaction"
  resources :orders, :only=>[:create]
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 article_payment_method_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 payment_method
  setup_for_transparent_redirect(params)
end

Modify payment_method.html.erb:

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

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

Transaction form

Setup transaction confirmation in orders_controller.rb:

def transaction
  load_and_verify_payment_method(params)
  redirect_to article_payment_method_path(@article, payment_method_params) and return unless @payment_method
end

Modify transaction.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 article_payment_method_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 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 transaction
  ...
  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 article_transaction_path(@article, :payment_method_token=>current_user.payment_method_token) and return if current_user.payment_method_token
    redirect_to article_payment_method_path(@article) and return
  end
  ...
end

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

<%= link_to 'Use a different credit card', article_payment_method_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!

Clone this wiki locally