2012-02-14 95 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); 
} 
?>