Jsp – How to use HTTP POST in JSP page to send a FORM to Paypal and read response

httphttp-gethttp-postjsppaypal

I'm using paypal's sandbox to test out the Payment Data Transfer (PDT) feature from Paypal. Please note, Paypal doesn't have a code example, in JSP, for PDT. I'm shocked, since they seem to have examples for everything else.

According to Paypal, I can specify the URL that I want to use for processing the PDT information. I did just that in my sandbox profile.

Now I'm stuck on a few things with the JSP code. I managed to get some example code, but it might not be complete, and to tell you the truth, I'm not exactly familiar with some of the code in it.

The JSP code is below. If you look at Paypal's Payment Data Transfer page, it explains, without any code examples, the PDT process.

It states that the transaction id will be appended to the URL specified in your Profile. Okay, so I can get that id via request.getParameter("tx"). That's the easy part.

1) — But how do I POST the form (as shown below) back to Paypal? That part I don't understand. How do I code that?

2) –Then the page states "In PayPal's reply to your post, the first line will be SUCCESS or FAIL. An example successful response looks like this (HTTP Header has been omitted):
SUCCESS

first_name=Jane+Doe
last_name=Smith
payment_status=Completed
payer_email=janedoesmith%40hotmail.com
payment_gross=3.99
mc_currency=USD
custom=For+the+purchase+of+the+rare+book+Green+Eggs+%26+Ham

How is this information retrieved from within my JSP page?

Html Form to Post to Paypal

<form method=post action="https://www.paypal.com/cgi-bin/webscr"> 
<input type="hidden" name="cmd" value="_notify-synch"> 
<input type="hidden" name="tx" value="TransactionID"> 
<input type="hidden" name="at" value="YourIdentityToken"> 
<input type="submit" value="PDT"> 
</form>

JSP code

// Java JSP

<%@ page import="java.util.*" %>
<%@ page import="java.net.*" %>
<%@ page import="java.io.*" %>

<%@ page import="javax.servlet.*"%>
<%@ page import="javax.servlet.http.*"%>
<%@ page import="javax.naming.*"%>
<%@ page import="javax.sql.*"%>
<%@ page import="java.sql.*"%>

<%
// read post from PayPal system and add 'cmd'
Enumeration en = request.getParameterNames();
String str = "cmd=_notify-validate";
while(en.hasMoreElements()){
String paramName = (String)en.nextElement();
String paramValue = request.getParameter(paramName);
str = str + "&" + paramName + "=" + URLEncoder.encode(paramValue);
}

String transId = request.getParameter("tx");

// post back to PayPal system to validate
// NOTE: change http: to https: in the following URL to verify using SSL (for increased security).
// using HTTPS requires either Java 1.4 or greater, or Java Secure Socket Extension (JSSE)
// and configured for older versions.
java.net.URL u = new java.net.URL("https://www.sandbox.paypal.com/cgi-bin/webscr");

java.netHttpURLConnection uc = (java.net.HttpURLConnection)u.openConnection();

uc.setRequestMethod("POST");

uc.setDoOutput(true);
uc.setRequestProperty("Content-Type","application/x-www-form-urlencoded");

PrintWriter pw = new PrintWriter(uc.getOutputStream());
pw.println(str);
pw.close();

BufferedReader in = new BufferedReader(
new InputStreamReader(uc.getInputStream()));
String res = in.readLine();
in.close();

// assign posted variables to local variables
String itemName = request.getParameter("item_name");
String itemNumber = request.getParameter("item_number");
String paymentStatus = request.getParameter("payment_status");
String paymentAmount = request.getParameter("mc_gross");
String paymentCurrency = request.getParameter("mc_currency");
String txnId = request.getParameter("txn_id");
String receiverEmail = request.getParameter("receiver_email");
String payerEmail = request.getParameter("payer_email");

            DataSource ds = null;
            Connection conn = null;
            Statement stmt = null;

            try {
            final Context ctx = new InitialContext();
            ds = (DataSource) ctx.lookup("java:comp/env/jdbc/mydb");
            conn = ds.getConnection();
            stmt = conn.createStatement();

            //test_paypal
            int success = stmt.executeUpdate("insert into test_paypal values("paymentStatus="+request.getParameter("payment_status")+"paymentAmount="+request.getParameter("mc_gross")+
                                             "txnId"+request.getParameter("txn_id")+")");
             }//try
             catch(Exception e) {}

             finally {
                       stmt.close();
                       conn.close();
                     }



check notification validation
if(res.equals("VERIFIED")) {
// check that paymentStatus=Completed
// check that txnId has not been previously processed
// check that receiverEmail is your Primary PayPal email
// check that paymentAmount/paymentCurrency are correct
// process payment
}
else if(res.equals("INVALID")) {
// log for investigation
}
else {
// error
}
%>

Best Answer

To expand on @BalusC's comment a bit... I agree with him - you might want to consider using the PayPal API instead. There are two versions, the NVP (Name Value Pair) version and the SOAP version.

Essentially, it does come down to the same thing - you take the transactionId that is passed to you on the return URL, and you use that to to make a server side request to PayPal to retrieve the detailed information about the transaction.

However:

  1. Once you've learned your way around the NVP API, you'll find that it provides much richer data then this simple PDT POST.
  2. The NVP API will intuitively make more sense to you. You'll also find code examples and SDKs in all languages.
  3. If you do much work with PayPal, you'll find yourself dealing with the NVP API anyway. Might as well just do it now.