IPN 页面仍然无法正常工作 PHP mysqli

IPN page still not working PHP mysqli

现在对此感到非常沮丧。完全按照 Paypal 指南操作,但仍然没有得到我需要的东西。

正在将 IPN 中的值插入数据库

这是分步指南:

1: Plan your IPN Solution for both backend and listener: Decide which language you are going to use and review the PayPal IPN listener code samples. Plan what backend tasks need to be done for each type of IPN message (IPN Transaction Types) received. 完成

使用 php 并将插入 txn_id、payment_status 和 user_id 以

开头

2: 实施并验证您的侦听器的 PayPal 请求-响应部分:仅创建您的侦听器的 PayPal 请求-响应部分以验证所需的握手是否有效,没有附加任何后端代码。] 完成

Using sample code that paypal provide from github

IPN 模拟器输出:


3:实现监听后端功能:暂时注释掉监听代码的请求-响应握手部分,因为它已经被验证为有效,然后实现并验证您的侦听器代码的后端部分正在运行。] 完成

使用此表单测试我的查询以插入数据库:

<form action="**********" method="POST">
  <input name="mc_gross" type="hidden" value="500.00" />
  <input name="custom" type="hidden" value="some custom data" />
  <input name="address_status" type="hidden" value="confirmed" />
  <input name="item_number1" type="hidden" value="6" />
  <input name="item_number2" type="hidden" value="4" />
  <input name="payer_id" type="hidden" value="FW5W7ZUC3T4KL" />
  <input name="tax" type="hidden" value="0.00" />
  <input name="address_street" type="hidden" value="1234 Rock Road" />
  <input name="payment_date" type="hidden" value="14:55 15 Jan 07 2005 PST" />
  <input name="payment_status" type="hidden" value="Completed" />
  <input name="address_zip" type="hidden" value="12345" />
  <input name="mc_shipping" type="hidden" value="0.00" />
  <input name="mc_handling" type="hidden" value="0.00" />
  <input name="first_name" type="hidden" value="Jason" />
  <input name="last_name" type="hidden" value="Anderson" />
  <input name="mc_fee" type="hidden" value="0.02" />
  <input name="address_name" type="hidden" value="Jason Anderson" />
  <input name="notify_version" type="hidden" value="1.6" />
  <input name="payer_status" type="hidden" value="verified" />
  <input name="business" type="hidden" value="paypal@emailaddress.com" />
  <input name="address_country" type="hidden" value="United States" />
  <input name="num_cart_items" type="hidden" value="2" />
  <input name="mc_handling1" type="hidden" value="0.00" />
  <input name="mc_handling2" type="hidden" value="0.00" />
  <input name="address_city" type="hidden" value="Los Angeles" />
  <input name="verify_sign" type="hidden" value="AlUbUcinRR5pIo2KwP4xjo9OxxHMAi6.s6AES.4Z6C65yv1Ob2eNqrHm" />
  <input name="mc_shipping1" type="hidden" value="0.00" />
  <input name="mc_shipping2" type="hidden" value="0.00" />
  <input name="tax1" type="hidden" value="0.00" />
  <input name="tax2" type="hidden" value="0.00" />
  <input name="txn_id" type="hidden" value="TESTER" />
  <input name="payment_type" type="hidden" value="instant" />
  <input name="last_name=Borduin" type="hidden" />
  <input name="payer_email" type="hidden" value="test@domain.com" />
  <input name="item_name1" type="hidden" value="Rubber+clog" />
  <input name="address_state" type="hidden" value="CA" />
  <input name="payment_fee" type="hidden" value="0.02" />
  <input name="item_name2" type="hidden" value="Roman sandal" />
  <input name="invoice" type="hidden" value="123456" />
  <input name="quantity" type="hidden" value="1" />
  <input name="quantity1" type="hidden" value="1" />
  <input name="receiver_id" type="hidden" value="5HRS8SCK9NSJ2" />
  <input name="quantity2" type="hidden" value="1" />
  <input name="txn_type" type="hidden" value="web_accept" />
  <input name="mc_gross_1" type="hidden" value="0.01" />
  <input name="mc_currency" type="hidden" value="USD" />
  <input name="mc_gross_2" type="hidden" value="0.01" />
  <input name="payment_gross" type="hidden" value="0.02" />
  <input name="subscr_id" type="hidden" value="PP-1234" />
  <input name="test" type="submit" value="test" />
</form>

效果很好

4: 测试侦听器:取消注释请求-响应代码以测试和验证请求-响应握手和后端进程是否按预期使用各种不同的方式协同工作推荐的 IPN 测试方法级别,包括 PayPal 沙箱环境和 IPN 模拟器工具。 不完整

将查询和示例代码放在一起但没有插入到数据库中

这是我的 IPN 侦听器代码:

