PayPal IPN: some orders produce IPN failure ( Undefined index: invoice )

If your URL is correct then it's what Keyur Shah already commented, but probably wasn't clear enough. If you have IPN enabled and receive payments from different sources (ebay, Magento and others) to the same PayPal account, PayPal unfortunately continues to try sending notifications related to these order to the Magento store, where these orders don't exist.

A possible solution is creating a centralized IPN reciever, see this URL for a very useful script to get you started. http://codeseekah.com/2012/02/11/how-to-setup-multiple-ipn-receivers-in-paypal/


As pointed out by @Keyur Shah, these orders has not been placed with Magento. (so probably they are imported by M2E in my case)

Magento doesn't know anything about them and expect the field invoice to be populated, so something like this happens:

  1. Ipn receive a request from Paypal without theinvoicefield.
  2. Mage_Paypal_Model_Ipn::_getOrder() expect the invoice field and produce an exception
  3. Mage_Paypal_IpnController sent back a 503 Service Unavailable to Paypal
  4. You got Paypal email ... Paypal continue to retry for sometime for the failing orders

Solution
Rewrite Mage_Paypal_Model_Ipn::processIpnRequest()
I'm not explaining the full procedure as there are a lot of tutorials showing how to create a module that rewrite a core file.

This mod:

  1. No cause exception if invoice field is not present and log those order id
  2. Will reply to Paypal a success so Paypal do not sent any email and will stop send this order info to the IPN again.

Here the class file:

class MyModule_Fix_Model_Paypal_Ipn extends Mage_Paypal_Model_Ipn
{
    public function processIpnRequest(array $request, Zend_Http_Client_Adapter_Interface $httpAdapter = null)
    {
        $this->_request = $request;
        $this->_debugData = array('ipn' => $request);
        ksort($this->_debugData['ipn']);

        try {
            if (!isset($this->_request['invoice'])) {
                if ($httpAdapter) {
                    $this->_config = Mage::getModel('paypal/config', array('', ''));
                    $this->_postBack($httpAdapter); // send reply to paypal
                }
                $this->_debugData['exception'] = 'Missing Invoice/Order Id (maybe Ebay/Amazon order ?)';
                return;
            }

            if (isset($this->_request['txn_type']) && 'recurring_payment' == $this->_request['txn_type']) {
                $this->_getRecurringProfile();
                if ($httpAdapter) {
                    $this->_postBack($httpAdapter);
                }
                $this->_processRecurringProfile();
            } else {
                $this->_getOrder();
                if ($httpAdapter) {
                    $this->_postBack($httpAdapter);
                }
                $this->_processOrder();
            }
        } catch (Exception $e) {
            $this->_debugData['exception'] = $e->getMessage();
            $this->_debug();
            throw $e;
        }
        $this->_debug();
    }
}