PayPal IPN с fsockopen возвращает NULL - PullRequest
2 голосов
/ 04 января 2012

Я пытаюсь настроить IPP PayPal в своем веб-приложении, я скопировал из документации PayPal примерный фрагмент PHP, который можно найти здесь .

Однако, когда я тестирую с песочницей PayPal, отправляю IPN с симулятором, который найден здесь .

Теперь, когда PayPal отправляет IPN, я регистрирую действия и данные IPN, при попытке открыть соединение с помощью fsockopen, NULL, когда я * var_export.

Я не понимаю, почему код не идет дальше, когда fsockopen соединение NULL.

Я использую Codeigniter для своего приложения, и эта часть кода не работает:

if($this->uri->segment(3) == 'ipn')
{
    $error_msg = '';

    $error_msg .= " initiated ";

    $req = 'cmd=_notify-validate';

    $error_msg .= " \n\n req: " . var_export($req, true);

    foreach($this->input->post() as $key => $value) 
    {
        $value = urlencode(stripslashes($value));
        $req .= "&" . $key . "=" . $value;
    }

    $error_msg .= " \n\n req: " . var_export($req, true);

    $header = '';
    $header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
    $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
    $header .= "Content-Length: " . strlen($req) . "\r\n\r\n";

    $error_msg .= " \n\n headers: " . var_export($header, true);

    $fp = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30);

    $error_msg .= " \n\n fp: " . var_export($fp, true);

Я использую $error_msg для регистрации данных, это пример того, что регистрируется:

 initiated  

 req: 'cmd=_notify-validate' 

 req: 'cmd=_notify-validate&test_ipn=1&payment_type=echeck&payment_date=17%3A30%3A40+Jan+03%2C+2012+PST&payment_status=Completed&address_status=confirmed&payer_status=verified&first_name=John&last_name=Smith&payer_email=buyer%40paypalsandbox.com&payer_id=TESTBUYERID01&address_name=John+Smith&address_country=United+States&address_country_code=US&address_zip=95131&address_state=CA&address_city=San+Jose&address_street=123%2C+any+street&business=seller%40paypalsandbox.com&receiver_email=seller%40paypalsandbox.com&receiver_id=TESTSELLERID1&residence_country=US&item_name=something&item_number=DX4WYSur44CQICgO2lC%2FB10NmdaiPNH3xPZXQNAlfrEqpse0xnime22zaNXDFgbRrOL4Xsz4emkhqFw4JhOSHzCtaHt9%2B0p9p8xW6R71PVbFXNyEVjkPeHNdQm32PJg&quantity=1&shipping=3.04&tax=2.02&mc_currency=USD&mc_fee=0.44&mc_gross=12.34&txn_type=web_accept&txn_id=4014130&notify_version=2.1&custom=xyz123&invoice=abc1234&charset=windows-1252&verify_sign=An5ns1Kso7MWUdW4ErQKJJJ4qi4-AN8d2a.xggmx9Dn4AgHpvPHJHTAp' 

 headers: 'POST /cgi-bin/webscr HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 969

' 

 fp: NULL

Как видите, $fp возвращает NULL в последней строке зарегистрированных данных. Есть ли идея, почему это происходит?

Я могу подтвердить, что OpenSSL включен и установлен на моем сервере:

enter image description here

РЕДАКТИРОВАТЬ: только что проверил fsockopen на порт 80 до google.com, я все еще получаю NULL без номера ошибки или сообщения. Так что эта проблема возникает с каждым URL.

РЕДАКТИРОВАТЬ # 2: Протестировано на моем сервере, выполнив это:

fsockopen('ssl://www.paypal.com/cgi-bin/webscr', 443, $errno, $errstr, 30)

Произошла ошибка PHP

Серьезность: Предупреждение

Сообщение: fsockopen (): невозможно подключиться к ssl: //www.paypal.com/cgi-bin/webscr: 443 (php_network_getaddresses: сбой getaddrinfo: имя или имя сервера не предоставлено или не известно)

Ответы [ 4 ]

2 голосов
/ 14 февраля 2016

Если у кого-то еще есть такая же проблема, попробуйте использовать HTTPS вместо SSL

$fp = fsockopen ('https://www.paypal.com', 443, $errno, $errstr, 30);

А если при тестировании в Paypals Sandbox используется:

$fp = fsockopen ('https://www.sandbox.paypal.com', 443, $errno, $errstr, 30);
2 голосов
/ 08 января 2012

Будьте осторожны с $config['csrf_protection'] = TRUE;, это заблокирует все внешние сообщения, так как они не будут иметь CSRF token, у меня было это с моим PayPal IPN раньше, мне нужно было включить грубый, но эффективный способ получить обратный вызов(в config.php):

if(stripos($_SERVER["REQUEST_URI"],'/paypal') === FALSE) {
  // disable CSRF for the /paypal 
    $config['csrf_protection'] = TRUE;
} else {
    $config['csrf_protection'] = FALSE;
}

Я предполагаю, что это может быть проблемой, вы получите null, поскольку никакие данные не будут захвачены, так как CI просматривает ваши $_POST/$_GET переменные по соображениям безопасности.

Если я неправильно понял ваш вопрос и я не в курсе, просто дайте мне знать через комментарий.

1 голос
/ 11 января 2012

Контрольный список

  1. URL песочницы: "https://www.sandbox.paypal.com/cgi-bin/webscr";
  2. подобно @jakub говорит, что CSRF должен быть отключендля вашего контроллера PayPal
  3. IPN не будет проверяться на локальном хосте, однако вы все равно должны получить переменные.
  4. var_dump (fsockopen ('https://www.sandbox.paypal.com/', 443, $ errno, $errstr, 30));
  5. var_dump ($ _ POST);
0 голосов
/ 04 января 2012

Переменные $errno и $errstr, вероятно, содержат причину сбоя.Выведите их с сообщением об ошибке.

...