2015-07-03 44 views
0

我是小白贝宝和PHP,所以我跟着这个教程在线:https://www.developphp.com/video/PHP/PayPal-IPN-PHP-Instant-Payment-Notification-Script贝宝IPN没有连接到我的数据库中插入交易

我的问题是,我的IPN结果都不错,但我ipn.php脚本将不会连接到我的数据库,以便我可以存储结果。

IPN.PHP CODE

<?php 
//connect to the database 
    include_once ('includes/connect_to_mysql.php'); 
// Check to see there are posted variables coming into the script 
if ($_SERVER['REQUEST_METHOD'] != "POST") die ("No Post Variables"); 
// Initialize the $req variable and add CMD key value pair 
$req = 'cmd=_notify-validate'; 
// Read the post from PayPal 
foreach ($_POST as $key => $value) { 
    $value = urlencode(stripslashes($value)); 
    $req .= "&$key=$value"; 
} 
// Now Post all of that back to PayPal's server using curl, and validate everything with PayPal 
// We will use CURL instead of PHP for this for a more universally operable script (fsockopen has issues on some environments) 
$url = "https://www.sandbox.paypal.com/cgi-bin/webscr"; //USE SANDBOX ACCOUNT TO TEST WITH 
//$url = "https://www.paypal.com/cgi-bin/webscr"; //LIVE ACCOUNT 
$curl_result=$curl_err=''; 
$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL,$url); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); 
curl_setopt($ch, CURLOPT_POST, 1); 
curl_setopt($ch, CURLOPT_POSTFIELDS, $req); 
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/x-www-form-urlencoded", "Content-Length: " . strlen($req))); 
curl_setopt($ch, CURLOPT_HEADER , 0); 
curl_setopt($ch, CURLOPT_VERBOSE, 1); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 
curl_setopt($ch, CURLOPT_TIMEOUT, 30); 
$curl_result = @curl_exec($ch); 
$curl_err = curl_error($ch); 
curl_close($ch); 

$req = str_replace("&", "\n", $req); // Make it a nice list in case we want to email it to ourselves for reporting 

// Check that the result verifies with PayPal 
if (strpos($curl_result, "VERIFIED") !== false) { 
    $req .= "\n\nPaypal Verified OK"; 
    mail("[email protected]", "Verified OK", "$req", "From: [email protected]"); 
} else { 
    $req .= "\n\nData NOT verified from Paypal!"; 
    mail("[email protected]", "IPN interaction not verified", "$req", "From: [email protected]"); 
    exit(); 
} 

/* CHECK THESE 4 THINGS BEFORE PROCESSING THE TRANSACTION, HANDLE THEM AS YOU WISH 
1. Make sure that business email returned is your business email 
2. Make sure that the transaction’s payment status is “completed” 
3. Make sure there are no duplicate txn_id 
4. Make sure the payment amount matches what you charge for items. (Defeat Price-Jacking) */ 

// Check Number 1 ------------------------------------------------------------------------------------------------------------ 
$receiver_email = $_POST['receiver_email']; 
if ($receiver_email != "[email protected]") { 
    $message = "Investigate why and how receiver_email variable sent back by PayPal does not match the buisness email set in   cart.php. Email = " . $_POST['receiver_email'] . "\n\n\n$req"; 
    mail("[email protected]", "Receiver Email is incorrect", $message, "From: [email protected]"); 
    exit(); // exit script 
} 
// Check number 2 ------------------------------------------------------------------------------------------------------------ 
if ($_POST['payment_status'] != "Completed") { 
    // Handle how you think you should if a payment is not complete yet, a few scenarios can cause a transaction to be incomplete 
    $message = "Investigate why payment was not completed. Email = " . $_POST['receiver_email'] . "\n\n\n$req"; 
    mail("[email protected]", "Payment not complete", $message, "From: [email protected]"); 
    exit(); // exit script 
} 
// Check number 3 ------------------------------------------------------------------------------------------------------------ 
$this_txn = $_POST['txn_id']; 
$sql = mysqli_query($conn, "SELECT id FROM transactions WHERE txn_id='$this_txn' LIMIT 1"); //check to see transaction id exists in the DB 
$numRows = mysqli_num_rows($sql); 
if ($numRows == 0) { 
    $message = "Duplicate transaction ID occured so we killed the IPN script. \n\n\n$req"; 
    mail("[email protected]", "Duplicate transaction ID(txn_id) in the IPN system", $message, "From: [email protected]"); 
    exit(); // exit script 
} 
// Check number 4 ------------------------------------------------------------------------------------------------------------ 
$product_id_string = $_POST['custom']; 
$product_id_string = rtrim($product_id_string, ","); // remove last comma 
// Explode the string, make it an array, then query all the prices out, add them up, and make sure they match the payment_gross amount 
$id_str_array = explode(",", $product_id_string); // Uses Comma(,) as delimiter(break point) 
$fullAmount = 0; 
foreach ($id_str_array as $key => $value) { 

    $id_quantity_pair = explode("-", $value); // Uses Hyphen(-) as delimiter to separate product ID from its quantity 
    $product_id = $id_quantity_pair[0]; // Get the product ID 
    $product_quantity = $id_quantity_pair[1]; // Get the quantity 
    $sql = mysqli_query($conn, "SELECT price FROM products WHERE id='$product_id' LIMIT 1"); 
    while($row = mysqli_fetch_array($sql)){ 
     $product_price = $row["price"]; 
    } 
    $product_price = $product_price * $product_quantity; 
    $fullAmount = $fullAmount + $product_price; 
} 
$fullAmount = number_format($fullAmount, 2); 
$grossAmount = $_POST['mc_gross']; 
if ($fullAmount != $grossAmount) { 
     $message = "Possible Price Jack: " . $_POST['mc_gross'] . " != $fullAmount \n\n\n$req"; 
     mail("[email protected]", "Price Jack or Bad Programming", $message, "From: [email protected]"); 
     exit(); // exit script 
} 
// END ALL SECURITY CHECKS NOW IN THE DATABASE IT GOES ------------------------------------ 
//////////////////////////////////////////////////// 
// Assign local variables from the POST PayPal variables 
$custom = $_POST['custom']; 
$payer_email = $_POST['payer_email']; 
$first_name = $_POST['first_name']; 
$last_name = $_POST['last_name']; 
$payment_date = $_POST['payment_date']; 
$mc_gross = $_POST['mc_gross']; 
$payment_currency = $_POST['payment_currency']; 
$txn_id = $_POST['txn_id']; 
$receiver_email = $_POST['receiver_email']; 
$payment_type = $_POST['payment_type']; 
$payment_status = $_POST['payment_status']; 
$txn_type = $_POST['txn_type']; 
$payer_status = $_POST['payer_status']; 
$address_street = $_POST['address_street']; 
$address_city = $_POST['address_city']; 
$address_state = $_POST['address_state']; 
$address_zip = $_POST['address_zip']; 
$address_country = $_POST['address_country']; 
$address_status = $_POST['address_status']; 
$notify_version = $_POST['notify_version']; 
$verify_sign = $_POST['verify_sign']; 
$payer_id = $_POST['payer_id']; 
$mc_currency = $_POST['mc_currency']; 
$mc_fee = $_POST['mc_fee']; 