<?php
include 'connect.php'
// CONFIG: Enable debug mode. This means we'll log requests into 'ipn.log' in the same directory.
// Especially useful if you encounter network errors or other intermittent problems with IPN (validation).
// Set this to 0 once you go live or don't require logging.
define("DEBUG", 1);
// Set to 0 once you're ready to go live
define("USE_SANDBOX", 1);
define("LOG_FILE", "./ipn.log");
// Read POST data
// reading posted data directly from $_POST causes serialization
// issues with array data in POST. Reading raw POST data from input stream instead.
$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 post from PayPal system and add 'cmd'
$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";
}
// Post IPN data back to PayPal to validate the IPN data is genuine
// Without this step anyone can fake IPN data
if(USE_SANDBOX == true) {
    $paypal_url = "https://www.sandbox.paypal.com/cgi-bin/webscr";
} else {
    $paypal_url = "https://www.paypal.com/cgi-bin/webscr";
}
$ch = curl_init($paypal_url);
if ($ch == FALSE) {
    return FALSE;
}
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);
if(DEBUG == true) {
    curl_setopt($ch, CURLOPT_HEADER, 1);
    curl_setopt($ch, CURLINFO_HEADER_OUT, 1);
}
// CONFIG: Optional proxy configuration
//curl_setopt($ch, CURLOPT_PROXY, $proxy);
//curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);
// Set TCP timeout to 30 seconds
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));
// CONFIG: Please download 'cacert.pem' from "http://curl.haxx.se/docs/caextract.html" and set the directory path
// of the certificate as shown below. Ensure the file is readable by the webserver.
// This is mandatory for some environments.
//$cert = __DIR__ . "./cacert.pem";
//curl_setopt($ch, CURLOPT_CAINFO, $cert);
$res = curl_exec($ch);
if (curl_errno($ch) != 0) // cURL error
    {
    if(DEBUG == true) { 
        error_log(date('[Y-m-d H:i e] '). "Can't connect to PayPal to validate IPN message: " . curl_error($ch) . PHP_EOL, 3, LOG_FILE);
    }
    curl_close($ch);
    exit;
} else {
        // Log the entire HTTP response if debug is switched on.
        if(DEBUG == true) {
            error_log(date('[Y-m-d H:i e] '). "HTTP request of validation request:". curl_getinfo($ch, CURLINFO_HEADER_OUT) ." for IPN payload: $req" . PHP_EOL, 3, LOG_FILE);
            error_log(date('[Y-m-d H:i e] '). "HTTP response of validation request: $res" . PHP_EOL, 3, LOG_FILE);
        }
        curl_close($ch);
}
// Inspect IPN validation result and act accordingly
// Split response headers and payload, a better way for strcmp
$tokens = explode("\r\n\r\n", trim($res));
$res = trim(end($tokens));
if (strcmp ($res, "VERIFIED") == 0) {
    // check whether the payment_status is Completed
    // check that txn_id has not been previously processed
    // check that receiver_email is your PayPal email
    // check that payment_amount/payment_currency are correct
    // process payment and mark item as paid.
    // 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'];
    $id = $_POST['custom'];

        if($payment_status=="Completed"){
        $txn_id_check = $mysqli->query("SELECT `transaction_id` FROM `payment` WHERE `transaction_id`='$txn_id'");;
        if($txn_id_check->num_rows != 1) {  
                    $query = "INSERT INTO `payment` (`transaction_id`, `payment_status`, `users_id`) VALUES(?, ?, ?)";
                    $statement = $mysqli->prepare($query);
                    $statement->bind_param('ssi',$txn_id, $payment_status, $id);
                    if($statement->execute()){
                    print 'Success! ID of last inserted record is : ' .$statement->insert_id .'<br />'; 
                    }else{
                    die('Error : ('. $mysqli->errno .') '. $mysqli->error);
                    }
                    $statement->close();
        }
    }
    if(DEBUG == true) {
        error_log(date('[Y-m-d H:i e] '). "Verified IPN: $req ". PHP_EOL, 3, LOG_FILE);
    }
} else if (strcmp ($res, "INVALID") == 0) {
    // log for manual investigation
    // Add business logic here which deals with invalid IPN messages
    if(DEBUG == true) {
        error_log(date('[Y-m-d H:i e] '). "Invalid IPN: $req" . PHP_EOL, 3, LOG_FILE);
    }
}
?>

我也遵循了本指南on how to create an IPN page,但仍然存在相同的结果

注意,这是我在 1 个模拟 IPN 后的 ipn.log 文件:

