2010-08-04 47 views
4

我正在測試使用Web Payments標準和HTML變量將網站集成到PayPal。PayPal IPN返回HTTP/1.1 200好

我寫了一個簡單的PHP腳本來處理IPN通知。

按照Paypal documentation,貝寶服務器用一個簡單的「VERIFIED」或「無效」響應來響應,一旦你ping命令接收到的數據回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; 
    } 
?> 

我的錯誤消息顯示我收到來自Paypal的'HTTP/1.1 200 OK'響應。

貝寶

未知響應: 'HTTP/1.1 200 OK'

已PayPal的API改變了,還是我做錯了什麼?

回答

2

PayPal的反應是在HTTP響應的主體。您需要先處理HTTP標頭,然後才能進入正文。或者,也可以繼續閱讀直到找到空行,然後下一行將是主體。

+0

非常感謝您的回答,對我來說是有幫助的。 – oletob 2013-10-09 16:39:08

1

對不起,我最初的反應是實在太差了措辭:)

與fgets只能逐行讀取行,第一行是HTTP響應。但是,您的代碼永遠不會讓您有機會繼續閱讀,因爲您在處理完第一行後「錯誤退出」。

我傾向於喜歡的東西來代替while循環:

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所說的,你必須閱讀全文 - 在你的情況下,你只是測試如果VERIFIEDINVALID出現在答覆的前1024個字節中,這可能是頭。

順便說一下,大多數人都不需要使用fsockopen(),因爲PayPal提供了一個使用它的示例,以便它可以在舊套件中使用。捲曲或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; 
}