2012-02-14 56 views
0

如果我检查的详细信息不正确,我希望能够停止交易。如何停止IPN内的PayPal交易?

我的代码

// check that receiver_email is your Primary PayPal email 
if($_POST['receiver_email'] != "[email protected]") { 
exit(); // exit script 
} 

我用exit()一个例子,但在测试这个使用sandbox.paypal.com当电子邮件是不正确的,exit()被称为交易仍会处理并在本质上给出了沙盒帐户的钱。

+4

我不是专家,但我不认为你可以完全停止交易。 IPN意味着即时付款*通知*,意味着交易已经发生 – 2012-02-14 01:05:45

+1

通常它到达您的IPN,它可能*已被处理*,除非它是eCheck或其他东西。这不是“此交易已开始”的通知,而是“您已收到此笔交易的金钱”。 – animuson 2012-02-14 01:06:26

+0

@animuson这是一个公平点,但我的IPN也检查_POST数据与存储在我的数据库中的数据。所以如果有人试图在我的网站上进行一些价格上涨,那么这里就会被检查。所以不接受付款是有意义的。 – 2012-02-14 01:10:15

回答

1

如上所述,这当然是可能的。理想情况下,您需要从IPN处理程序中卸载任何处理,以便IPN处理程序可以专注于从PayPal接收POST数据。
但您可以使用以下方式检查付款金额是否与预期金额相符,并在金额不同时自动退款。

例如(基于PayPal PHP示例代码,并很快抛在一起)。 注意:此代码仅用于说明背后的逻辑。

<?php 

// Set this dynamically. 
$amountToBeExpected = "0.99"; 


// PHP 4.1 

// read the post from PayPal system and add 'cmd' 
$req = 'cmd=_notify-validate'; 

foreach ($_POST as $key => $value) { 
$value = urlencode(stripslashes($value)); 
$req .= "&$key=$value"; 
} 

// post back to PayPal system to validate 
$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"; 
$fp = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30); 

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

if (!$fp) { 
// HTTP ERROR 
} else { 
fputs ($fp, $header . $req); 
while (!feof($fp)) { 
$res = fgets ($fp, 1024); 
if (strcmp ($res, "VERIFIED") == 0) { 
// check the payment_status is Completed 
// check that txn_id has not been previously processed 
// check that receiver_email is your Primary PayPal email 
// check that payment_amount/payment_currency are correct 
// process payment 


    if($payment_amount != $amountToBeExpected) { 
     /** RefundTransaction NVP example; last modified 08MAY23. 
     * 
     * Issue a refund for a prior transaction. 
     */ 

     $environment = 'sandbox'; // or 'beta-sandbox' or 'live' 

     /** 
     * Send HTTP POST Request 
     * 
     * @param string The API method name 
     * @param string The POST Message fields in &name=value pair format 
     * @return array Parsed HTTP Response body 
     */ 
     function PPHttpPost($methodName_, $nvpStr_) { 
      global $environment; 

      // Set up your API credentials, PayPal end point, and API version. 
      $API_UserName = urlencode('my_api_username'); 
      $API_Password = urlencode('my_api_password'); 
      $API_Signature = urlencode('my_api_signature'); 
      $API_Endpoint = "https://api-3t.paypal.com/nvp"; 
      if("sandbox" === $environment || "beta-sandbox" === $environment) { 
       $API_Endpoint = "https://api-3t.$environment.paypal.com/nvp"; 
      } 
      $version = urlencode('51.0'); 

      // Set the curl parameters. 
      $ch = curl_init(); 
      curl_setopt($ch, CURLOPT_URL, $API_Endpoint); 
      curl_setopt($ch, CURLOPT_VERBOSE, 1); 

      // Turn off the server and peer verification (TrustManager Concept). 
      curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 
      curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); 

      curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
      curl_setopt($ch, CURLOPT_POST, 1); 

      // Set the API operation, version, and API signature in the request. 
      $nvpreq = "METHOD=$methodName_&VERSION=$version&PWD=$API_Password&USER=$API_UserName&SIGNATURE=$API_Signature$nvpStr_"; 

      // Set the request as a POST FIELD for curl. 
      curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq); 

      // Get response from the server. 
      $httpResponse = curl_exec($ch); 

      if(!$httpResponse) { 
       exit("$methodName_ failed: ".curl_error($ch).'('.curl_errno($ch).')'); 
      } 

      // Extract the response details. 
      $httpResponseAr = explode("&", $httpResponse); 

      $httpParsedResponseAr = array(); 
      foreach ($httpResponseAr as $i => $value) { 
       $tmpAr = explode("=", $value); 
       if(sizeof($tmpAr) > 1) { 
        $httpParsedResponseAr[$tmpAr[0]] = $tmpAr[1]; 
       } 
      } 

      if((0 == sizeof($httpParsedResponseAr)) || !array_key_exists('ACK', $httpParsedResponseAr)) { 
       exit("Invalid HTTP Response for POST request($nvpreq) to $API_Endpoint."); 
      } 

      return $httpParsedResponseAr; 
     } 

     // Set request-specific fields. 
     $transactionID = urlencode($txn_id); 
     $refundType = urlencode('Full');      // or 'Partial' 
     //$amount;            // required if Partial. 
     //$memo;             // required if Partial. 
     $currencyID = urlencode('USD');       // or other currency ('GBP', 'EUR', 'JPY', 'CAD', 'AUD') 

     // Add request-specific fields to the request string. 
     $nvpStr = "&TRANSACTIONID=$transactionID&REFUNDTYPE=$refundType&CURRENCYCODE=$currencyID"; 

     if(isset($memo)) { 
      $nvpStr .= "&NOTE=$memo"; 
     } 

     if(strcasecmp($refundType, 'Partial') == 0) { 
      if(!isset($amount)) { 
       exit('Partial Refund Amount is not specified.'); 
      } else { 
       $nvpStr = $nvpStr."&AMT=$amount"; 
      } 

      if(!isset($memo)) { 
       exit('Partial Refund Memo is not specified.'); 
      } 
     } 

     // Execute the API operation; see the PPHttpPost function above. 
     $httpParsedResponseAr = PPHttpPost('RefundTransaction', $nvpStr); 

     if("SUCCESS" == strtoupper($httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr["ACK"])) { 
      exit('Refund Completed Successfully: '.print_r($httpParsedResponseAr, true)); 
     } else { 
      exit('RefundTransaction failed: ' . print_r($httpParsedResponseAr, true)); 
     } 



    } 



} 
else if (strcmp ($res, "INVALID") == 0) { 

} 
} 
fclose ($fp); 
} 
?>