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.