So… since we started using Paypal Express in one of our client’s Magento v1.6 Stores, we’ve been getting an exception. In the exception.log file, it logs the following error for the Paypal IPN: “Wrong Order ID: 100000123″.
NOTE: Magento have fixed the cause of this error in the Community version 1.7 Paypal IPN. However, we don’t like the way they fixed it. See “The Code” below.
If you just want the solution, go down to “The Solution”. But first, some of the things it is NOT caused by.
The “Attempted” Solutions
After trolling the web to find a solution nothing seemed to be working. For those of you who have followed this post for some time, you know we’ve tried a number of possible solutions, which we will preserve below.
First, a bit of background on this issue: Paypal uses a request variable called [invoice] which contains the order number from Magento and that get’s looped back to the Magento store via IPN. Don’t worry… even though it’s called “invoice” it’s just the order number. But, we thought… what if there’s some wires being crossed somewhere in the IPN code? Especially since, when using Paypal Express, Magento reserves an order number at the time of the redirect to Paypal, BUT if the order is not completed IT HOLDS ONTO that order number for the customer’s next order. Crazy huh?
In the meantime… invoices continue to be processed according to their regular increment, so the invoice numbers and order numbers get out of sync.
Attempt 1
We tried an extension by Fooman (Available on Magento Connect) to make the order number and invoice number always equal to one another… this seemed to reduce the errors, but didn’t solve them completely. And… it’s sort of neat and tidy to be able to have your order numbers = invoice numbers = credit memos, etc.
Attempt 2
What if… the invoice number increment and the order number increment had just got so far out of whack that attempting to reconcile them with the above solution was causing errors too? Well… if that was a possibility, we installed another extension by ASchroder (Available on Magento Connect) that allows you to “Reset” your order/invoice/credit memo/shipment IDs to start at whatever you specify.
We tried this… and it made our order numbers look pretty, BUT no improvement.
Attempt 3
Finally, we dug deeper into the Paypal IPN code ourselves to see what was going on. It seemed as though at the point that the IPN code was calling the _getOrder() method, the order number was somehow not yet available from the Magento store?
After a useful post by Oleg below in comments, we zoned in on server performance as a possible contributor. After looking at the web site traffic in Analytics, there definitely seemed to be a correlation between the IPN errors and times of high traffic.
For a while we resorted to solving the server performance problem, even adding additional indexes to the database. Bottom line, nothing worked.
THE Solution
At long last we have the solution. The reason this error shows up in your exception log, IS because the order number is not available to Magento at the time that Paypal pings your IPN url. However, the Magento Paypal IPN for Magento 1.6 was badly written. Even though there was an exception, Magento still sent back an HTTP status code 200. So Paypal thought everything was fine. So, what if your server is not accessible at the moment Paypal is trying to ping your IPN url? Do you just want Paypal and Magento to forget it ever happened? Of course not.
To fix the problem, you have to change the IPN model code to return an HTTP 503 – “Service not available”, in the event that an order id could not be found. Then all that Paypal will do is try again until the order number is available and viola… no exception.
The Code
As always… don’t modify core code! We will take the “local” path override approach. We’ll show you two ways to fix the problem, the Magento 1.7 way and then our way. (Our way is better and we’ll explain why)
- Create a new directory under you Magento root. “app/code/local/Mage/Paypal/Model”
- Download the core file “app/code/core/Mage/Paypal/Model/Ipn.php”
- Edit this file using one of the methods below
The Magento Way
Around line 172, find the following code:
if (!$this->_order->getId()) { throw new Exception(sprintf('Wrong order ID: "%s".', $id)); }
Change it to look like so…
if (!$this->_order->getId()) { $this->_debugData['exception'] = sprintf('Wrong order ID: "%s".', $id); $this->_debug(); Mage::app()->getResponse() ->setHeader('HTTP/1.1','503 Service Unavailable') ->sendResponse(); exit; }
Now… all you have to do is copy the edited version of “Ipn.php” to the new directory on your server. So the final path of this file will be “app/code/local/Mage/Paypal/Model/Ipn.php”. Clear your Magento cache and recompile.
Our Way
For various reasons we don’t like the Magento fix. Firstly, what if Paypal really has the wrong order number for some reason? Then it will never be found in your store. So Paypal will retry and retry to no avail, until it results in a failure. If this happens enough times, Paypal will automatically disable IPN messages on your account.
For that reason, our solution implements a few other checks to make sure that doesn’t happen. First, we check if this is a retry attempt or a first attempt. Second, if it IS a retry attempt, we check how long it’s been since the original transaction. If it has been longer than 48 hours, it’s safe to say the order number doesn’t exist. In that case we send back an HTTP 200, log an exception and Paypal forgets about it.
And here’s our code…
Around line 166, find the following block of code:
protected function _getOrder() { if (empty($this->_order)) { // get proper order $id = $this->_request['invoice']; $this->_order = Mage::getModel('sales/order')->loadByIncrementId($id); if (!$this->_order->getId()) { throw new Exception(sprintf('Wrong order ID: "%s".', $id)); } // re-initialize config with the method code and store id $methodCode = $this->_order->getPayment()->getMethod(); $this->_config = Mage::getModel('paypal/config', array($methodCode, $this->_order->getStoreId())); if (!$this->_config->isMethodActive($methodCode) || !$this->_config->isMethodAvailable()) { throw new Exception(sprintf('Method "%s" is not available.', $methodCode)); } $this->_verifyOrder(); } return $this->_order; }
Replace it with this:
protected function _getOrder() { $resend = false; if (empty($this->_order)) { //get the variables we need from the IPN request if(array_key_exists('resend', $this->_request)) { $resend = $this->_request['resend']; } $paymentdate = strtotime($this->_request['payment_date']); $today = strtotime('now'); // get proper order $id = $this->_request['invoice']; $this->_order = Mage::getModel('sales/order')->loadByIncrementId($id); if (!$this->_order->getId()) { //if this is not the first attempt, check how many days have elapsed if($resend && $today->diff($paymentdate)->days >= 2) { //more than two days have elapsed, log an error throw new Exception(sprintf('Wrong order ID: "%s".', $id)); } //this is the first attempt else { $this->_debugData['exception'] = sprintf('Order not found ID: "%s".', $id); $this->_debug(); Mage::app()->getResponse() ->setHeader('HTTP/1.1','503 Service Unavailable') ->sendResponse(); exit; } } // re-initialize config with the method code and store id $methodCode = $this->_order->getPayment()->getMethod(); $this->_config = Mage::getModel('paypal/config', array($methodCode, $this->_order->getStoreId())); if (!$this->_config->isMethodActive($methodCode) || !$this->_config->isMethodAvailable()) { throw new Exception(sprintf('Method "%s" is not available.', $methodCode)); } $this->_verifyOrder(); } return $this->_order; }
Once again, save your “Ipn.php” file and upload it to it’s new location “app/code/local/Mage/Paypal/Model/Ipn.php”. Clear your Magento cache and recompile.
A Last Word
For those of us who have worked with Magento a long time, we EXPECT quirky error messages that don’t have any rhyme or reason, because Magento has tons of them. However, in this case, the error appears to be accurate although it’s cause is not clearly apparent at first.
If you have any questions about this solution, please drop us a comment below.
Beon de Nood
Latest posts by Beon de Nood (see all)
- FileMaker on iPad in the Enterprise? - April 10, 2013
- The Day We Blew Away WordPress - April 6, 2013
- Magento Paypal IPN Wrong Order ID - February 15, 2013


