在贝宝上使用 IPN

Using IPN on PayPal

我已经使用 PayPal 创建了一个结帐系统。我正在使用从 GitHub 获得的 IPN 的一些代码,并且我添加了一段代码以将商品标记为已售出库存,库存存储在网站的 MySQL 数据库中.

我已经测试了代码,我发现它执行了 CURL 并在 PayPal 端收到了一条消息,但是更新数据库的代码没有被执行。为了测试更新数据库的代码是否有效,我将其移至执行 CURL 之前。当我这样做时,代码 运行 和数据库已更新。所以,一定是有一个问题,在执行 CURL 时停止了代码。

这是 PayPal 将 IPN 发送到的页面的完整代码。

<?php 
// STEP 1: read POST data 
// Reading POSTed data directly from $_POST causes serialization issues with array data in the POST. 
// Instead, read raw POST data from the input stream.  
$raw_post_data = file_get_contents('php://input'); 
$raw_post_array = explode('&', $raw_post_data); 
$myPost = array(); 
foreach ($raw_post_array as $keyval) { 
  $keyval = explode ('=', $keyval); 
  if (count($keyval) == 2) {$myPost[$keyval[0]] = urldecode($keyval[1]);}
} 
// read the IPN message sent from PayPal and prepend 'cmd=_notify-validate' 
$req = 'cmd=_notify-validate'; 
if(function_exists('get_magic_quotes_gpc')) { 
  $get_magic_quotes_exists = true; 
}  
foreach ($myPost as $key => $value) {         
  if($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1) {  
    $value = urlencode(stripslashes($value));  
  } else { 
    $value = urlencode($value); 
  } 
  $req .= "&$key=$value"; 
} 

// STEP 2: POST IPN data back to PayPal to validate 
$ch = curl_init('https://www.paypal.com/cgi-bin/webscr'); 
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); 
curl_setopt($ch, CURLOPT_POST, 1); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); 
curl_setopt($ch, CURLOPT_POSTFIELDS, $req); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1); 
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); 
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1); 
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close')); 

// In wamp-like environments that do not come bundled with root authority certificates, 
// please download 'cacert.pem' from "http://curl.haxx.se/docs/caextract.html" and set  
// the directory path of the certificate as shown below: 
// curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__) . '/cacert.pem'); 
if(!($res = curl_exec($ch))) { 
  error_log("Got " . curl_error($ch) . " when processing IPN data"); 
  curl_close($ch); 
  exit; 
} 

// STEP 3: Inspect IPN validation result and act accordingly 
if (strcmp ($res, "VERIFIED") == 0) { 
  // The IPN is verified, process it: 
  // check whether 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 the notification 

  // assign posted variables to local variables 
  $item_number = $_POST['item_number']; 
  $item_name = $_POST['item_name']; 
  $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'];
  include('sql.php');
  mysqli_query($mysqli, $sql);
  $sql = "UPDATE inventory SET sold='1' WHERE code='".$item_number."'";
  if (mysqli_query($mysqli, $sql)) {
    foreach($_POST as $key => $value) { 
      echo $key." = ". $value."<br>"; 
    }
  }else{
    echo $mysqli->error;
  }
  mysqli_close($mysqli);

} else if (strcmp ($res, "INVALID") == 0) { 
  // IPN invalid, log for manual investigation 
  echo "The response from IPN was: <b>" .$res ."</b>"; 
} 
curl_close($ch);
?>

我真的是两周前才做的。屁股这么痛。这是我使用的:

function connectAPI($data, $location){

    $getData = array();
    foreach($data as $key=>$value){
        $getData[] = urlencode($key).'='.urlencode($value);
    }
    $location = $location . '?'.implode('&', $getData);

    $ch = curl_init($location);
    curl_setopt($ch,CURLOPT_USERAGENT,$_SERVER['HTTP_USER_AGENT']);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);


    $response = curl_exec($ch);

    $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);

    $return['status'] = $status;
    $return['response'] = $response;

    return $return;
}

$input = $_POST;
$headers = getallheaders();
$location = 'https://ipnpb.paypal.com/cgi-bin/webscr';
$response = array('cmd'=>'_notify-validate');
$jsondata = $response + $input;
$resend = connectAPI($jsondata, $location);

if($resend['response'] === 'VERIFIED'){

    // --- Do what you need to do.

}

echo $resend['response'];