2015-03-02 190 views
2

我已經被正確地發送郵件到我的文件的IPN,我已經證實,我接受了他們,首先這裏是我的代碼:貝寶IPN驗證

echo "test"; 
// Response from Paypal 

// read the post from PayPal system and add 'cmd' 
$req = 'cmd=_notify-validate'; 
foreach ($_POST as $key => $value) { 
    $value = urlencode(stripslashes($value)); 
    $value = preg_replace('/(.*[^%^0^D])(%0A)(.*)/i','${1}%0D%0A${3}',$value);// IPN fix 
    $req .= "&$key=$value"; 
} 

// assign posted variables to local variables 
$data['item_name']   = $_POST['item_name']; 
$data['item_number']  = $_POST['item_number']; 
$data['payment_status']  = $_POST['payment_status']; 
$data['payment_amount']  = $_POST['mc_gross']; 
$data['payment_currency'] = $_POST['mc_currency']; 
$data['txn_id']    = $_POST['txn_id']; 
$data['receiver_email']  = $_POST['receiver_email']; 
$data['payer_email']  = $_POST['payer_email']; 
$data['custom']    = $_POST['custom']; 

// post back to PayPal system to validate 
$header = "POST /cgi-bin/webscr HTTP/1.1\r\n"; 
$header .= "Host: www.sanbox.paypal.com\r\n"; 
$header .= "Accept: */*\r\n"; 
$header .= "Connection: Close\r\n"; 
$header .= "Content-Length: " . strlen($req) . "\r\n"; 
$header .= "Content-Type: application/x-www-form-urlencoded\r\n"; 
$header .= "\r\n"; 

$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30); 
if ($fp === FALSE) { 
exit("Could not open socket"); 
}else{ 
if (!$fp) { 
    echo "Error code: 200"; 
}else{ 

    fputs ($fp, $header . $req); 
$res = stream_get_contents($fp, 2048); 
echo "test2"; 
$res = trim($res); 
     if (strcmp($res, "VERIFIED") == 0){ 
     echo "test3"; 
      // Used for debugging 
      //@mail("[email protected]", "PAYPAL DEBUGGING", "Verified Response<br />data = <pre>".print_r($post, true)."</pre>"); 

      // Validate payment (Check unique txnid & correct price) 
      $valid_txnid = check_txnid($data['txn_id']); 
      $valid_price = check_price($data['payment_amount'], $data['item_number']); 
      // PAYMENT VALIDATED & VERIFIED! 
      if($valid_txnid && $valid_price){ 
       $orderid = updatePayments($data);  
       if($orderid){  
        echo "thanks for your payment!"; 
        $lel = mysqli_query($con,"UPDATE stats SET stats.bankedgold = 10000 WHERE stats.id = $id4"); 
        // Payment has been made & successfully inserted into the Database        
       }else{       
        echo "Error code: 100"; 
        // E-mail admin or alert user 
       } 
      }else{ 
       echo "Error code: 130"; 
       // Payment made but data has been changed 
       // E-mail admin or alert user 
      }      

     }else if (strcmp ($res, "INVALID") == 0) { 
      echo "Error code: 170"; 
      // PAYMENT INVALID & INVESTIGATE MANUALY! 
      // E-mail admin or alert user 

      // Used for debugging 
      //@mail("[email protected]", "PAYPAL DEBUGGING", "Invalid  Response<br />data = <pre>".print_r($post, true)."</pre>"); 
     }  
    echo strcmp($res,"VERIFIED" == 0);  
fclose ($fp); 
} 

} 
} 

現在,$ RES給人的var_dump:

HTTP/1.1 200 OK 
Date: Mon, 02 Mar 2015 11:24:35 GMT 
Server: Apache X-Frame- 
Options: SAMEORIGIN 
Set-Cookie: <REDACTED_FOR_PRIVACY> 
Set-Cookie: navcmd=_notify-validate; domain=.paypal.com; path=/; Secure; HttpOnly 
Set-Cookie: navlns=0.0; expires=Wed, 01-Mar-2017 11:24:35 GMT; domain=.paypal.com; path=/; Secure; HttpOnly 
Set-Cookie: Apache=10.72.108.11.1425295475397401; path=/; expires=Wed, 22-Feb-45 11:24:35 GMT 
Vary: Accept-Encoding,User-Agent Connection: close 
Set-Cookie: <REDACTED_FOR_PRIVACY> 
Set-Cookie: X-PP-SILOVER=; Expires=Thu, 01 Jan 1970 00:00:01 GMT  
Set-Cookie: Apache=10.72.128.11.1425295475383817; path=/; expires=Wed, 22-Feb-45 11:24:35 GMT 
Strict-Transport-Security: max-age=14400 
Transfer-Encoding: chunked 
Content-Type: text/html; charset=UTF-8 8 

VERIFIED 0 

但我需要它說只是驗證或無效,所以我可以確定從那裏做什麼。

對我來說一個簡單的解決方法是添加「strpos」,只是看看它是否包含單詞,但我想向您的專家證實,這將是一個很好的解決方案?

回答

0

PayPal已經開始使用HTTP/1.1來發送其響應。這意味着,除其他外,您在回覆中獲得Transfer-Encoding: chunked

分塊編碼需要解析。典型地,它看起來像這樣:

8 
VERIFIED 

0 

翻譯,這給「長度的塊8 = VERIFIED ||長度0 =流的結尾的塊」

如果不能分析此響應,則可以嘗試通過在驗證響應中指定HTTP/1.0來強制PayPal不使用分塊編碼。或者,使用像cURL這樣的更好的庫來爲你解析 - PayPal的演示IPN代碼是爲PHP的一個非常舊的版本編寫的,或者至少有一個未啓用擴展。看起來程序員對http_build_query函數無知,無法正確編碼$req驗證數據,這真的讓人感到難過。你會認爲貝寶能買得起主管開發商*啊哈*但無論如何...我個人僅僅閱讀了Content-Length頭「解決」了 - 所有的貝寶可以把這裏有不同長度的響應。有點作弊,但它的工作。

希望這有助於:)

0

改變這一行:

$value = urlencode(stripslashes($value)); 

要這樣:

$value = urlencode($value); 

你只需要在那裏用stripslashes如果你捉迷藏PHP與魔術引號上。從PHP 5.4開始,這是(幸好)不再可能。

貝寶允許用戶數據包含反斜槓(我已經在address_street變量中的IPN數據中看到它)。如果你從IPN數據中去掉反斜槓,貝寶將返回一個INVALID響應。