2 Comments

Integrating Paypal Express with Rails 3.1 – Part 3

This is the last part of a three-part series. As mentioned in the previous post, the next step is to define the PaypalExpress#purchase action so that we would get the paypal_express_purchase_path.

Modifying routes.rb

We first need to add this line to the routes.rb file so that Rails router would work properly:

   get "paypal_express/purchase"

Next, here’s the implementation of PaypalExpress#purchase action:

class PaypalExpressController < ApplicationController
  # ... everything else was covered in the previous blog

  def purchase
    if params[:token].nil? or params[:payer_id].nil?
      redirect_to home_url, :notice => "Sorry! Something went wrong with the Paypal purchase. Please try again later." 
      return
    end

    total_as_cents, purchase_params = get_purchase_params @cart, request, params
    purchase = @gateway.purchase total_as_cents, purchase_params

    if purchase.success?
      # you might want to destroy your cart here if you have a shopping cart 
      notice = "Thanks! Your purchase is now complete!"
    else
      notice = "Woops. Something went wrong while we were trying to complete the purchase with Paypal. Btw, here's what Paypal said: #{purchase.message}"
    end

    redirect_to home_url, :notice => notice
  end
end

and the corresponding PaypalExpressHelper methods to go with it:

module PaypalExpressHelper
  # ... other methods were implemented in the previous blog posts

  def get_totals(cart)
    # implemented in the previous blog posts
  end

  def to_cents(total)
    # implemented in the previous blog posts
  end 

  def get_items(cart)
    # implemented in the previous blog posts
  end

  def get_purchase_params(cart, request, params)
    subtotal, shipping, total = get_totals(cart)
    return to_cents(total), {
      :ip => request.remote_ip,
      :token => params[:token],
      :payer_id => params[:payer_id],
      :subtotal => to_cents(subtotal),
      :shipping => to_cents(shipping),
      :handling => 0,
      :tax =>      0,
      :items =>    get_items(cart),
    }
  end
end

So, with this action defined, paypal_express_purchase_path should now be defined.

Now, let’s cover what this action does:

  • When the customer gets redirected from the Paypal website back to our site, Paypal will send us two paramters: token and payer_id. The first thing we do, then, is to validate that these two values are supplied as part of the request parameters. If the parameters don’t exist, we redirect to the home page.
  • Next, we extract the parameters that ActiveMerchant’s PaypalExpressGateway#purchase requires. The two parameters that the purchase method requires are:
    • Total for the order (in cents)
    • Purchase parameters (see: PaypalExpressHelper#get_purchase_params method to see the parameters)
  • The next step is the crux of the purchase action. We call PaypalExpressGateway#purchase and pass it the parameters from the previous step.
  • We then save the the return value of the purchase method as purchase. The purchase object has a success? method which would tell you whether the operation was successful or not. If not, you can extract the error message via the message method.
  • Finally, for my own app, I redirect to my home page. Of course, you are free to do whatever you want. I would suggest showing some form of notification or redirecting to a “post-purchase” page.

This concludes a simple tutorial on integrating Paypal Express with Rails using ActiveMerchant. I hope that it has been helpful! If you run into any problems with ActiveMerchant, I recommend ActiveMerchant Google Group.