I am using Node.js for my server and paypal-ipn for IPN verification. When I send an IPN from the Simulator to myself (my IP + port forwarding), I see IPN was sent and the handshake was verified. message on the Simulator page. So my listener is working correctly.
This is my server code:
ipn = require('paypal-ipn');
app.post('/ipn', function(req, res){
res.sendStatus(200);
ipn.verify(req.params, {'allow_sandbox':false}, function callback(err, msg){
if(err){
console.log(err);
} else {
console.log('Verify no error.');
if(params.payment_status == 'Completed') {
console.log('Payment completed.');
}
}
});
});
The problem is that I don't have the test_ipn
variable in req.params
. How I know that? I have intentionally set allow_sandbox
to false
.This is a chunk of the code from paypal-ipn
:
if (params.test_ipn && !settings.allow_sandbox) {
process.nextTick(function () {
callback(new Error('Received request with test_ipn parameter while sandbox is disabled'));
});
return;
}
If allow_sandbox
is disabled (which it is) and I have test_ipn
set, I should be seeing Received request with test_ipn parameter while sandbox is disabled, but I don't. This means the other part of the condition is not met - test_ipn
is missing. I see this instead:
Error: IPN Verification status: <HTML><HEAD>
<TITLE>Access Denied</TITLE>
</HEAD><BODY>
<H1>Access Denied</H1>
You don't have permission to access "http://www.paypal.com/cgi-bin/webscr" on this server.<P>
Reference #18.8d5e6cc1.1462971151.3d758294
</BODY>
</HTML>
at IncomingMessage.response_end (C:\Users\Hristiyan\Desktop\StickGame\node_modules\paypal-ipn\lib\paypal-ipn.js:57:18)
at emitNone (events.js:91:20)
at IncomingMessage.emit (events.js:185:7)
at endReadableNT (_stream_readable.js:926:12)
at _combinedTickCallback (internal/process/next_tick.js:74:11)
at process._tickCallback (internal/process/next_tick.js:98:9)
Notice that it attempts to use the live paypal URL, not the sandbox one.
With allow_sandbox
set to true, I get the same thing. That's because paypal-ipn
receives a request without test_ipn
set and thinks the IPN is real when it is not.
I also tried to add test_ipn
to the request myself, but then, I have manually altered the initial request, which makes the transaction invalid and shows this:
Error: IPN Verification status: INVALID
at IncomingMessage.response_end (C:\Users\Hristiyan\Desktop\StickGame\node_modules\paypal-ipn\lib\paypal-ipn.js:57:18)
at emitNone (events.js:91:20)
at IncomingMessage.emit (events.js:185:7)
at endReadableNT (_stream_readable.js:926:12)
at _combinedTickCallback (internal/process/next_tick.js:74:11)
at process._tickCallback (internal/process/next_tick.js:98:9)
On my PayPal sandbox accounts, I have Review test payments before they're completed. set to On.