Focus on IT Recommend

Home > php - PayPal IPN hander is no longer inserting into database

php - PayPal IPN hander is no longer inserting into database



My IPN handler is no longer inserting any values into the 'payments' table. The transaction is still taking place in the PayPal sandbox perfectly. I've also tried using the IPN simulator, it says 'IPN sent successfully' but still nothing is inserted into the table.

I did have it working fine last week, but since then have made some changes to the site and I can't figure out which changes have affected this.

Any help on this is greatly appreciated.

This is the form I'm using

<form class="paypal" action="payments.php" method="post" id="paypal_form" target="_blank">    
    <input type="hidden" name="cmd" value="_xclick" /> 
    <input type="hidden" name="no_note" value="1" />
    <input type="hidden" name="currency_code" value="AUD" />
    <input type="hidden" name="bn" value="PP-BuyNowBF:btn_buynow_LG.gif:NonHostedGuest" />
    <input type="hidden" name="item_name" value="Membership" />
    <input type="hidden" name="item_number" value="Membership" />
    <input type="submit"  value="Submit Payment"/>

Here is my IPN handler/listener (payments.php)

Recommend:php - PayPal IPN not updating MySQL database

ugging me for a while. i'm trying to write an IPN script for an online store that sells individual items. once the payment is complete, the script will update the database and change the availability from "available" to "unavailable". the I

// Database variables
$host = "localhost"; //database location
$user = "xxxx"; //database username
$pass = "xxxx"; //database password
$db_name = "xxxx"; //database name

// PayPal settings
$paypal_email = '';
$return_url = 'xxxx';
$cancel_url = 'xxxx';
$notify_url = 'xxxx';

$item_amount = $_POST["item_amount"];

