Tuesday, 23 July 2013

Paypal activemerchent Integration - ROR

PayPal Express Payments with ActiveMerchant


There is a lot of confusion over the myriad of services that PayPal offers for accepting PayPal payments. In reality there are two ways of accepting PayPal payments.

PayPal Website Payments Standard

Website Payments Standard is the basic service PayPal offers for accepting PayPal payments. Website Payments Standard requires the creation of an HTML form that is posted to PayPal. The user is redirected to the PayPal website where they complete their payment. They are then redirected back to the seller's website at the end of the process where it is possible to display an order confirmation, or other information. Very basic, easy to setup, but also quite limited.

PayPal Express

PayPal Express is a much more powerful alternative to PayPal Website Payments Standard. The downside is that it is slightly more complicated. However, I am going to show how easy it is to get PayPal Express working with ActiveMerchant. PayPal Express has several benefits including support for Authorization and Capture. Website Payments Standard also has support for Authorization and Capture, but the seller has to actually login to their PayPal account to capture the funds. PayPal Express also keeps control of the payment flow on your page, instead of PayPal's. The user is only redirected to PayPal briefly to confirm payment, and then they are sent back to the seller's page to complete the payment. There are several advantages to this, but I think the biggest is that you can rely on PayPal to provide address information for the buyer and then determine additional shipping or other charges to add to the total of the order.
Now that I've provided a bit of background on PayPal Express I'm going to show how simple it is to integrate into Rails application. The code is based on the integration of PayPal Express into Shopify. The applicable integration points from the PayPal Express Checkout Integration Guide will be noted throughout the example. If you like you can download the completed Sprockets application sprockets.tar.gz. You will need at least Rails 2.0.2 Gems to run the Sprockets application. You will only need to add your API credentials into the application, which is described in the example text.
First, in order to use the sandbox, you'll need a PayPal Sandbox buyer and seller to work with. See Sandbox Testing for more information on getting these accounts setup. The seller account must be either a Premier Account or Business Account in order to work with PayPal Express. Don't forget to activate the account using the Test Email link in Developer Central. Email isn't really sent in the sandbox. It just accumulates in the Developer Central inbox. Then you'll have to confirm your bank account using the Get Verified link while logged in as the test user.

Build

Add to Gemfile:

gem  ‘activemerchant’

$ bundle install

The first thing to do is to configure ActiveMerchant. By default ActiveMerchant uses the production environment of a payment gateway, so we have to force ActiveMerchant into test mode while we're running in the Rails development environment. This is easily accomplished by opening up config/environments/development.rb and adding the following code to the bottom of the file:

config.after_initialize do
ActiveMerchant::Billing::Base.mode = :test
 ActiveMerchant::Billing::PaypalExpressGateway.default_currency = 'USD'
 paypal_options = {
    :login => 'API Login',
   :password => 'API Password’,
   :signature => 'API Signature',
   :PAYMENTREQUEST_0_CURRENCYCODE => "YOUR CURRENCY"
 }
 ::STANDARD_GATEWAY = ActiveMerchant::Billing::PaypalGateway.new(paypal_options)
 ::EXPRESS_GATEWAY = ActiveMerchant::Billing::PaypalExpressGateway.new(paypal_options)
end



The preceding code ensures that the PayPal Sandbox will be used for the test payments, and waits until the entire application is loaded before doing the configuration.
The next thing to do is to login to the PayPal Sandbox and launch the sandbox for the seller account you previously created. Click the My Account link followed by the Profile _ link. Then click _API Access underneath Account Information. Select Request API signature and then click Agree and Submit. Record the API username, API Password, and Signature. We'll be using them shortly.
Now that all of the configuration has been completed we can move onto actually accepting payments. Let's generate a controller PaymentsController that will be used to accept the payments from PayPal.
$ rails g controller payments index confirm complete
We created the controller with the action index, confirm, complete actions in the controller along with their associated views. Let's open up the index.html.erbtemplate and add the PayPal Express logo that the customer will click to make payment.The first thing we need to do is include the ActiveMerchant::Billing namespace into the controller so that we can access the classes from ActiveMerchant with less typing:

class PaymentsController < ApplicationController
 include
ActiveMerchant::Billing
end

I'm assuming that you have created a common layout, such as application.html.erb to provide the required HTML structure for the page. The index action represents Integration Point 1a from the Integration Guide. index.html.erb looks as follows:

