php - IPN 页面仍然无法工作 PHP mysqli

标签 php mysql mysqli paypal paypal-ipn

现在对此感到非常沮丧。完全按照 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 模拟器输出: enter image description here

<小时/>

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 Sandbox环境和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'");

关于php - IPN 页面仍然无法工作 PHP mysqli,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33224793/

相关文章:

php - 如何创建 PHP 多重插入?

PHP 获取参数值的安全性

php - 在PHP页面上显示泰语字符/泰语字符可以在服务器的数据库中显示

PHP 文件上传无法正常使用,如何解决?

php - 需要 PHP 和 MySQL 保存游戏进度的反馈

php - 2个表,3列需要1个值

phpMailer - 你如何删除收件人

php - 使用搜索文本框加载更多结果

MySQL 5.7 (RHEL6.6) 使用 AD 进行 PAM 身份验证

php - 关于 Prepared Statements 的几个问题