Saturday, August 7, 2010

PayPal Mass Payments using HttpClient 4

Here's another PayPal tip. The PayPal Mass Payments feature allows anyone with a Premier or Business account to send multiple payments instantly—saving time, money and the hassle of having to individually send funds to every payment recipient.

In this tip I will show you how to make a mass payment using the apache httpclient library (http://hc.apache.org/httpcomponents-client/index.html), version 4.

First we define some constants we'll need in the code:

private NumberFormat paypalNumberFormat = new DecimalFormat("0.00", new DecimalFormatSymbols(Locale.US));
private static final String PAYPAL_URL = "https://api-3t.sandbox.paypal.com/nvp"; //Remove the ".sandbox" if you want to use the live environment
private static final String PAYPAL_USER = "username";
private static final String PAYPAL_PASSWORD = "password";
private static final String PAYPAL_SIGNATURE = "signature";

Here's the code to make the actual call:

HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(PAYPAL_URL);
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("USER", PAYPAL_USER));
params.add(new BasicNameValuePair("PWD", PAYPAL_PASSWORD));
params.add(new BasicNameValuePair("SIGNATURE", PAYPAL_SIGNATURE));
params.add(new BasicNameValuePair("VERSION", "2.3"));
params.add(new BasicNameValuePair("METHOD", "MassPay"));
params.add(new BasicNameValuePair("RECEIVERTYPE", "EmailAddress"));
params.add(new BasicNameValuePair("L_EMAIL0", email));
params.add(new BasicNameValuePair("L_AMT0", paypalNumberFormat.format(amountToSend)));
params.add(new BasicNameValuePair("CURRENCYCODE", "USD"));
post.setEntity(new UrlEncodedFormEntity(params));
HttpResponse response = client.execute(post);

This sample will send 1 payment to the PayPal account in the email variable and with the amount in the amountToSend variable. The parameters are called L_EMAIL0 and L_AMT0. Since this is the mass payments API, you can send more than one payment. To do so, just add 2 new parameters for each payment you want to make: L_EMAILx for the PayPal account you want to send the money to and L_AMTx for the amount you want to transfer. x is a number from 0 to 255, making the maximum number of simultaneous payments you can make 256.

PayPal sends back a couple of parameters. You will probably want to check the "ACK" parameter, which tells you if your call succeeded. See https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_nvp_NVPAPIOverview for an overview of the parameters and their values returned by PayPal. Here is a way to parse the response:

private Map<String, String> parseResponse(HttpResponse response) throws IllegalStateException, IOException {
Map<String, String> map = new HashMap<String, String>();
String responseStr = getResponseContent(response);
List<NameValuePair> responseParams = new ArrayList<NameValuePair>();
URLEncodedUtils.parse(responseParams, new Scanner(responseStr), "UTF-8");
for (NameValuePair nvp : responseParams) {
map.put(nvp.getName(), nvp.getValue());
}
return map;
}

private String getResponseContent(HttpResponse response) throws IOException, IllegalStateException {
InputStream is = response.getEntity().getContent();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String result = "";
String line = null;
while ((line = br.readLine()) != null) {
result += line;
}
return result;
}

You can call it like this:

Map<String, String> responseParams = parseResponse(response);
String ack = responseParams.get("ACK");
if (ack != null && ack.indexOf("Success") >= 0) {
//Do something
} else {
//Do something else
}