如何解决PayPal IPN 有时不更新数据库
几个星期以来,PayPal 没有为某些交易更新我的数据库。也许 10 个事务中有 3 个被添加到数据库中。不知道发生了什么。在此之前,一切都很好。没有错误,PayPal 历史记录中的每笔交易都已完成。我不知道问题出在哪里。
这是我的 ipn.php
<?php
if (gethostbyaddr($_SERVER['REMOTE_ADDR']) !== 'notify.paypal.com') {
exit();
}
// Require the functions to connect to database and fetch config values
require 'config.php';
require 'db.php';
// Fetch and sanitize POST and GET values
function getValue($value) {
return (!empty($value)) ? sanitize($value) : false;
}
function sanitize($data) {
return htmlentities(strip_tags(mysql_znote_escape_string($data)));
}
function VerifyPaypalIPN(array $IPN = null){
if(empty($IPN)){
$IPN = $_POST;
}
if(empty($IPN['verify_sign'])){
return null;
}
$IPN['cmd'] = '_notify-validate';
$PaypalHost = (empty($IPN['test_ipn']) ? 'www' : 'www.sandbox').'.paypal.com';
$cURL = curl_init();
curl_setopt($cURL,CURLOPT_SSL_VERIFYPEER,1);
curl_setopt($cURL,CURLOPT_SSL_VERIFYHOST,2);
curl_setopt($cURL,CURLOPT_SSLVERSION,6);
curl_setopt($cURL,CURLOPT_CAINFO,__DIR__ . '/cert/cacert.pem');
curl_setopt($cURL,CURLOPT_URL,"https://{$PaypalHost}/cgi-bin/webscr");
curl_setopt($cURL,CURLOPT_ENCODING,'gzip');
curl_setopt($cURL,CURLOPT_BINARYTRANSFER,true);
curl_setopt($cURL,CURLOPT_POST,true); // POST back
curl_setopt($cURL,CURLOPT_POSTFIELDS,$IPN); // the $IPN
curl_setopt($cURL,CURLOPT_HEADER,false);
curl_setopt($cURL,CURLOPT_RETURNTRANSFER,CURLOPT_FORBID_REUSE,CURLOPT_FRESH_CONNECT,CURLOPT_CONNECTTIMEOUT,30);
curl_setopt($cURL,CURLOPT_TIMEOUT,60);
curl_setopt($cURL,CURLINFO_HEADER_OUT,CURLOPT_HTTPHEADER,array(
'Connection: close','Expect: ',));
$Response = curl_exec($cURL);
$Status = (int)curl_getinfo($cURL,CURLINFO_HTTP_CODE);
curl_close($cURL);
if(empty($Response) or !preg_match('~^(VERIFIED|INVALID)$~i',$Response = trim($Response)) or !$Status){
return null;
}
if(intval($Status / 100) != 2){
return false;
}
return !strcasecmp($Response,'VERIFIED');
}
// Fetch paypal configurations
$paypal = $config['paypal'];
$prices = $config['paypal_prices'];
// Send an empty HTTP 200 OK response to acknowledge receipt of the notification
header('HTTP/1.1 200 OK');
// Build the required acknowledgement message out of the notification just received
$req = 'cmd=_notify-validate';
foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}
$postdata = $req;
// Assign payment notification values 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 = getValue($_POST['txn_id']);
$receiver_email = getValue($_POST['receiver_email']);
$payer_email = getValue($_POST['payer_email']);
$custom = (int)$_POST['custom'];
$connectedIp = $_SERVER['REMOTE_ADDR'];
mysql_insert("INSERT INTO `paypal` VALUES ('0','$txn_id','Connection from IP: $connectedIp','0','0')");
$status = VerifyPaypalIPN();
if ($status) {
// Check that the payment_status is Completed
if ($payment_status == 'Completed') {
// Check that txn_id has not been previously processed
$txn_id_check = mysql_select_single("SELECT `txn_id` FROM `paypal` WHERE `txn_id`='$txn_id'");
if ($txn_id_check !== false) {
// Check that receiver_email is your Primary PayPal email
if ($receiver_email == $paypal['email']) {
$status = true;
$paidMoney = 0;
$paidPoints = 0;
foreach ($prices as $priceValue => $pointsValue) {
if ($priceValue == $payment_amount) {
$paidMoney = $priceValue;
$paidPoints = $pointsValue;
}
}
if ($paidMoney == 0) $status = false; // Wrong amount of money
if ($payment_currency != $paypal['currency']) $status = false; // Wrong currency
// Verify that the user haven't messed around with POST data
if ($status) {
// transaction log
mysql_insert("INSERT INTO `paypal` VALUES ('0','$payer_email','$custom','".$paidMoney."','".$paidPoints."')");
// Process payment
$data = mysql_select_single("SELECT `premium_points` AS `old_points` FROM `accounts` WHERE `id`='$custom';");
// Give points to user
$new_points = $data['old_points'] + $paidPoints;
mysql_update("UPDATE `accounts` SET `premium_points`='$new_points' WHERE `id`='$custom'");
}
} else {
$pmail = $paypal['email'];
mysql_insert("INSERT INTO `paypal` VALUES ('0','ERROR: Wrong mail. Received: $receiver_email,configured: $pmail','0')");
}
}
}
} else {
// Something is wrong
mysql_insert("INSERT INTO `paypal` VALUES ('0','ERROR: Invalid data. $postdata','0')");
}
?>
解决方法
您可以在 https://www.paypal.com/cgi-bin/webscr?cmd=_display-ipns-history
查看您帐户的 IPN 历史记录如果您收到了您期望的所有 IPN,那么您需要调试您的侦听器。添加日志记录以确定哪里出错了,例如无法回发以验证 IPN。记录所有内容以确定错误是什么。还要检查您的网络服务器日志。
有关 IPN 的文档位于:https://developer.paypal.com/docs/api-basics/notifications/ipn/
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。