Yii and PayPal IPN (400 Bad Request via IPN Simulator)


Does anyone here have any experience with setting up a PayPal IPN receiver with Yii, as I’ve hit a problem that’s rather difficult to trace.

If I go to the PayPal sandbox site, and enter -any- URL on the site that uses the Yii framework, I get a “400 Bad Request” message back. If I load any file which doesn’t use the Yii framework, the IPN message is sent successfully.

I haven’t gotten very far in terms of tracing it, but if I go to the main index.php and comment out this line:

Then the IPN Simulator says the request was sent successfully. The request never reaches the controller, as any database logging calls I add on SiteController.actionPayPalIPN do not get run. Thus, the error must be occuring somewhere within the Yii Framework itself, possibly as a result of all the POST variables sent from the IPN Simulator. I’ve already checked the URL that gets invoked, and it’s exactly the same was what I enter on the tester, with no get parameters tacked on.

Has anyone else run into this issue before?

Did you allow actionPayPalIPN in accessControl?


Not specifically, no, I’m using SiteController, which by default doesn’t have any accessRules.

I did find something more concrete though. I did a local implementation of what the IPN Simulator is sending, and I got this out:

So the guilty party is the enabling of Csrf Validation in the config:

I added that as per the security guidelines. Disabling it gets rid of the error, but then weakens the site’s security.

Is there a way to specify that the validation shouldn’t be done on requests to the SiteController.actionPayPalIPN, or is there a way to set certain URLs as trusted, etc, etc?

Seems you need to derive a new class from CHttpRequest and override its validateCsrfToken() method:

class MyHttpRequest extends CHttpRequest


  public validateCsrfToken(CEvent $event)


    if (!isTrustedRequest())

      parent::validateCsrfToken( $event );



   * Whatever you think is appropriate...

   * (referrer, action, anything payPal sends to authenticate itself?)


  protected isTrustedRequest()





Then, in your config:

'request' => array(

  'class' => 'path.to.MyHttpRequest',



This is not safe but this is what I had to put in my controller to make it work

  public $enableCsrfValidation = false;