Ever wanted to add this button to your site?
I spent a few weeks figuring out how to make the Paypal checkout button work properly on my site. There were a lot of resources on the web, but none of them were complete. After a lot of trial and error, here is the step-by-step guide that should provide everything you need.
Adding the Paypal Button to Your Site
The first step is the simplest one: add the button to your site!
Find the page on your site where you want to add the button, and paste the following code to add a clickable Paypal checkout button. Please note that I use Haml for my project.
You will notice that I have a controller called ‘PaypalExpress’ with a custom action called ‘checkout’. We don’t have such controller yet, but at least you have a button on your site now.
Modifying Rails routes.rb
Try using Firebug to inspect the Paypal checkout button. You will notice that the href is ‘paypal_express/checkout’. So, to make the link work properly when we click on it, we need to add the following line to routes.rb:
Of course, clicking on it will make Rails complain that such controller doesn’t exist. So now it’s time to create the controller.
Creating PaypalExpressController
Here’s what my PaypalExpressController looks like:
There are quite a few ivars/classes/modules/methods used in the controller, namely:
- ActiveMerchant::Billing and PaypalExpressGateway
- PaypalLogin
- PaypalExpressHelper and get_setup_purchase_params method
- @cart
A lot of code right? No worries. I will go over the details you need to know. Before we dive into the details of what the controller does, let’s take care of all the dependencies I just mentioned.
ActiveMerchant Gem
The first part of the controller I want you to pay attention to is ActiveMerchant::Billing and PaypalExpressGateway class. These two come from ActiveMerchant. It provides a nice wrapper around Paypal APIs so that you don’t have to go through this kind of setup.
To install the gem, just put this into your Gemfile.
gem 'activemerchant'
Once you have it installed, please don’t forget to configure ActiveMerchant so that it will be in test mode for your development environment.
Optionally, you could put the same code in your config/environments/test.rb.
As you can see, Paypal requires the following credentials for it to properly work:
- login
- password
- signature
Here’s an example of Paypal credentials taken from Railscasts.com:
To obtain these credentials, for development and testing, sign up for a sandbox account here. I found following the direction given by Ryan Bates’s Railscasts to be really helpful, though it’s a little outdated.
For production, you will need to sign up for Paypal Express Checkout, Website Payment Standard or Website Payment Pro. Discussing the differences between each one is beyond the scope of this guide and should be researched to use the best one for your application.
PaypalExpressHelper
PaypalExpressHelper is a helper class I created on my own. Here’s what my PaypalExpressHelper looks like:
This class provides all the information that ActiveMerchant needs to talk to Paypal.
A few of things I want to point out regarding the code above:
- ‘review’ is another action of PaypalExpressController. We will cover it in the next blog post.
- ‘home_url’ is my application’s home page URL. So for your application, you will need to come up with your own.
@cart
@cart is an ActiveRecord model in my application and it :has_many :products and :has_many :line_items. You can study how it’s used in PaypalExpressHelper.
Now we are ready to understand what the controller does.
PaypalExpressController#checkout
So, here’s what happens when the Paypal checkout button is clicked.
- PaypalExpressController#checkout action is called because that is how our routes.rb is setup.
- But since our PaypalExpressController has a before_filter, PaypalExpressController#assigns_gateway will get called first.
- Using credentials provided by PaypalLogin class, it creates a ActiveMerchant::Billing::PaypalExpressGateway object.
- Based on Rails request and data stored in the shopping cart, it calls PaypalExpressHelper.get_setup_purchase_params() to get parameters that ActiveMerchant needs.
- Calls ActiveMerchant::Billing::PaypalExpressGateway.setup_purchase and passes the parameters. The parameters include:
- First parameter is an integer: The total amount you plan to charge your customer in cents, NOT dollars.
- Second parameter is a hash (see PaypalExpressHelper.get_setup_purchase_params) which includes:
- Your customer’s IP address
- Return URL: The page (URL) you want your customer to see when your customer returns from Paypal site.
- Cancel URL: The page (URL) you want your customer to see in case your customer clicks cancel on Paypal site.
- Subtotal, shipping, handling, tax… all in cents
- Allow note (set to true) will allow your customer to add notes as part of the transaction. It’s a small, bearly visible <textarea> on the Paypal checkout page
- List of items that your customers wanted to purchase. See PaypalExpressHelper.get_items method to see what the array of hashes looks like.
- Finally, based on the response from Paypal, redirect to Paypal website.
thanks for this, when’s the next one available?
Hi Dave,
Thanks for your comments. The next one should be up in a couple of weeks. =)
Excelent, good work.
[…] Picking up from my last post, we will now look at the next PaypalExpressController action: review. Here’s the […]
what if you add taxes?
i am getting paypal error “The totals of the cart item amounts do not match order amounts.” because i have to substract the tax amount from every item’s amount which leads to rounding issues because of the overall total ending up one cent above or below the tax-less total…
any suggestions, anyone?
I was playing with paypal express gem the last month, and didnt works for me, but this tutorial helps me a lot, I think will be very helpfull. Thanks, and waiting for Part 2.
hi, i have followed tutorial, thanks for making it clear, but as a newbie to rails ive made a mistake somewhere and was wondering if you could help me.. i think ive covered everything you have stated bit i get this error after i click the paypal link
NameError in PaypalExpressController#checkout
uninitialized constant PaypalExpressController::PaypalLogin
I am unsure to what this means
Hey did you ever get a fix for this?
Make sure you have a paypal_express model:
class PaypalLogin < Settingslogic
source "#{Rails.root}/config/paypal_login.yml"
namespace Rails.env
end
Attractive component to content. I just stumbled upon your site and in accession capital to assert that I acquire in fact loved account your blog posts. Any way I’ll be subscribing for your feeds and even I achievement you access constantly quickly.
[…] https://spin.atomicobject.com/2011/10/24/integrating-paypal-express-with-rails-3-1-part-1/ […]
What is not covered is @cart variable in PaypalExpressController#checkout method