2016-03-18 5 views
0

Я знаю, что это обсуждалось несколько раз - хотя исследовался каждый отдельный поток, я не могу его запустить. Прежде чем отказаться от этого, я хочу дать ему последнюю попытку:nodejs paypal ipn недействителен

Мое окружение - это современные узлы с курьерским и кузовным аппаратом. Я разработал свое приложение и попытался выполнить простую проверку Paypal Express. Я использовал paypal-ipn, но не смог получить ответ VALID от Paypal. Я играл с тем, что, как я полагал, было проблемой (реализовал синтаксический анализатор тела только для обратного вызова paypal, играл с параметрами кодирования и заголовка, переключал настройки в учетной записи paypal из окон в кодировку utf8), но вы, возможно, уже знаете, ничего не работало , Поэтому я решил оставить свое приложение и пойти с нуля с простой и простой новой настройкой. Я использовал другой подход, найденный в сети, и снова оказался с той же ошибкой. Затем я решил пойти «вживую», как иногда сообщается, что песочница всегда возвращается недействительно. Попытка стоила мне 50-процентной транзакционной комиссии ... и осталась недействительной :-)

Что-то меня смущает, так это то, что большинство обсуждений, которые я нашел, несколько лет. Поскольку я использовал 2 разных фрагмента кода (которые оба были и остаются), которые были указаны как достоверные, я считаю справедливым предположить, что это не общая ошибка в логике программирования. Возможно, произошли изменения в API Paypal или обновленные пакеты 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); 

Консольный журнал показывает два одинаковых тела для принятых и отправленных.

Любые идеи?

Большое спасибо.

Редактировать через день: Вещи становятся более любопытными. Для дальнейшего изучения я настраиваю среду wamp, используя собственный пример php Paypals, опубликованный в Github. Что я должен сказать: недействительно. Это сводит меня с ума ...

+0

Я в настоящее время имеющий ту же самую проблему. Не удалось получить ответ ниже, чтобы работать. Вам удалось решить эту проблему в конце концов? – Fizzix

ответ

0

Это мой код. У меня были некоторые случайные НЕВЕРНЫЕ ответы, которые тоже сводили меня с ума. Дело в том, что у нас есть интерфейс на испанском языке, и иногда звонок из PAYPAL включал специальные символы, но те были уже сбежаны ... мы снова убегали от них. Таким образом, мы удалили «querystring.escape» при составлении почтового запроса на paypal; которые решили нашу проблему.

Это код:

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') {