2010-08-04 3 views
4

Я тестирую интеграцию веб-сайта с Paypal, используя стандарт веб-платежей и HTML-переменные.Paypal IPN, возвращающий HTTP/1.1 200 OK

Я написал простой PHP-скрипт для обработки уведомлений IPN.

Согласно Paypal documentation, сервер Paypal отвечает простой «ПОДТВЕРЖДЕН» или ответ «INVALID» после того, как вы свистеть полученные данные обратно в Paypal.

В моем обработчике я выполняю сравнение строк для этих двух ключевых слов, если одно из этих известных ключевых слов не найдено, тогда оно рассматривается как ошибка.

<?php 
    $fp = fsockopen ($socket_url, 80, $errno, $errstr, 10); 

    if (!$fp){ 
    // SOCKET ERROR 
    return false; 
    } 
    else { 
     fputs ($fp, $header . $req); 
     $is_ok = false; 

     while (!feof($fp)) { 
      $res = fgets ($fp, 1024); 

      if (strcmp("VERIFIED",$this->ipn_response)==0) { 
       //do something ... 
      } 
      // if the IPN POST was 'INVALID' 
      else if (strcmp ($res, "INVALID") == 0) { 
       fclose ($fp); 
       return false; 
      } 
      else { 
       echo "Unknown response from Paypal: $res"; 
       fclose ($fp); 
       return false; 
      } 
     } 

     fclose ($fp); 
     return true; 
    } 
?> 

Мое сообщение об ошибке показывает, что я получаю ответ «HTTP/1.1 200 OK» от Paypal.

Неизвестный ответ от Paypal: 'HTTP/1.1 200 OK'

Имеет API PayPal изменился, или я делаю что-то не так?

ответ

2

ответ PayPal находится в теле ответа HTTP. Вам нужно обработать заголовки HTTP, прежде чем вы сможете добраться до тела. Или, поочередно, просто продолжайте чтение строк, пока не найдете пустую строку, а следующая строка будет телом.

+0

спасибо за ваш ответ, это было полезно для меня. – oletob

1

К сожалению, мой первоначальный ответ был действительно плохо сформулированное :)

fgets только чтение построчно, то первая строка является ответом HTTP. Ваш код никогда не дает возможности продолжить чтение, хотя, как вы «выходите из системы» после обработки первой строки.

я был бы склонен заменить время цикла с чем-то вроде:

while (!feof($fp)) { 
     $res = trim(fgets($fp, 1024)); 

     if (strcmp($res, "VERIFIED")==0) { 
      //do something ... 
     } 
     else if (strcmp($res, "INVALID") == 0) { 
      fclose ($fp); 
      return false; 
     } 
    } 
1

Как сказал @Mike, вы должны прочитать все тело - в вашем случае вы просто проверяете, будет ли VERIFIED или INVALID в первых 1024 байтах ответа, что, вероятно, является заголовком.

Кстати, вам не нужно использовать fsockopen(), большинство людей делают это, потому что PayPal предоставляет пример, использующий его, чтобы он работал в старых установках. CURL или file_get_contents с контекстом в HTTP POST будет делать эту работу просто отлично, вот пример, который я закодирован для phunction PHP framework:

public static function PayPal($email, $status = 'Completed', $sandbox = false) 
{ 
    if (preg_match('~^(?:.+[.])?paypal[.]com$~', gethostbyaddr($_SERVER['REMOTE_ADDR'])) > 0) 
    { 
     $url = ($sandbox !== true) ? '' : '.sandbox'; 
     $result = self::CURL('https://www' . $url . '.paypal.com/cgi-bin/webscr/', array_merge(array('cmd' => '_notify-validate'), $_POST), 'POST'); 

     if ($result == 'VERIFIED') 
     { 
      $email = strlen($email) * strcasecmp($email, $_POST['receiver_email']); 
      $status = strlen($status) * strcasecmp($status, $_POST['payment_status']); 

      if (($email == 0) && ($status == 0)) 
      { 
       return true; 
      } 
     } 
    } 

    return false; 
} 
Смежные вопросы