Skip to content
Advertisement

PayPal IPN losing session on return?

I’m using Micha’s PayPal IPN script and for the most part it worked great: https://github.com/Quixotix/PHP-PayPal-IPN

When i click Pay now on the website it redirects to paypal with correct information, allows payment to be made, but on return nothing happens, ie it does not upgrade the user as it should. Now i’ve tested the script my code outside of the IPN and it works perfect so it looks to me like the IPN script is losing the session?

Here is my button code:

<form name="_xclick" action="https://www.paypal.com/cgi-bin/webscr" method="post">
    <input type="hidden" name="cmd" value="_xclick">
    <input type="hidden" name="business" value="EMAIL_TO">
    <input type="hidden" name="currency_code" value="GBP">
    <input type="hidden" name="item_name" value="Text Light">
    <input type="hidden" name="amount" value="0.01">
    <input type="hidden" name="return" value="http://domain.co.uk/editors">
    <input type="hidden" name="notify_url" value="http://domain.co.uk/account/upgrade">
    <input type="submit" value="Pay now" class="btn btn-preview" name="submit" alt="Make payments with PayPal - it's fast, free and secure!">
</form>

So the notify url (IPN code) is /account/upgrade — as far as i know this is where it should perform the upgrade task? so here is my (stripped down) code

if ($verified) {

    $errmsg = '';

    // some error checking

    if (!empty($errmsg)) {

        // manually investigate errors from the fraud checking

    } else {

        // upgrade user
        $package = serialize($_SESSION['package']);
        $this->db->update('users',array('id' => $_SESSION['user']['id']),array('payment_plan' => $package));

    }

} else {

    // not verified, investigate problems
}

As above, the code under ‘// upgrade user’ works fine outside, but on return from paypal it’s obviously not keeping hold of the session. It’s not throwing any errors, it’s just not doing anything.

Where have i gone wrong? how can i ensure that session information will be passed back from PayPal.

Thanks

Advertisement

Answer

Your question has a short answer: IPN isn’t done as the user.

To expand on the answer, here’s how IPN works. You make a payment, your visitor returns to your site, and PayPal pings your IPN URL. The important bit is in bold – the request will come from PayPal and not from the user, and will therefore not inherit the user’s session!

The reason for this is pretty simple – the IPN URL is supposed to be private, as you could do all sort of silly shenanigans if it wasn’t (including creating virtual transactions). For this very reason, the user never sees this address. (Another reason is that not all browsers will follow redirects – and IPN is designed to provide information 100% of the time).

If you would like to do this, you’ll need to pass a parameter to the IPN request indicating who the user is. Passing the user ID is a very bad idea – as parameters as modifiable. Instead, generate a transaction ID of some sort containing the info on the user, and pass this. On the IPN call, you’ll get this variable back as a custom parameter, which will allow you to fetch stuff from your DB and do whatever you want, knowing who the user was.

Hope this helped.

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