2015-07-03 24 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