[2015-10-21 13:49 America/Chicago] HTTP request of validation request:POST /cgi-bin/webscr HTTP/1.1
Host: www.sandbox.paypal.com
Accept: */*
Connection: Close
Content-Length: 882
Content-Type: application/x-www-form-urlencoded

 for IPN payload: cmd=_notify-validate&payment_type=echeck&payment_date=Wed+Oct+21+2015+19%3A14%3A37+GMT%2B0100+%28GMT+Summer+Time%29&payment_status=Completed&address_status=confirmed&payer_status=verified&first_name=John&last_name=Smith&payer_email=buyer%40paypalsandbox.com&payer_id=TESTBUYERID01&address_name=John+Smith&address_country=United+States&address_country_code=US&address_zip=95131&address_state=CA&address_city=San+Jose&address_street=123+any+street&business=seller%40paypalsandbox.com&receiver_email=seller%40paypalsandbox.com&receiver_id=seller%40paypalsandbox.com&residence_country=US&item_name=something&item_number=AK-1234&quantity=1&shipping=3.04&tax=2.02&mc_currency=USD&mc_fee=0.44&mc_gross=12.34&mc_gross1=12.34&txn_type=web_accept&txn_id=602383467&notify_version=2.1&custom=xyz123&invoice=abc1234&test_ipn=1&verify_sign=AFcWxV21C7fd0v3bYYYRCpSSRl31AhVMpD1906o6kD2.tixEm-LUc.gf
[2015-10-21 13:49 America/Chicago] HTTP response of validation request: HTTP/1.1 200 OK
Date: Wed, 21 Oct 2015 18:49:22 GMT
Server: Apache
X-Frame-Options: SAMEORIGIN
Set-Cookie: c9MWDuvPtT9GIMyPc3jwol1VSlO=e1HUZ1OWMNI1uP_J_wM_lNec93JAFurXcAwAzN1nuotTGpdRkUHMUn__h3D2JJuFN3K_6r8CLlTouCQd7MC07PjGHuLIJnpobt6AT6qTUJianiXIibJ8pMpfXC1mWpnYWZ4TF5ydp6hbjHvgj2oe0xsNSQD_IJ_ChEZqvi9EDAQZvpJJAw7HBIyrRNnEDUfsOr_M-sPRIHNQNXc0XdgNaHrWmozcxuSgUxocug7ClZKjoPymv8tqm8My5LMoZlQoMMaVoNFyptiymVktHNkRcO9cYi-aPI4ymcTb8iGWHLDHR9Sxte04ae7ap05Qi7dGj79RAGaYJAvDUOAOSjmFlfyM4qStFz2NFwi3WsVIZe4J-kPZR7ZlwkhlJyq82i5iM8otsWuSUYp9G5cJyrt7u7Cc8hYDDLAEx7cqfj7TR3LzBNcIHktt7Aye4yC; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: cookie_check=yes; expires=Sat, 18-Oct-2025 18:49:22 GMT; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: navcmd=_notify-validate; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: navlns=0.0; expires=Fri, 20-Oct-2017 18:49:22 GMT; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: Apache=10.72.108.11.1445453362642214; path=/; expires=Fri, 13-Oct-45 18:49:22 GMT
Vary: Accept-Encoding,User-Agent
Connection: close
Paypal-Debug-Id: 892222cc992c5
Set-Cookie: X-PP-SILOVER=name%3DSANDBOX3.WEB.1%26silo_version%3D880%26app%3Dappdispatcher%26TIME%3D853419862; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: X-PP-SILOVER=; Expires=Thu, 01 Jan 1970 00:00:01 GMT
Set-Cookie: Apache=10.72.128.11.1445453362627267; path=/; expires=Fri, 13-Oct-45 18:49:22 GMT
Strict-Transport-Security: max-age=14400
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8

VERIFIED
[2015-10-21 13:49 America/Chicago] Verified IPN: cmd=_notify-validate&payment_type=echeck&payment_date=Wed+Oct+21+2015+19%3A14%3A37+GMT%2B0100+%28GMT+Summer+Time%29&payment_status=Completed&address_status=confirmed&payer_status=verified&first_name=John&last_name=Smith&payer_email=buyer%40paypalsandbox.com&payer_id=TESTBUYERID01&address_name=John+Smith&address_country=United+States&address_country_code=US&address_zip=95131&address_state=CA&address_city=San+Jose&address_street=123+any+street&business=seller%40paypalsandbox.com&receiver_email=seller%40paypalsandbox.com&receiver_id=seller%40paypalsandbox.com&residence_country=US&item_name=something&item_number=AK-1234&quantity=1&shipping=3.04&tax=2.02&mc_currency=USD&mc_fee=0.44&mc_gross=12.34&mc_gross1=12.34&txn_type=web_accept&txn_id=602383467&notify_version=2.1&custom=xyz123&invoice=abc1234&test_ipn=1&verify_sign=AFcWxV21C7fd0v3bYYYRCpSSRl31AhVMpD1906o6kD2.tixEm-LUc.gf 

我使用电子邮件错误处理来检查我做错了什么

function error_handler($number,$message,$file,$line,$vars){

    $email = "<p>An error ($number) occured on line <strong>$line</strong> and in the file:
    $file.<p>$message</p>";
    $email .= "<pre>" . print_r($vars) . "</pre>";
    $headers = 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
    error_log($email, 1, 'myemail@gmail.com', $headers);
}

set_error_handler('error_handler');

然后它告诉我我少了一个分号

inlude 'connect.php'

所以

包括 'connect.php';

我这里有两个分号:

("SELECT `transaction_id` FROM `payment` WHERE `transaction_id`='$txn_id'");;

所以

 ("SELECT `transaction_id` FROM `payment` WHERE `transaction_id`='$txn_id'");