Skip to content
Advertisement

How to update database after receiving PayPal IPN

I am trying a simple listener to update my user info database (like setting their account type from FREE to PREMIUM) after receiving the PayPal IPN. Upon checking the IPN history, the IPN is successfully sent to my listener but can’t seem to update my database. I wanted to update the user’s account type after VERIFIED part using the SESSION ID that my user is using. The listener.php that I am using is from a tutorial video that I followed.

Here is the code:

session_start();

require 'scr/db.inc.php';

header('HTTP:/1.1 200 OK');

$resp = "cmd=_notify-validate";
foreach ($_POST as $parm => $var) {
    $var = urlencode (stripslashes($var));
    $resp .= "&$parm=$var";
}

$item_name          = $_POST['item_name'];
$item_number        = $_POST['$item_number'];
$payment_status     = $_POST['$payment_status'];
$payment_amount     = $_POST['$payment_amount'];
$payment_currency   = $_POST['$payment_currency'];
$txn_id             = $_POST['$txn_id'];
$receiver_email     = $_POST['$receiver_email'];
$payer_email        = $_POST['$payer_email'];
$record_id          = $_POST['$record_id'];

$httphead = "POST /cgi-bin/webscr HTTP/1.0rn";
$httphead .= "Content-Type: application/x-www-form-urlencodedrn";
$httphead .= "Content-Length: " .strlen($resp) . "rnrn";

$errno = '';
$errstr = '';

$fh = fsockopen ('ssl:www.paypal.com',443,$errno,$errstr,30);

if (!$fh) {

} else {
    fputs ($fh, $httphead . $resp);
    while (!feof($fh)) {
        $readresp = fgets ($fh, 1024);
        if(strcmp ($readresp, "VERIFIED") == 0 ) {

           $handler = new Dbh();

           $sql = 'UPDATE `users` SET `type` = "PREMIUM" WHERE `id`  = :id ';
           $query = $handler->connect()->prepare($sql);
           $query->execute(array(':id'=>$_SESSION['log_id']));

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

        }
    }
fclose($fh);        
}


?>

I just added a couple of lines into it to hopefully update the database. These are those lines:

session start();
require 'scr/db.inc.php';
.
.
.
.
$handler = new Dbh(); // used to connect to database

$sql = 'UPDATE `users` SET `type` = "PREMIUM" WHERE `id`  = :id ';
$query = $handler->connect()->prepare($sql);
$query->execute(array(':id'=>$_SESSION['log_id']));
.
.
.
.

Advertisement

Answer

When the PayPal server calls your IPN listener, it starts its own mini “session” between itself and your webserver. Your user’s web browser is not a party to this direct HTTP communication between PayPal and your server, so none of the web session details of your user’s browser with your server will be available.

If you need an ID to be available at the time you are processing an IPN, you need to pass it to PayPal as part of the transaction, using a variable such as INVNUM or CUSTOM.

When you write to the database, you will need to grab the appropriate variables from the IPN message body in $_POST (not from $_SESSION which will have absolutely nothing of value)


Side note: whenever I see IPN being used asynchronously like this on a server, I can’t help noting a much nicer and more robust integration is to integrate a server-side pattern that captures synchronously from the server side and so gets an immediate API response of transaction success/failure, with the user $_SESSION active. Here’s a demo pattern of the UI , and the backend v2/orders server-side calls

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement