我知道这已经讨论了好几次 - 虽然研究过每一个线程我都无法运行它。在放弃这个之前,我想最后一次尝试:
我的环境是使用express和bodyparser的最新nodejs。我开发了我的应用程序并尝试实现简单的Paypal Express结账。我使用了paypal-ipn,但无法从Paypal获得有效的回复。我玩了我认为的问题(实现了一个原始的解析器,仅用于paypal回调,使用编码和标题选项,在paypal帐户中从windows转换为utf8编码)但你可能已经知道,没有任何工作。所以我决定离开我的应用程序并从头开始使用简单而简单的新设置。我在网上使用了一种不同的方法,最后又出现了同样的错误。然后我决定去"生活"有时会报告,沙箱总是返回无效。那次尝试花了我50美元的交易费......并保持无效: - )
让我感到困惑的是,我发现的大部分讨论都是几年之久。由于我使用了2个不同的代码片段(它们都已经存在并且仍然存在),因此我认为将其视为编程逻辑中的一般错误是公平的。 Paypal API或更新的nodejs软件包可能已经发生了变化。所以,如果你们中的任何一个人能指出我正确的方向......
这是我目前的代码。我在其中留下了一些bodyparser替代品,只是为了将其投入讨论。而且,我并不想用借来的羽毛来装饰自己。大部分代码都是来自网络的片段:
var express = require('express');
var querystring = require('querystring');
var request = require('request');
var colors = require('colors');
var bodyParser = require('body-parser');
var StringDecoder = require('string_decoder').StringDecoder;
colors.setTheme({
silly: 'rainbow',
input: 'grey',
verbose: 'cyan',
prompt: 'grey',
info: 'green',
data: 'grey',
help: 'cyan',
warn: 'yellow',
debug: 'blue',
error: 'red'
});
var app = express();
var bpJSON = bodyParser.json();
var bpUrl = bodyParser.urlencoded({
extended: false
});
var parseRaw = function (req, res, next) {
req.body = '';
var helper = '';
req.setEncoding('utf8');
var decoder = new StringDecoder('utf8');
req.on('data', function (chunk) {
req.body += decoder.write(chunk);
console.log(req.body);
});
req.on('end', function () {
next();
});
};
app.use(function (req, res, next) {
if (!~req.url.indexOf('/notipal')) bpJSON(req, res, next)
else return next();
});
app.use(function (req, res, next) {
if (!~req.url.indexOf('/notipal')) bpUrl(req, res, next)
else return next();
});
app.use(function (req, res, next) {
if (~req.url.indexOf('/notipal')) parseRaw(req, res, next)
else return next();
});
app.get('/', function (req, res) {
res.end('Response will be available on console, nothing to look here!');
});
app.post('/notipal', function (req, res) {
console.log('Received POST /'.bold);
console.log(req.body);
logger.log(req.body);
console.log('\n\n');
// STEP 1: read POST data
req.body = req.body || {};
res.send('200');
res.end();
// read the IPN message sent from PayPal and prepend 'cmd=_notify-validate'
var postreq = 'cmd=_notify-validate';
for (var key in req.body) {
if (req.body.hasOwnProperty(key)) {
var value = querystring.escape(req.body[key]);
postreq = postreq + "&" + key + "=" + value;
console.log('key: ' + key + ' value: ' + value);
}
}
// Step 2: POST IPN data back to PayPal to validate
console.log('Posting back to paypal'.bold);
console.log(postreq);
console.log('\n\n');
var options = {
url: 'https://www.sandbox.paypal.com/cgi-bin/webscr',
method: 'POST',
headers: {
'Connection': 'close'
},
body: postreq,
strictSSL: true,
rejectUnauthorized: false,
requestCert: true,
agent: false
};
request(options, function callback(error, response, body) {
if (!error && response.statusCode === 200) {
// inspect IPN validation result and act accordingly
if (body.substring(0, 8) === 'VERIFIED') {
// The IPN is verified, process it
console.log('Verified IPN!'.green);
console.log('\n\n');
// assign posted variables to local variables
var item_name = req.body['item_name'];
var item_number = req.body['item_number'];
var payment_status = req.body['payment_status'];
var payment_amount = req.body['mc_gross'];
var payment_currency = req.body['mc_currency'];
var txn_id = req.body['txn_id'];
var receiver_email = req.body['receiver_email'];
var payer_email = req.body['payer_email'];
//Lets check a variable
console.log("Checking variable".bold);
console.log("payment_status:", payment_status)
console.log('\n\n');
// IPN message values depend upon the type of notification sent.
// To loop through the &_POST array and print the NV pairs to the screen:
console.log('Printing all key-value pairs...'.bold)
for (var key in req.body) {
if (req.body.hasOwnProperty(key)) {
var value = req.body[key];
console.log(key + "=" + value);
}
}
} else if (body.substring(0, 7) === 'INVALID') {
// IPN invalid, log for manual investigation
console.log('Invalid IPN!'.error);
console.log('\n\n');
console.log(body);
}
}
});
});
var port = 80;
app.listen(port);
var msg = 'Listening at http://localhost:' + port;
console.log(msg.green.bold);
控制台日志显示两个相同的已接收和已发送的实体。
有什么想法吗?
提前多多感谢。
一天后编辑: 事情变得更加好奇。为了进一步调查,我使用在Github上发布的Paypals自己的php示例设置了一个wamp环境。我应该说什么:无效。这让我发疯了......
答案 0 :(得分:0)
这是我的代码。我有一些随机的无效答案,那些也让我发疯。问题是,我们有一个西班牙语界面,有时来自PAYPAL的调用包括特殊字符,但那些已经被转义......我们再次逃脱它们。所以我们在向paypal发布帖子请求时删除了“querystring.escape”;这解决了我们的问题。
这是代码:
function processNotify(req, res) {
console.log('Receiving call in /paypal/notify as POST. Dumping req.body...');
console.log(JSON.stringify(req.body));
// STEP 1: Read the IPN message sent from PayPal and prepend 'cmd=_notify-validate'
var postreq = 'cmd=_notify-validate';
for (var key in req.body) {
if (req.body.hasOwnProperty(key)) {
// postreq = postreq + "&" + key + "=" + querystring.escape(req.body[key]);
postreq = postreq + "&" + key + "=" + req.body[key];
}
}
// Step 2: POST IPN data back to PayPal to validate
console.log('Posting back to paypal');
config.paypal.verifyOptions.body = postreq;
request(config.paypal.verifyOptions, function callback(error, response, body) {
if (!error && response.statusCode !== 200) {
console.log('Error: Response status code !== 200, it is:' + response.statusCode());
return;
}
if (body.substring(0, 8) === 'VERIFIED') {