<h1>Purchase Sprockets</h1>
<p>Thank you for your decision to purchase our sprockets.</
p>
<p>
Your order total is $50.00</p>
<p>
 <%= link_to image_tag('https:/
/www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif'), :action => 'checkout' %>
</p>
Clicking the PayPal Express button do a GET request on the checkout action. The checkout action is where we setup the purchase with PayPal and get the token identifying the purchase from PayPal. We didn't generate the checkout action initially because it doesn't require a view. The checkout action representsIntegration Point 1b from the Integration Guide. Define the checkout action as follows:

def checkout
 setup_response = gateway.setup_purchase(
5000,
   :ip                => request.remote_ip,
   :return_url        => url_for(:action =>
'confirm', :only_path => false),
   :cancel_return_url => url_for(:action =>
'index', :only_path => false)
 )
 redirect_to gateway.redirect_url_for(setup_response.token)
end
gateway is actually a method which constructs the PaypalExpressGateway if it hasn't been already:

privatedef gateway
 @gateway ||=
PaypalExpressGateway.new(
   :login =>
'API Login',
   :password =>
'API Password',
   :signature =>
'API Signature'
 )
end

As you can see, we're constructing the gateway using the credentials provided to us earlier in the PayPal Sandbox and returning the new instance of the gateway.
The setup_purchase() method informs PayPal of the details of the purchase we're going to make and returns a token. 5000 is the amount in cents of the purchase, which is $50.00. ActiveMerchant only accepts amounts in cents. The customer's IP address, passed in using the :ip option, is a required option, and helps PayPal reduce fraud. The :return_url option is the absolute URL that the customer will be redirected to after their purchase, and:cancel_return_url is the URL the customer will return to if they cancel the purchase.
Finally, we redirect the customer to PayPal. The URL is constructed by passing the token returned in the setup_purchase() call to the redirect_url_for()method provided by the gateway.
Now if you load http://localhost:3000/payments in your browser and click the PayPal Express button you should be redirected to PayPal. You will need to be logged into the PayPal Developer Central at the time you click the button in order for the sandbox to load correctly. You can now log in to PayPal using the Sandbox buyer account that you created earlier. Once logged in you will see the details of the purchase. You'll also see the link to cancel the transaction below the Continue button. The time spent on PayPal's site represents Integration Point 2a and Integration Point 2b from the Integration Guide. Clicking theContinue button will redirect your browser back to the Sprockets application confirm action. The redirection back to our application represents Integration Point 2c from the Integration guide. We already have a confirm action, but it just displays the default message put in the template by the Rails generator.
Let's enhance the confirm action as follows:
def confirm
 redirect_to :action =>
'index' unless params[:token]
 details_response = gateway.details_for(params[:token])
 
if !details_response.success?
   @message = details_response.message
   render :action =>
'error'
   
return
 
end
 @address = details_response.address
end

First, we request the details of the purchase from PayPal using the details_for() method, which takes the token param as its first argument. If we successful get the details for the purchase then we display the confirm.html.erb template. Otherwise, we render the the error.html.erb template. error.html.erb looks as follows:
<h1>Error</h1>
<p>Unfortunately an error occurred: <%= @message %></
p>
The confirm.html.erb templates displays the customer's PayPal address and asks them if they want to complete the payment. Displaying the review page represents Integration Point 3a from the Integration guide. This is the customer's opportunity to review the details of their order, change shipping methods, etc. It looks like this:
<h1>Please Confirm Your Payment Details</h1>

<table>
 <tr><td>Name</
td><td><%= @address['name'] %></td></tr>
 <tr><td>Company</
td><td><%= @address['company'] %></td></tr>
 <tr><td>Address 1</
td><td><%= @address['address1'] %></td></tr>
 <tr><td>Address 2</
td><td><%= @address['address2'] %></td></tr>
 <tr><td>City</
td><td><%= @address['city'] %></td></tr>
 <tr><td>State</
td><td><%= @address['state'] %></td></tr>
 <tr><td>Country</
td><td><%= @address['country'] %></td></tr>
 <tr><td>Zip</
td><td><%= @address['zip'] %></td></tr>
</
table>

<% form_tag :action =>
'complete', :token => params[:token], :payer_id => params[:PayerID] do %>
 <%= submit_tag 'Complete Payment' %>

<%
end %>



When the customer clicks the Complete Payment button they will post their token, and PayerID, which were returned from PayPal, back to the complete action where we'll inform PayPal to complete the purchase. Completing the purchase represents Integration Point 3b from the Integration Guide. It looks as follows:

def complete
 purchase = gateway.purchase(
5000,
   :ip       => request.remote_ip,
   :payer_id => params[:payer_id],
   :token    => params[:token]
 )
 
if !purchase.success?
   @message = purchase.message
   render :action =>
'error'
   
return
 
end
end

This looks similar to when we initially setup the purchase, but we're calling purchase() instead of setup_purchase(). If the purchase is successful then we render the complete.html.erb template. Displaying the final success message represents Integration Point 4 from the Integration Guide, which is the final step. It looks like:

<p>Thank you for your purchase</p>

The entire flow of the purchase is very flexible. The initial amount of the setup_purchase() method doesn't even need to match the final amount sent in purchase(). This allows for the buyer to change their mind about their order details during the checkout flow in your site. This is useful for situations where the customer may want to add high priority shipping, a discount code, or gift wrapping while reviewing their order. There is a lot of data that can be provided to PayPal throughout the integration.

No comments: