Magento, Paypal und der Betrugsverdacht (Suspected Fraud)

Bei einem unserer Kunden sind ab & zu Probleme bei Zahlungen über PayPal aufgetreten. Nach kurzer Recherce stellten wir erleichtert fest, dass dieses als „Magento Rundungsfehler“ bekannte Problem nicht nur uns, sondern auch schon viele andere vor uns traf. Unsere Freude schwand, als keine der vorgeschlagenen Lösungen wirklich half. Wir konnten zwar einen gewissen Rückgang verzeichnen, hatten aber immer noch fast täglich Meldungen, das Paypal einen Betrugsverdacht vermuten würde.

Das Problem zusammengefasst

Wir runden in Magento mit 4 Stellen nach dem Komma, Paypal mit zwei. Bei bestimmten Zahlen kommt es nun vor, dass der Shop für eine Bestellung z.B. den Betrag von 14,9401 € erfasst. Bei Zahlung über Paypal meldet dessen API am Ende der Transaktion an Magento, dass 14,94 € gezahlt wurden. Für Magento ist das nicht der Betrag, der erwartet wurde – das System schlägt Alarm und versetzt die Bestellung in den Status „Suspected Fraud“.

Lösungsansätze

Wie Fabian Kröger in seinem Blog bereits schön beschrieben hat, gibt es eine Reihe von Lösungsansätzen. Gefruchtet hat keiner wirklich, aber bei einem Satz von Ihm habe ich aufgemerkt: „Den Fraud-Check einfach auszustellen stellte sich als aufwändiger als erwartet heraus da die Funktionalität leider sehr verstreut ist.“ Das wollte ich so nicht glauben und habe mich daran gesetzt. Den Check habe ich gelassen, jedoch soweit angepasst, dass er fehlertolerant wird. Genaue Erklärung kommt später, hier schonmal die Lösung:

In der Datei „Mage/Paypal/Model/Ipn.php“ wird der von Paypal verarbeitete Betrag entgegengenommen und mit der Rechnung abgeglichen. Dies geschieht in meiner Magento-Version (1.7) in der Methode _registerPaymentCapture(). Dort prüfe ich einfach, 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 mir eine Nachkommastelle genug. Wenn dem so ist, ersetze ich den von Paypal gelieferten durch den von Magento erwarteten betrag. Damit bekommt Magento genau, was es will, und stellt keinen Betrugsverdacht mehr an.

$x_price = $this->_order->getBaseGrandTotal();
if(round($this->getRequestData('mc_gross'),1) == round($x_price, 1))
	$this->_request['mc_gross'] = $x_price;

Seitdem hatten wir keinen einzigen Fall mehr von fälschlichem Betrugsverdacht.

Umsetzen im Code

Um diesen Fix so sauber wie möglich einzubauen, einfach wie folgt vorgehen:

  1. Die Datei „Mage/Paypal/Model/Ipn.php“ von „app/code/core/“ nach „app/code/local“ kopieren
  2. In der Methode __registerPaymentCapture() den Code ganz an den Anfang setzen
  3. fertig

Ich hoffe, ich konnte dem einen oder anderen damit helfen.