Welcome Guest, Not a member yet? Register   Sign In
CodeIgniter vs IPN
#1

[eluser]benjamin[/eluser]
Hi All,

I'm using PayPal's IPN, and whilst I'm aware that there is a CI library for it, I'm trying to understand something, and was hoping whether somebody could help me shed some light into this. If I use the CI library, requests are being sent and received (all OK). Now if I'm being playful, and simply create a controller (let's call it "paypal_ipn"), and re-direct my IPN to xyz/index.php/paypal_ipn/listener, then suddenyl paypal can no longer send any messages...However if I call the same URL from my browser, everything works fine (i.e. no syntax errors etc)...I guess there is a fundamental CI principle that I don't understand / missed? Thanks in advance.

Controller:

Code:
<?php

class PayPal_IPN extends CI_Controller {


    /**
     * Constructor.
     *
     * @since 1.0
     */
    function __construct() {
        parent::__construct();
    }

    /**
     * The IPN listener. Processes IPN events.
     *
     * @since 1.0
     */
    function listener() {
        // read the post from PayPal system and add 'cmd'
        $req = 'cmd=_notify-validate';


        foreach ($_POST as $key => $value) {
            $value = urlencode(stripslashes($value));
            $req .= "&$key=$value";
        }

        // 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://www.paypal.com', 443, $errno, $errstr, 30);

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

        if (!$fp) {
            // HTTP ERROR

        } else {
            fputs($fp, $header . $req);
            while (!feof($fp)) {
                $res = fgets($fp, 1024);
                if (strcmp($res, "VERIFIED") == 0) {
                    // confirm and process order...foo bar
                } else if (strcmp($res, "INVALID") == 0) {
                    // log for manual investigation
        
                }
            }
            fclose($fp);
        }
    }

    

}

?>
#2

[eluser]TheBaron[/eluser]
I haven't used IPN in ages. Don't you have to specify a return url on your Paypal account? When you changed the url did you change this also?
#3

[eluser]benjamin[/eluser]
Yes and no :-) That is, yes, you have (and I did) specify a return URL, however this (as far as I'm aware) is not related to the IPN verification message. The re-direct works fine in itself (both with auto-redirect on and off), but has no impact on the IPN messages being received.

It seems odd that PayPal cannot directly post to the controller. I get a "HTTP response code: 500" for all messages.


Thanks for your reply.
#4

[eluser]arcreative[/eluser]
I ran into some HTTP 500 problems a while back, and it had to do with something stupid like the formatting of whitespace in the response. There's a patch for it here somewhere, but I can't seem to find it at the moment...
#5

[eluser]benjamin[/eluser]
@acreative: Thanks for your time. Yes, you are right in saying that PayPal requires an exact copy of the original IPN message to be sent back. However this wasn't the problem. Figured it out at long last:

The problem was that I had CSRF enabled - so, PayPal couldn't post to my controller. The solution is to paste the following code snippet into your config file where
you would usually set $config['csrf_protection']:

Code:
if (isset($_SERVER["REQUEST_URI"])) {
    if (stripos($_SERVER["REQUEST_URI"], '/paypal_ipn') === FALSE) {
        $config['csrf_protection'] = TRUE;
    } else {
        $config['csrf_protection'] = FALSE;
    }
} else {
    $config['csrf_protection'] = TRUE;
}

From: http://ellislab.com/forums/viewthread/182631/




Theme © iAndrew 2016 - Forum software by © MyBB