// Place the transaction into the database 
$sql = mysqli_query($conn, "INSERT INTO transactions (product_id_array, payer_email, first_name, last_name, payment_date, mc_gross, payment_currency, txn_id, receiver_email, payment_type, payment_status, txn_type, payer_status, address_street, address_city, address_state, address_zip, address_country, address_status, notify_version, verify_sign, payer_id, mc_currency, mc_fee) 
    VALUES('$custom','$payer_email','$first_name','$last_name','$payment_date','$mc_gross','$payment_currency','$txn_id','$receiver_email','$payment_type','$payment_status','$txn_type','$payer_status','$address_street','$address_city','$address_state','$address_zip','$address_country','$address_status','$notify_version','$verify_sign','$payer_id','$mc_currency','$mc_fee')") or die ("unable to execute the query"); 

mysqli_close(); 
// Mail yourself the details 
mail("[email protected]", "NORMAL IPN RESULT - Transaction Entered", $req, "From: [email protected]"); 
?> 

测试时我给自己用的验证和PAYMENT_STATUS =完成了其返回的IPN结果的电子邮件。

这里是IPN输出:

cmd=_notify-validate 
mc_gross=9.99 
protection_eligibility=Eligible 
address_status=confirmed 
item_number1= 
payer_id=BDK3Z8X34KY3Y 
tax=0.00 
address_street=1+Maire-Victorin 
payment_date=13%3A51%3A16+Jul+06%2C+2015+PDT 
payment_status=Completed 
charset=windows-1252 
address_zip=M5A+1E1 
mc_shipping=0.00 
mc_handling=0.00 
first_name=test 
mc_fee=0.59 
address_country_code=CA 
address_name=test+buyer 
notify_version=3.8 
custom=9-1%2C 
payer_status=verified 
business=email-facilitator%40hotmail.com 
address_country=Canada 
num_cart_items=1 
mc_handling1=0.00 
address_city=Toronto 
verify_sign=A2YnYs6LuOd-R8BHIdbWTA6xHgalAu.DiwxDdytu5YxLaIvebtzbprOA 
payer_email=email-buyer%40hotmail.com 
mc_shipping1=0.00 
tax1=0.00 
txn_id=6HE31475W2614530U 
payment_type=instant 
last_name=buyer 
address_state=Ontario 
item_name1=Leather+Pouch 
receiver_email=email-facilitator%40hotmail.com 
payment_fee= 
quantity1=1 
receiver_id=SF4CCTMHQJMF8 
txn_type=cart 
mc_gross_1=9.99 
mc_currency=CAD 
residence_country=CA 
test_ipn=1 
transaction_subject=9-1%2C 
payment_gross= 
ipn_track_id=a7531c2eb1cec 

Paypal Verified OK 

我进一步调试的代码到一个事实,即我的select语句没有返回这对我表示到数据库连接后没有任何价值。

任何人都可以帮助我,为什么我不能使用ipn.php代码连接到我的数据库?我的网站的所有其他页面将使用除此页面以外的相同代码进行连接,因此我只能认为它与PayPal呼叫此页面而不是我的服务器有关。

这里是connect_to_mysql.php我的连接代码:

<?php 
/* PHP Database Connection */ 
$servername = "localhost"; 
$username = "user"; 
$password = "passs"; 
$database = "database"; 

// Create connection 
$conn = mysqli_connect($servername, $username, $password, $database); 

// Check connection 
if (!$conn) { 
    die("Connection failed: " . mysqli_connect_error()); 
} 
echo "Connected successfully"; 
?> 
+0

mysql已弃用。使用mysqli或PDO。 –

+0

是的,谢谢。一旦所有设置和工作都完成,我打算切换到mysqli,以免使调试过程复杂化。 – Neeeewb

回答

0

我解决了这个问题。我需要将所有查询切换到Mysqli版本而不是旧的Mysql。下面的固定代码:

<?php 
// Report all PHP errors 
ini_set('error_reporting', E_ALL); 

// Destinations 
define("ADMIN_EMAIL", "[email protected]"); 

// Destination types 
define("DEST_EMAIL", "1"); 

/* PHP Database Connection */ 
$servername = "localhost"; 
$username = "aesirleatherworks"; 
$password = ""; 
$database = "my_aesirleatherworks"; 

// Create connection 
$conn = mysqli_connect($servername, $username, $password, $database); 


// Send an e-mail to the administrator if connection fails 
if (!$conn) { 
     error_log("Failed to connect to MYSQL ".mysqli_connect_error(), DEST_EMAIL, ADMIN_EMAIL); 
    } 

// Check to see there are posted variables coming into the script 
if ($_SERVER['REQUEST_METHOD'] != "POST") die ("No Post Variables"); 
// Initialize the $req variable and add CMD key value pair 
$req = 'cmd=_notify-validate'; 
// Read the post from PayPal 
foreach ($_POST as $key => $value) { 
    $value = urlencode(stripslashes($value)); 
    $req .= "&$key=$value"; 
} 
// Now Post all of that back to PayPal's server using curl, and validate everything with PayPal 
// We will use CURL instead of PHP for this for a more universally operable script (fsockopen has issues on some environments) 
$url = "https://www.sandbox.paypal.com/cgi-bin/webscr"; //USE SANDBOX ACCOUNT TO TEST WITH 
//$url = "https://www.paypal.com/cgi-bin/webscr"; //LIVE ACCOUNT 
$curl_result=$curl_err=''; 
$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL,$url); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); 
curl_setopt($ch, CURLOPT_POST, 1); 
curl_setopt($ch, CURLOPT_POSTFIELDS, $req); 
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/x-www-form-urlencoded", "Content-Length: " . strlen($req))); 
curl_setopt($ch, CURLOPT_HEADER , 0); 
curl_setopt($ch, CURLOPT_VERBOSE, 1); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 
curl_setopt($ch, CURLOPT_TIMEOUT, 30); 
$curl_result = @curl_exec($ch); 
$curl_err = curl_error($ch); 
curl_close($ch); 

