Magento: Rundungsfehler in Version 1.9.x

von
Kreativ&Söhne

Magento Rundungsfehler

Ausgangslage

Der Magento Rundungsfehler geschieht immer dann, wenn der Netto-Wert und der MwSt.-Betrag unterschiedlich gerundet werden. Dabei kommt es dann zu einer Differenz.

In unserer Konstellation werden die Produktpreise netto gepflegt und brutto ausgegeben.
Weiterhin ist uns aufgefallen das es sich nicht nur um einen Rundungsfehler von ein oder zwei Cent handelt, sondern die Abweichung um so größer wird, je niedriger die Preise und je höher die Anzahl der Produkte im Warenkorb ist.

Lösung für den Magento Rundungsfehler

Unsere Lösung beschränkt sich, im Gegensatz zu anderen Lösungsvorschlägen auf nur eine grundlegende Änderung.

Zuerst sollte man die Rundung innnerhalb von Magento von 2 auf 4 Stellen erweitern. Das ist schnell und einfach gemacht.

  1. Ableiten der Core Datei "/app/code/core/Mage/Core/Model/Store.php" in "/app/code/local/Mage/Core/Model/Store.php"
  2. In der Datei "Store.php" den Code auf Zeile 995 (Magento 1.9.x) die Zahl von 2 auf 4 ändern.
/**
 * Round price
 *
 * @param mixed $price
 * @return double
 */
 
 public function roundPrice($price)
 {
 	//return round($price, 2);
 	return round($price, 4);
 }

Der Magento Rundungsfehler und Paypal

Durch die höhere Rundungsgenauigkeit im Magento kann es nun aber leider passieren das PayPal einen Betrugsverdacht (Suspected Fraud) an Magento zurück meldet.

Der Magento Rundungsfehler bei Zahlungen mit PayPal geschieht immer dann, wenn der Netto-Wert und der MwSt.-Betrag unterschiedlich gerundet werden. Dabei kommt es dann zu einer Differenz zwischen dem übermittelten Betrag von Magento an PayPal und dem Wert, den PayPal selber errechnet.

Wie Fabian Kröger in seinem Blog bereits beschrieben hat, gibt es eine Reihe von Lösungsansätzen.
Die Kurzfassung: In der Datei "Mage/Paypal/Model/Ipn.php" wird der von Paypal verarbeitete Betrag entgegengenommen und mit der Rechnung abgeglichen. Dies geschieht in unserer Magento-Version (1.9.1.0) in der Methode _registerPaymentCapture(). Diese Lösung sollte für alle Magentos zwischen 1.7 und 1.9 funktionieren. Dort wird geprüft ob der erwartete Betrag ungefähr dem von Paypal gelieferten entspricht. Wieviel Differenz ihr zugestehen wollt, hängt von euch ab, in diesem Beispiel ist uns eine Nachkommastelle genug. Wenn dem so ist, ersetzen wir den von Paypal gelieferten durch den von Magento erwarteten Betrag. Damit bekommt Magento genau das, was es will, und stellt keinen Betrugsverdacht mehr fest.

  1. Die Datei "Mage/Paypal/Model/Ipn.php" von "app/code/core/" nach "app/code/local" ableiten
  2. Folgenden Code in Zeile 474 (Magento 1.9.1.) in der Methode "registerPaymentCapture" ganz am Anfang einsetzen
/**
 * Process completed payment (either full or partial)
 *
 * @param bool $skipFraudDetection
 */
 
 protected function _registerPaymentCapture($skipFraudDetection = false)
 {
    // Fraud fix
    $x_price = $this->_order->getBaseGrandTotal();
    if(round($this->getRequestData('mc_gross'),1) == round($x_price, 1))
    	$this->_request['mc_gross'] = $x_price;
    // --

Zurück