2015-03-02 127 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响应。