$req = str_replace("&", "\n", $req); // Make it a nice list in case we want to email it to ourselves for reporting 

// Check that the result verifies with PayPal 
if (strpos($curl_result, "VERIFIED") !== false) { 
    $req .= "\n\nPaypal Verified OK"; 
} else { 
    $req .= "\n\nData NOT verified from Paypal!"; 
    mail("[email protected]", "IPN interaction not verified", "$req", "From: [email protected]"); 
    exit(); 
} 

/* CHECK THESE 4 THINGS BEFORE PROCESSING THE TRANSACTION, HANDLE THEM AS YOU WISH 
1. Make sure that business email returned is your business email 
2. Make sure that the transaction’s payment status is “completed” 
3. Make sure there are no duplicate txn_id 
4. Make sure the payment amount matches what you charge for items. (Defeat Price-Jacking) */ 

// Check Number 1 ------------------------------------------------------------------------------------------------------------ 
$receiver_email = $_POST['receiver_email']; 
if ($receiver_email != "[email protected]") { 
    $message = "Investigate why and how receiver_email variable sent back by PayPal does not match the buisness email set in   cart.php. Email = " . $_POST['receiver_email'] . "\n\n\n$req"; 
    mail("[email protected]", "Receiver Email is incorrect", $message, "From: [email protected]"); 
    exit(); // exit script 
} 
// Check number 2 ------------------------------------------------------------------------------------------------------------ 
if ($_POST['payment_status'] != "Completed") { 
    // Handle how you think you should if a payment is not complete yet, a few scenarios can cause a transaction to be incomplete 
    $message = "Investigate why payment was not completed. Email = " . $_POST['receiver_email'] . "\n\n\n$req"; 
    mail("[email protected]", "Payment not complete", $message, "From: [email protected]"); 
    exit(); // exit script 
} 
// Check number 3 ------------------------------------------------------------------------------------------------------------ 
$this_txn = $_POST['txn_id']; 
$query = "SELECT id FROM transactions WHERE txn_id='$this_txn' LIMIT 1"; 
$result = mysqli_query($conn, $query); 
$numRows = mysqli_num_rows($result); 
if ($numRows != 0) { 
    $message = "Duplicate transaction ID occured so we killed the IPN script. Transaction ID:$this_txn \n\n\n$req"; 
    mail("[email protected]", "Duplicate transaction ID(txn_id) in the IPN system", $message, "From: [email protected]"); 
    exit(); // exit script 
} 
// Check number 4 ------------------------------------------------------------------------------------------------------------ 
$product_id_string = $_POST['custom']; 
$product_id_string = rtrim($product_id_string, ","); // remove last comma 
// Explode the string, make it an array, then query all the prices out, add them up, and make sure they match the payment_gross amount 
$id_str_array = explode(",", $product_id_string); // Uses Comma(,) as delimiter(break point) 
$fullAmount = 0; 
foreach ($id_str_array as $key => $value) { 

    $id_quantity_pair = explode("-", $value); // Uses Hyphen(-) as delimiter to separate product ID from its quantity 
    $product_id = $id_quantity_pair[0]; // Get the product ID 
    $product_quantity = $id_quantity_pair[1]; // Get the quantity 
    $query = "SELECT price FROM products WHERE id='$product_id' LIMIT 1"; 
    $result = mysqli_query($conn, $query); 
    while($row = mysqli_fetch_array($result)){ 
     $product_price = $row["price"]; 
    } 
    $product_price = $product_price * $product_quantity; 
    $fullAmount = $fullAmount + $product_price; 
} 
$fullAmount = number_format($fullAmount, 2); 
$grossAmount = $_POST['mc_gross']; 
if ($fullAmount != $grossAmount) { 
     $message = "Possible Price Jack: " . $_POST['mc_gross'] . " != $fullAmount \n\n\n$req"; 
     mail("[email protected]", "Price Jack or Bad Programming", $message, "From: [email protected]"); 
     exit(); // exit script 
} 
// END ALL SECURITY CHECKS NOW IN THE DATABASE IT GOES ------------------------------------ 
//////////////////////////////////////////////////// 
// Assign local variables from the POST PayPal variables 
$custom = $_POST['custom']; 
$payer_email = $_POST['payer_email']; 
$first_name = $_POST['first_name']; 
$last_name = $_POST['last_name']; 
$payment_date = $_POST['payment_date']; 
$mc_gross = $_POST['mc_gross']; 
$payment_currency = $_POST['payment_currency']; 
$txn_id = $_POST['txn_id']; 
$receiver_email = $_POST['receiver_email']; 
$payment_type = $_POST['payment_type']; 
$payment_status = $_POST['payment_status']; 
$txn_type = $_POST['txn_type']; 
$payer_status = $_POST['payer_status']; 
$address_street = $_POST['address_street']; 
$address_city = $_POST['address_city']; 
$address_state = $_POST['address_state']; 
$address_zip = $_POST['address_zip']; 
$address_country = $_POST['address_country']; 
$address_status = $_POST['address_status']; 
$notify_version = $_POST['notify_version']; 
$verify_sign = $_POST['verify_sign']; 
$payer_id = $_POST['payer_id']; 
$mc_currency = $_POST['mc_currency']; 
$mc_fee = $_POST['mc_fee']; 

