简体   繁体   English

在PayPal上使用IPN

[英]Using IPN on PayPal

I've created a checkout system using PayPal. 我使用PayPal创建了一个结帐系统。 I'm using some code for the IPN that I got from GitHub, and I've added a piece of code to mark the item as sold in the inventory, which is stored in the website's MySQL database. 我正在使用从GitHub获得的IPN的一些代码,并且添加了一段代码以将该商品标记为库存中出售的商品,该商品存储在网站的MySQL数据库中。

I have tested the code, and I have found that it carries out the CURL and a message is received at PayPal's end, but the code to update the database wasn't being executed. 我已经测试了代码,发现它执行了CURL,并且在PayPal的末尾收到了一条消息,但是未执行更新数据库的代码。 To test that the code to update the database worked, I moved it to before when the CURL is carried out. 为了测试更新数据库的代码是否有效,我将其移至执行CURL之前的位置。 When I did this, the code ran, and the database was updated. 当我这样做时,代码开始运行,并且数据库已更新。 So, there must be an issue that stops the code when the CURL is executed. 因此,必须存在一个问题,当执行CURL时会停止代码。

This is the entire code from the page that PayPal sends the IPN to. 这是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);
?>

I literally just did this two weeks ago. 我实际上只是在两周前做了这个。 Such a pain in the butt. 屁股这么疼。 Here's what I used: 这是我使用的:

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'];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM