-
Notifications
You must be signed in to change notification settings - Fork 4
Samurai Rails Demo Instructions
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.
rails s
Open: http://127.0.0.1:3000
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
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
...
gem 'samurai'
Then, run bundler:
bundle install
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'
}
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 %>
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 %>
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
Restart the server and hit http://127.0.0.1:3000
rails s
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) %>
Restart the server and hit http://127.0.0.1:3000
rails s