#146 PayPal Express Checkout
PayPal Express Checkout is easy to add to an existing ordering system. See how in this episode.
- Download:
- source codeProject Files in Zip (108 KB)
- mp4Full Size H.264 Video (28.9 MB)
- m4vSmaller H.264 Video (17.9 MB)
- webmFull Size VP8 Video (46.3 MB)
- ogvFull Size Theora Video (38.9 MB)
Resources
- Episode 144: Active Merchant Basics
- Episode 145: Integrating Active Merchant
- PayPal Express with ActiveMerchant Article
- PayPal's Express Checkout Guide PDF
- Full Episode Source Code
bash
script/generate migration add_express_token_to_orders express_token:string express_payer_id:string
rake db:migrate
script/generate migration add_express_token_to_orders express_token:string express_payer_id:string rake db:migrate
config/environments/development.rb
config.after_initialize do
ActiveMerchant::Billing::Base.mode = :test
paypal_options = {
:login => "seller_1229899173_biz_api1.railscasts.com",
:password => "FXWU58S7KXFC6HBE",
:signature => "AGjv6SW.mTiKxtkm6L9DcSUCUgePAUDQ3L-kTdszkPG8mRfjaRZDYtSu"
}
::STANDARD_GATEWAY = ActiveMerchant::Billing::PaypalGateway.new(paypal_options)
::EXPRESS_GATEWAY = ActiveMerchant::Billing::PaypalExpressGateway.new(paypal_options)
end
config.after_initialize do ActiveMerchant::Billing::Base.mode = :test paypal_options = { :login => "seller_1229899173_biz_api1.railscasts.com", :password => "FXWU58S7KXFC6HBE", :signature => "AGjv6SW.mTiKxtkm6L9DcSUCUgePAUDQ3L-kTdszkPG8mRfjaRZDYtSu" } ::STANDARD_GATEWAY = ActiveMerchant::Billing::PaypalGateway.new(paypal_options) ::EXPRESS_GATEWAY = ActiveMerchant::Billing::PaypalExpressGateway.new(paypal_options) end
config/environments/test.rb
config.after_initialize do
ActiveMerchant::Billing::Base.mode = :test
::STANDARD_GATEWAY = ActiveMerchant::Billing::BogusGateway.new
::EXPRESS_GATEWAY = ActiveMerchant::Billing::BogusGateway.new
end
config.after_initialize do ActiveMerchant::Billing::Base.mode = :test ::STANDARD_GATEWAY = ActiveMerchant::Billing::BogusGateway.new ::EXPRESS_GATEWAY = ActiveMerchant::Billing::BogusGateway.new end
config/environments/production.rb
config.after_initialize do
ActiveMerchant::Billing::Base.mode = :production
paypal_options = {
:login => "seller_1229899173_biz_api1.railscasts.com",
:password => "FXWU58S7KXFC6HBE",
:signature => "AGjv6SW.mTiKxtkm6L9DcSUCUgePAUDQ3L-kTdszkPG8mRfjaRZDYtSu"
}
::STANDARD_GATEWAY = ActiveMerchant::Billing::PaypalGateway.new(paypal_options)
::EXPRESS_GATEWAY = ActiveMerchant::Billing::PaypalExpressGateway.new(paypal_options)
end
config.after_initialize do ActiveMerchant::Billing::Base.mode = :production paypal_options = { :login => "seller_1229899173_biz_api1.railscasts.com", :password => "FXWU58S7KXFC6HBE", :signature => "AGjv6SW.mTiKxtkm6L9DcSUCUgePAUDQ3L-kTdszkPG8mRfjaRZDYtSu" } ::STANDARD_GATEWAY = ActiveMerchant::Billing::PaypalGateway.new(paypal_options) ::EXPRESS_GATEWAY = ActiveMerchant::Billing::PaypalExpressGateway.new(paypal_options) end
routes.rb
map.resources :orders, :new => { :express => :get }
map.resources :orders, :new => { :express => :get }
orders_controller.rb
def express
response = EXPRESS_GATEWAY.setup_purchase(current_cart.build_order.price_in_cents,
:ip => request.remote_ip,
:return_url => new_order_url,
:cancel_return_url => products_url
)
redirect_to EXPRESS_GATEWAY.redirect_url_for(response.token)
end
def new
@order = Order.new(:express_token => params[:token])
end
def express response = EXPRESS_GATEWAY.setup_purchase(current_cart.build_order.price_in_cents, :ip => request.remote_ip, :return_url => new_order_url, :cancel_return_url => products_url ) redirect_to EXPRESS_GATEWAY.redirect_url_for(response.token) end def new @order = Order.new(:express_token => params[:token]) end
models/order.rb
def purchase
response = process_purchase
transactions.create!(:action => "purchase", :amount => price_in_cents, :response => response)
cart.update_attribute(:purchased_at, Time.now) if response.success?
response.success?
end
def express_token=(token)
write_attribute(:express_token, token)
if new_record? && !token.blank?
details = EXPRESS_GATEWAY.details_for(token)
self.express_payer_id = details.payer_id
self.first_name = details.params["first_name"]
self.last_name = details.params["last_name"]
end
end
private
def process_purchase
if express_token.blank?
STANDARD_GATEWAY.purchase(price_in_cents, credit_card, standard_purchase_options)
else
EXPRESS_GATEWAY.purchase(price_in_cents, express_purchase_options)
end
end
def standard_purchase_options
{
:ip => ip_address,
:billing_address => {
:name => "Ryan Bates",
:address1 => "123 Main St.",
:city => "New York",
:state => "NY",
:country => "US",
:zip => "10001"
}
}
end
def express_purchase_options
{
:ip => ip_address,
:token => express_token,
:payer_id => express_payer_id
}
end
def validate_card
if express_token.blank? && !credit_card.valid?
credit_card.errors.full_messages.each do |message|
errors.add_to_base message
end
end
end
def purchase response = process_purchase transactions.create!(:action => "purchase", :amount => price_in_cents, :response => response) cart.update_attribute(:purchased_at, Time.now) if response.success? response.success? end def express_token=(token) write_attribute(:express_token, token) if new_record? && !token.blank? details = EXPRESS_GATEWAY.details_for(token) self.express_payer_id = details.payer_id self.first_name = details.params["first_name"] self.last_name = details.params["last_name"] end end private def process_purchase if express_token.blank? STANDARD_GATEWAY.purchase(price_in_cents, credit_card, standard_purchase_options) else EXPRESS_GATEWAY.purchase(price_in_cents, express_purchase_options) end end def standard_purchase_options { :ip => ip_address, :billing_address => { :name => "Ryan Bates", :address1 => "123 Main St.", :city => "New York", :state => "NY", :country => "US", :zip => "10001" } } end def express_purchase_options { :ip => ip_address, :token => express_token, :payer_id => express_payer_id } end def validate_card if express_token.blank? && !credit_card.valid? credit_card.errors.full_messages.each do |message| errors.add_to_base message end end end
carts/show.html.erb
<%= link_to image_tag("https://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif"), express_new_order_path %>
<%= link_to image_tag("https://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif"), express_new_order_path %>
orders/new.html.erb
<% form_for @order do |f| %>
<%= f.error_messages %>
<% if @order.express_token.blank? %>
...
<% else %>
<%= f.hidden_field :express_token %>
<p>Name: <%=h @order.first_name %> <%=h @order.last_name %></p>
<p>TODO Display order confirmation details</p>
<% end %>
<p><%= f.submit "Complete Order" %></p>
<% end %>
<% form_for @order do |f| %> <%= f.error_messages %> <% if @order.express_token.blank? %> ... <% else %> <%= f.hidden_field :express_token %> <p>Name: <%=h @order.first_name %> <%=h @order.last_name %></p> <p>TODO Display order confirmation details</p> <% end %> <p><%= f.submit "Complete Order" %></p> <% end %>

