Login With PayPal Using PayPal Authentication Service
PayPal is trusted by over 90 million users world wide. All of us know having “Pay with PayPal” helps building trust in the consumer’s mind. They are rest assured that you are a legitimate and a PayPal verified merchant. Now how about earning more trust from your visitors by providing them a “Login With PayPal” functionality? It might sound a difficult and involving task but fortunately PayPal has made it very simple by providing access to their Authentication Service.
Both our products, ellipsis dive! and ellipsis AdNet use this functionality. Check them out by simply clicking here:
ellipsis dive! - http://apps.ellipsissolutions.com/dive
ellipsis AdNet – http://apps.ellipsissolutions.com/adnet
Here are the steps to implement this in your website. I have provided the sample code in Java Servlet. But you should be able to do this in pretty much any programming language.
Step 1: Create your App on x.com
http://x.com is PayPal’s Developer Network Site. Simply log in using your current PayPal account and click on “My Apps” link and create an App. Select Identity Services and provide your Realm URL. It would be something like http://<your website>/*. It will take a few days before PayPal verifies everything and approves your App.
Step 2: Write the Servlet
The Servlet below should be invoked when the visitor clicks on the “Login With PayPal” link/button on your website. Unlike the standard PayPal buttons that PayPal provides, there’s nothing available for the Login Functionality. So feel free to come up with your own!
The Servlet does the following things:
A. Gets an Authentication Token
B. Redirect the user to PayPal’s login page using that Authentication Token
C. Provides PayPal a Return URL. This is the URL that PayPal hits on successful login
D. If the response in the Return URL is a success, then use the Authentication API to pull basic information about the logged in user (such as name, email, etc.)
—–
Keep in mind that PayPal Authentication Service based Login is not a way to implement “Single Sign On”. It merely “authenticates” the user and let’s you know that the person is a legitimate PayPal user. “True Single Sign On” functionality can be built using technologies such as “Open Id” or “OAuth”.
—–
Step 3: Deploy the Servlet
I am skipping this part and assuming that you are a seasoned web developer and know what you are doing. However if you have any questions, please do not hesitate to ask! There’s always a “first time” and no question is dumb!
package <your package>; import <all the relevant imports - your IDE will tell you so am stripping them from here to save space>; // I am using Apache HTTP Client to make HTTP GET/POST calls public class LoginWithPayPal extends HttpServlet { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { if (req.getParameter("auth-resp") == null) { HttpClient client = new HttpClient(); GetMethod method = new GetMethod( "https://api-3t.paypal.com/nvp?" + "USER=<your API user name>" + "&PWD=<your API password>" + "&SIGNATURE=<your API signature>" + "&VERSION=65%2e1" + "&RETURNURL=http://<your website>/" + "loginwithpaypal.servlet?" + "auth-resp=success" + "&CANCELURL=http://<your website>/" + "loginwithpaypal.servlet?" + "auth-resp=cancel" + "&LOGOUTURL=http://<your website>/" + "loginwithpaypal.servlet?" + "auth-resp=logout" + "&SERVICENAME1=Name" + "&SERVICEDEFREQ1=Required" + "&SERVICENAME2=Email" + "&SERVICEDEFREQ2=Required" + "&INITFLOWTYPE=Signup" + "&HDRIMG=<path to your logo (optional)>" + "&METHOD=SetAuthFlowParam"); client.executeMethod(method); Hashtable<String, String> respBodyParams = getParamsFromBody( method.getResponseBodyAsString()); String token = respBodyParams.get("TOKEN"); String ack = respBodyParams.get("ACK"); if (token != null && ack != null && ack.equals("Success")) { req.getSession().setAttribute( "paypal-token", token); resp.sendRedirect( "https://www.paypal.com/" + "cgi-bin/webscr?cmd=" + "_account-authenticate-login&token=" + URLDecoder.decode(token)); return; } else { req.getSession().setAttribute( "paypal-token", null); // Redirect the user back to your home page // and display a login failure message. return; } } else if (req.getParameter("auth-resp"). equals("success")) { if (req.getSession(). getAttribute("paypal-token") != null) { HttpClient client = new HttpClient(); GetMethod method = new GetMethod( "https://api-3t.paypal.com/nvp?" + "USER=<your API user name>" + "&PWD=<your API password>" + "&SIGNATURE=<your API signature>" + "&VERSION=65%2e1" + "&TOKEN="+req.getSession(). getAttribute("paypal-token") + "&METHOD=GetAuthDetails"); client.executeMethod(method); Hashtable<String, String> respBodyParams = getParamsFromBody( method.getResponseBodyAsString()); String ack = respBodyParams.get("ACK"); if (ack != null && ack.equals("Success")) { String email = respBodyParams. get("EMAIL"); String firstName = respBodyParams. get("FIRSTNAME"); String lastName = respBodyParams. get("LASTNAME"); // Use this information (perhaps save it // in session or in a database, etc. and // then redirect the user to your // successful login page return; } else { req.getSession().setAttribute( "paypal-token", null); // Redirect the user back to your // home page and display a login failure // message. return; } } else { req.getSession().setAttribute( "paypal-token", null); // Redirect the user back to your // home page and display a login // failure message. return; } } else { req.getSession().setAttribute( "paypal-token", null); // Redirect the user back to your home page and // display a login failure message. return; } } private Hashtable<String, String> getParamsFromBody(String body) { StringTokenizer stTok = new StringTokenizer(body, "&"); Hashtable<String, String> hash = new Hashtable<String, String>(); while (stTok.hasMoreElements()) { StringTokenizer stk = new StringTokenizer(stTok.nextToken(), "="); hash.put(stk.nextToken(), URLDecoder.decode(stk.nextToken())); } return hash; } }
This is how this Servlet Works:
When the visitor clicks on a link on your website, you invoke this servlet without any parameters. The servlet looks for “auth-resp” parameter in the request. Since it doesn’t find that, it assumes that this is a new login request. It then makes a HTTP call to PayPal to get authentication token. While calling that the servlet provides the return URL as itself (So PayPal will call this servlet in case of success or failure). Once a valid token is received, the servlet stores that token in the session variable called “paypal-token” and redirects the visitor to PayPal’s login page. PayPal then handles the user login and authentication and in case of successful authentication, PayPal calls the servlet with an “auth-resp“. This time when the servlet is called, it does find “auth-resp” in the request parameters and it looks out for the “Success” acknowledgement in the auth-resp. If it is successful, it then calls the Authentication Service to get first name, last name and email of the visitor.
Hope this helps! Enjoy! And feel free to shoot questions if any!
package com.ellipsis.dive.servlet;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Date;
import java.util.Hashtable;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.mail.EmailException;
import com.Ostermiller.util.StringTokenizer;
import com.ellipsis.dive.domain.UserDao;
import com.ellipsis.dive.model.User;
import com.ellipsis.dive.utils.EmailSender;
@SuppressWarnings(“serial”)
public class LoginWithPayPal extends HttpServlet {
private static Log log = LogFactory.getLog(LoginWithPayPal.class);
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doPost(req, resp);
}
@SuppressWarnings(“deprecation”)
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
if (req.getParameter(“auth-resp”) == null) {
HttpClient client = new HttpClient();
GetMethod method = new GetMethod(“https://api-3t.paypal.com/nvp?” +
“USER=sales_api1.ellipsissolutions.com” +
“&PWD=SYABFV7DEQZUGNCA” +
“&SIGNATURE=AKxshOAvZdwPThAccajffzxpJ2P-AX9dlPIJmTKtsIUW2DnFgLYMOiB8″ +
“&VERSION=65%2e1″ +
“&RETURNURL=http://apps.ellipsissolutions.com/dive/loginwithpaypal.servlet?auth-resp=success” +
“&CANCELURL=http://apps.ellipsissolutions.com/dive/loginwithpaypal.servlet?auth-resp=cancel” +
“&LOGOUTURL=http://apps.ellipsissolutions.com/dive/loginwithpaypal.servlet?auth-resp=logout” +
“&SERVICENAME1=Name” +
“&SERVICEDEFREQ1=Required” +
“&SERVICENAME2=Email” +
“&SERVICEDEFREQ2=Required” +
“&INITFLOWTYPE=Signup” +
“&HDRIMG=http://www.ellipsissolutions.com/logo.jpg” +
“&METHOD=SetAuthFlowParam”);
client.executeMethod(method);
Hashtable<String, String> respBodyParams = getParamsFromBody(method.getResponseBodyAsString());
String token = respBodyParams.get(“TOKEN”);
String ack = respBodyParams.get(“ACK”);
if (token != null && ack != null && ack.equals(“Success”)) {
req.getSession().setAttribute(“paypal-token”, token);
resp.sendRedirect(“https://www.paypal.com/cgi-bin/webscr?cmd=_account-authenticate-login&token=”+URLDecoder.decode(token));
return;
} else {
req.getSession().setAttribute(“paypal-token”, null);
resp.sendRedirect(“/dive/default.jsp?login_msg=” + URLEncoder.encode(“Login Failure! Please Try Again Later.”));
return;
}
} else if (req.getParameter(“auth-resp”).equals(“success”)) {
if (req.getSession().getAttribute(“paypal-token”) != null) {
HttpClient client = new HttpClient();
GetMethod method = new GetMethod(“https://api-3t.paypal.com/nvp?” +
“USER=sales_api1.ellipsissolutions.com” +
“&PWD=SYABFV7DEQZUGNCA” +
“&SIGNATURE=AKxshOAvZdwPThAccajffzxpJ2P-AX9dlPIJmTKtsIUW2DnFgLYMOiB8″ +
“&VERSION=65%2e1″ +
“&TOKEN=”+req.getSession().getAttribute(“paypal-token”) +
“&METHOD=GetAuthDetails”);
client.executeMethod(method);
Hashtable<String, String> respBodyParams = getParamsFromBody(method.getResponseBodyAsString());
String ack = respBodyParams.get(“ACK”);
if (ack != null && ack.equals(“Success”)) {
try {
String email = respBodyParams.get(“EMAIL”);
User u = UserDao.get(email);
if (u != null) {
u.setLastLoginTime(new Date());
UserDao.update(u);
req.getSession().setAttribute(“loginUser”, u);
if (req.getSession().getAttribute(“redirectUrl”) == null) {
req.getSession().setAttribute(“paypal-token”, null);
resp.sendRedirect(“/dive/login/manage.jsp”);
} else {
req.getSession().setAttribute(“paypal-token”, null);
resp.sendRedirect((String)req.getSession().getAttribute(“redirectUrl”));
req.getSession().removeAttribute(“redirectUrl”);
}
return;
} else {
String firstName = respBodyParams.get(“FIRSTNAME”);
String lastName = respBodyParams.get(“LASTNAME”);
u = new User();
u.setEmail(email);
u.setFirstName(firstName);
u.setLastName(lastName);
Date today = new Date();
u.setRegistrationDate(today);
u.setLastLoginTime(today);
u.setPerLeadDiveFee(0);
u.setPerDupLeadDiveFee(0);
u.setAccountBalance(0);
u.setSendWeeklyDigest(true);
try {
UserDao.save(u);
try {
EmailSender.sendMail(false, EmailSender.SENDER_TECHSUPPORT, EmailSender.SENDER_SALES,
“[ellipsis dive!] New User Registration”,
“<html><body>” +
“Name: ” + u.getFirstName() + ” ” + u.getLastName() + “<br/>” +
“Email: ” + u.getEmail() + “<br/>” +
“</body></html>”);
} catch (EmailException e) {
e.printStackTrace();
}
u = UserDao.get(u.getEmail());
req.getSession().setAttribute(“loginUser”, u);
resp.sendRedirect(“/dive/login/manage.jsp”);
} catch (SQLException e) {
req.getSession().setAttribute(“paypal-token”, null);
log.error(e.getMessage());
req.getSession().setAttribute(“exception”, e);
resp.sendRedirect(“/dive/error.jsp”);
}
return;
}
} catch (SQLException e) {
req.getSession().setAttribute(“paypal-token”, null);
log.error(e.getMessage());
req.getSession().setAttribute(“exception”, e);
resp.sendRedirect(“/dive/error.jsp”);
return;
}
} else {
req.getSession().setAttribute(“paypal-token”, null);
resp.sendRedirect(“/dive/default.jsp?login_msg=” + URLEncoder.encode(“Login Failure! Please Try Again Later.”));
return;
}
} else {
req.getSession().setAttribute(“paypal-token”, null);
resp.sendRedirect(“/dive/default.jsp?login_msg=” + URLEncoder.encode(“Login Failure! Please Try Again Later.”));
return;
}
} else {
req.getSession().setAttribute(“paypal-token”, null);
resp.sendRedirect(“/dive/default.jsp”);
return;
}
}
@SuppressWarnings(“deprecation”)
private Hashtable<String, String> getParamsFromBody(String body) {
StringTokenizer stTok = new StringTokenizer(body, “&”);
Hashtable<String, String> hash = new Hashtable<String, String>();
while (stTok.hasMoreElements()) {
StringTokenizer stk = new StringTokenizer(stTok.nextToken(), “=”);
hash.put(stk.nextToken(), URLDecoder.decode(stk.nextToken()));
}
return hash;
}
}
–
info@ellipsissolutions.com
ellipsis solultions LLC
http://www.ellipsissolutions.com
PO Box 2462, Union City, CA 94587
|
Toll Free: |
+1 (855) ELLIPSIS |
|
FAX: |
+1 (855) 355-4774 |
**************************************************************************
ellipsis solutions is committed to protecting your privacy and asks you not to send sensitive
account information through e-mail. If you are not an ellipsis solutions customer and believe
you received this message in error, please notify us by responding to this email.
**************************************************************************
August 5, 2011 at 9:00 am Comments (0)