Node express bodyParser for Paypal IPN

I'm trying to get paypal ipn working for my node.js express app and I have to validate the ipn message once I receive it by "send[ing] back the contents in the exact order they were received and precede it with the command _notify-validate". The example they give is a query string like this:

https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_notify-validate&mc_gross=19.95&protection_eligibility=Eligible&address_status=confirmed&payer_id=LPLWNMTBWMFAY&tax=0.00&...&payment_gross=19.95&shipping=0.00

However, because I'm using bodyParser, the request.body is a json object. If I am to append the "cmd=_notify-validate" and send it back, how would I receive it as a simple querystring and send it as a simple querystring without getting rid of bodyParser? I still need the json-parsed version on this route for actually interpreting the data. Also, what does sending a POST on server-side look like? (do I just do res.send(str)?)

I used paypal-ipn module for node and it turns out a json parsed body is fine. The main problem i had using this module was making sure to respond with res.send(200), otherwise paypal's ipn keeps sending the message for about a minute at intervals. Here's the code to help:

exports.ipn = function(req,res){
    var params = req.body
    res.send(200);

    ipn.verify(params, function callback(err, msg) {
        if (err) { console.log(err); return false }

        if (params.payment_status == 'Completed') {

            // Payment has been confirmed as completed
            // do stuff, save transaction, etc.
        }
    });
}

Since you did ask about how to make an HTTP POST request, this is how you do it.

var options = {
  host: 'example.com',
  port: '80',
  path: '/pathname',
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
    'Content-Length': post_data.length
  }
};

var post_req = http.request(options, function (res) {
  res.setEncoding('utf8');
  var chunks = '';
  res.on('data', function (chunk) {
    chunks += chunk;
  });
  res.on('end', function() {
    console.log(chunks);
  });
});

post_req.write(post_data);
post_req.end();

I also struggled for a day or two for this IPN to make it work. I had a similar issue with bodyparser and url-encoded.

Here is some working sample code in NodeJS that listen to incoming IPN message and validate it against Paypal Sandbox.

https://github.com/HenryGau/node-paypal-ipn

You can run the subscriptionMessage.js by mocha subscriptionMessage.js in tests folder to mimic/simulate Paypal IPN message.

Hope it helps.