Question

My base currency is in Canadian Dollars (CAD)., when I go to PayPal express checkout, everything is working fine I can checkout in CAD.

PROBLEM IS: Whenever I switch currency to USD, USD is a conversion on my website. PayPal express throws an error:

PayPal gateway has rejected request. The totals of the cart item amounts do not match order amounts (#10413: Transaction refused because of an invalid argument. See additional error messages for details).

I debugged PAYPAL and here is the error I get when I checkout in USD (non base).. 110.00 USD ---> 150.00 CAD

[PAYMENTACTION] => Authorization
        [AMT] => 110.00
        [CURRENCYCODE] => USD
        [INVNUM] => 10000012
        [SOLUTIONTYPE] => Mark
        [LOCALECODE] => en_CA
        [ITEMAMT] => 150.00
        [TAXAMT] => 0.00
        [SHIPPINGAMT] => 0.00
        [METHOD] => SetExpressCheckout
        [VERSION] => 72.0
        [BUTTONSOURCE] => IWD_SI_MagentoCE_WPS
    )
Was it helpful?

Solution

The issue you faced is related to Magento bug due to which the logic of actions of TAX calculation is performed in the wrong order.

To resolve the problem, you just need to navigate to file:

app/code/core/Mage/Sales/Model/Config/Ordered.php

find _getSortedCollectorCodes() function and replace with below code

protected function _getSortedCollectorCodes()
    {
        if (Mage::app()->useCache('config')) {
            $cachedData = Mage::app()->loadCache($this->_collectorsCacheKey);
            if ($cachedData) {
                return unserialize($cachedData);
            }
        }
        $configArray = $this->_modelsConfig;
        // invoke simple sorting if the first element contains the "sort_order" key
        reset($configArray);
        $element = current($configArray);
        if (isset($element['sort_order']) && false) {
            uasort($configArray, array($this, '_compareSortOrder'));
            $sortedCollectors = array_keys($configArray);
        } else {

            $sortedCollectors = array_keys($configArray);

            foreach ($configArray as $code => &$data) {
                foreach ($data['before'] as $positionCode) {
                    if (!isset($configArray[$positionCode])) {
                        continue;
                    }
                    if (!in_array($code, $configArray[$positionCode]['after'], true)) {
                        // Also add additional after condition for related total,
                        // to keep it always after total with before value specified
                        $configArray[$positionCode]['after'][] = $code;
                    }
                    $currentPosition = array_search($code, $sortedCollectors, true);
                    $desiredPosition = array_search($positionCode, $sortedCollectors, true);
                    if ($currentPosition > $desiredPosition) {
                        // Only if current position is not corresponding to before condition
                        array_splice($sortedCollectors, $currentPosition, 1); // Removes existent
                        array_splice($sortedCollectors, $desiredPosition, 0, $code); // Add at new position
                    }
                }
            }

            // Sort out totals with after position specified
            foreach ($configArray as $code => &$data) {
                $maxAfter = null;
                $currentPosition = array_search($code, $sortedCollectors, true);
                foreach ($data['after'] as $positionCode) {
                    $maxAfter = max($maxAfter, array_search($positionCode, $sortedCollectors, true));
                }
                if ($maxAfter !== null && $maxAfter > $currentPosition) {
                    // Moves only if it is in front of after total
                    array_splice($sortedCollectors, $maxAfter + 1, 0, $code); // Add at new position
                    array_splice($sortedCollectors, $currentPosition, 1); // Removes existent
                }
            }
        }

        if (Mage::app()->useCache('config')) {
            Mage::app()->saveCache(serialize($sortedCollectors), $this->_collectorsCacheKey, array(
                    Mage_Core_Model_Config::CACHE_TAG
                )
            );
        }
        return $sortedCollectors;
    }

Note : Please override core file. Do not change core file. Clear cache

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top