// Include Functions
function check_txnid($tnxid){
    global $link;
    return true;
    $valid_txnid = true;
    //get result set
    $sql = mysql_query("SELECT * FROM `payments` WHERE txnid = '$tnxid'", $link);       
    if($row = mysql_fetch_array($sql)) {
        $valid_txnid = false;
    return $valid_txnid;

function check_price($price, $id){
    $valid_price = false;
    //you could use the below to check whether the correct price has been paid for the product

    $sql = mysql_query("SELECT amount FROM `products` WHERE id = '$id'");       
    if (mysql_numrows($sql) != 0) {
        while ($row = mysql_fetch_array($sql)) {
            $num = (float)$row['amount'];
            if($num == $price){
                $valid_price = true;
    return $valid_price;
    return true;

function updatePayments($data){ 
    global $link;
        $sql = mysql_query("INSERT INTO `payments` (txnid, payment_amount, payment_status, itemid, createdtime) VALUES (
                '".$data['txn_id']."' ,
                '".$data['payment_amount']."' ,
                '".$data['payment_status']."' ,
                '".$data['item_number']."' ,
                '".date("Y-m-d H:i:s")."' 
                )", $link);

    return mysql_insert_id($link);

//Database Connection
$link = mysql_connect($host, $user, $pass);

// Check if paypal request or response
if (!isset($_POST["txn_id"]) && !isset($_POST["txn_type"])){

    // Firstly Append paypal account to querystring
    $querystring .= "?business=".urlencode($paypal_email)."&";  

    // Append amount& currency (£) to quersytring so it cannot be edited in html

    //The item name and amount can be brought in dynamically by querying the $_POST['item_number'] variable.
    $querystring .= "item_name=".urlencode($item_name)."&";
    $querystring .= "amount=".urlencode($item_amount)."&";

    //loop for posted values and append to querystring
    foreach($_POST as $key => $value){
        $value = urlencode(stripslashes($value));
        $querystring .= "$key=$value&";

    // Append paypal return addresses
    $querystring .= "return=".urlencode(stripslashes($return_url))."&";
    $querystring .= "cancel_return=".urlencode(stripslashes($cancel_url))."&";
    $querystring .= "notify_url=".urlencode($notify_url);

    // Append querystring with custom field
    //$querystring .= "&custom=".USERID;

    // Redirect to paypal IPN


    // Response from Paypal

    // read the post from PayPal system and add 'cmd'
    $req = 'cmd=_notify-validate';
    foreach ($_POST as $key => $value) {
        $value = urlencode(stripslashes($value));
        $value = preg_replace('/(.*[^%^0^D])(%0A)(.*)/i','${1}%0D%0A${3}',$value);// IPN fix
        $req .= "&$key=$value";

    // assign posted variables to local variables
    $data['item_name']          = $_POST['item_name'];
    $data['item_number']        = $_POST['item_number'];
    $data['payment_status']     = $_POST['payment_status'];
    $data['payment_amount']     = $_POST['mc_gross'];
    $data['payment_currency']   = $_POST['mc_currency'];
    $data['txn_id']         = $_POST['txn_id'];
    $data['receiver_email']     = $_POST['receiver_email'];
    $data['payer_email']        = $_POST['payer_email'];
    $data['custom']             = $_POST['custom'];

    // post back to PayPal system to validate
    $header = "POST /cgi-bin/webscr HTTP/1.0\r\n";
    $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
    $header .= "Content-Length: " . strlen($req) . "\r\n\r\n";

    $fp = fsockopen ('ssl://', 443, $errno, $errstr, 30); 

    if (!$fp) {
        // HTTP ERROR
    } else {    

        fputs ($fp, $header . $req);
        while (!feof($fp)) {
            $res = fgets ($fp, 1024);
            if (strcmp($res, "VERIFIED") == 0) {

                // Used for debugging
                //@mail("", "PAYPAL DEBUGGING", "Verified Response<br />data = <pre>".print_r($post, true)."</pre>");

                // Validate payment (Check unique txnid & correct price)
                $valid_txnid = check_txnid($data['txn_id']);
                $valid_price = check_price($data['payment_amount'], $data['item_number']);
                // PAYMENT VALIDATED & VERIFIED!
                if($valid_txnid && $valid_price){               
                    $orderid = updatePayments($data);       
                        // Payment has been made & successfully inserted into the Database                              
                        // Error inserting into DB
                        // E-mail admin or alert user
                    // Payment made but data has been changed
                    // E-mail admin or alert user

            }else if (strcmp ($res, "INVALID") == 0) {

                // E-mail admin or alert user 

                // Used for debugging
                //@mail("", "PAYPAL DEBUGGING", "Invalid Response<br />data = <pre>".print_r($post, true)."</pre>");
    fclose ($fp);
php mysql sql paypal paypal-ipn
  this question
asked Aug 12 '12 at 12:37 tenderloin 874 1 8 16      Be advised that your script is vulnerable to SQL injection. At a minimum, you MUST call mysql_real_escape_string() on each and every one of those $_POST values in your $data array before you pass them to the INSERT statement. In the long run, consider moving to an API that supports prepared statements, such as PDO or MySQLi –  Michael Berkowski Aug 12 '12 at 12:48      Now, when you call updatePayments($data), what happens? do you get to the E-mail admin or alert user block? Your values are unescaped, so it is possible they could break your query. echo mysql_error(); –  Michael Berkowski Aug 12 '12 at 12:50      Hi Michael, I can't (to my knowledge) use echo mysql_error(); to debug this as it isn't a page that you visit. If there is a way of doing this please, let me know. –  tenderloin Aug 12 '12 at 13:21      I've tried using the @mail script under: fputs ($fp, $header . $req); while (!feof($fp)) { $res = fgets ($fp, 1024); if (strcmp($res, "VERIFIED") == 0) { But I haven't recieved an email. –  tenderloin Aug 12 '12 at 13:24      But you can die(mysql_error()) so the whole script ends when it is called, wherever the output goes, you'll see it. –  Michael Berkowski Aug 12 '12 at 13:27


1 Answers


It turns out nothing was wrong with my code, after de-bugging I found the IPN was not being verified using PayPal's Sandbox (so that's obviously a problem on their end). But when I ran it through the real PayPal site it worked perfectly.

Thanks Michael for the heads up on the SQL injection.

  this answer
answered Aug 14 '12 at 8:22 tenderloin 874 1 8 16


Recommend:database - IPN Paypal (PHP)

o be able to solve. I've made a IPN Listener and put it up on my website @ the listener is a class, so i have another file, called ipn.php that has the functions needed when I get the payment notification


------splitte line----------------------------