// Place the transaction into the database 
$sql = mysqli_query($conn, "INSERT INTO transactions (id, product_id_array, payer_email, first_name, last_name, payment_date, mc_gross, payment_currency, receiver_email, payment_type, payment_status, txn_type, payer_status, address_street, address_city, address_state, address_zip, address_country, address_status, notify_version, verify_sign, payer_id, mc_currency, mc_fee) 
    VALUES('$txn_id','$custom','$payer_email','$first_name','$last_name','$payment_date','$mc_gross','$payment_currency','$receiver_email','$payment_type','$payment_status','$txn_type','$payer_status','$address_street','$address_city','$address_state','$address_zip','$address_country','$address_status','$notify_version','$verify_sign','$payer_id','$mc_currency','$mc_fee')") or die ("unable to execute the query"); 

mysqli_close(); 
// Mail yourself the details 
mail("[email protected]", "New Order Entered: ".$txn_id, $req, "From: [email protected]"); 
?> 
0

你需要解决的脚本来找到问题。这对于IPN来说可能很困难,但如果您按照how to test PayPal IPN的这些步骤进行操作,您应该能够很快地追踪它。

+0

我已经调试过IPN,脚本本身工作正常。数据正在正确发送,交易正在进行。问题在于连接到我的数据库。在运行沙箱测试的贝宝交易时,ipn.php页面没有连接到我的数据库。如果我只是加载页面,它将连接到我的数据库罚款,但不是在贝宝交易期间。 – Neeeewb