PayPal#10413: Transaction refused because of an invalid argument
-
15-04-2021 - |
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
)
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