0
votes

Synopsis: PayPal payment module from Magento will not convert currency to USD or any paypal accepted currency if your base currency is other than those listed here https://www.paypal.com/us/webapps/helpcenter/helphub/article/?solutionId=FAQ2390

I have a Magento installation with 3 currencies installed.

I use PayPal standard payments as a payment option but the problem is that users are charged the same amount but in USD. For example if I have 100 RON and choose to pay by paypal i will be charged for 100 USD instead.

I checked the paypal module that makes the redirection available in

app/code/core/Mage/Paypal/Block/Standard/Redirect.php

and the variables related to currency and amount are correctly set and sent to paypal.

I do not know exactly how to tackle this issue and it is very frustrating as I guess the standard PayPal module in Magento is designed by PayPal (needs confirmation) and is verified for this kind of situations.

Info #1: PayPal does not accept some currencies (like Romanian Lei for example which happens to be the base currency for this shop) for transactions (allowed currencies are listed here https://www.paypal.com/us/webapps/helpcenter/helphub/article/?solutionId=FAQ2390) so by the time you click submit they will convert only the currency sign (to $) and not the amount. The amount you will have to change yourself, however the default PayPal module in Magento (v 1.5) is not doing this and this is why I opened this question.

EDIT #1

I tried the solution proposed down below but it did not work as in fact it replaces some of the variables but not in the desired way.

There are two options I see here:

Option #1: 'find and replace' option is where I find all the float values in the final form and replace them with the values converted to USD. However this is not a viable option because is not converting the values correctly and error may occur.

Option #2:

I found the functions that pop out the values in the form and it is located in spp/code/core/Mage/Paypal/Model/Api/Abstract.php

protected function _exportLineItems(array &$request, $i = 0)
    {
        if (!$this->_cart) {
            return;
        }

        // always add cart totals, even if line items are not requested
        if ($this->_lineItemTotalExportMap) {
            foreach ($this->_cart->getTotals() as $key => $total) {
                if (isset($this->_lineItemTotalExportMap[$key])) { // !empty($total)
                    $privateKey = $this->_lineItemTotalExportMap[$key];
                    $request[$privateKey] = $this->_filterAmount($total);
                }
            }
        }

        // add cart line items
        $items = $this->_cart->getItems();
        if (empty($items) || !$this->getIsLineItemsEnabled()) {
            return;
        }
        $result = null;
        foreach ($items as $item) {
            foreach ($this->_lineItemExportItemsFormat as $publicKey => $privateFormat) {
                $result = true;
                $value = $item->getDataUsingMethod($publicKey);
                if (isset($this->_lineItemExportItemsFilters[$publicKey])) {
                    $callback   = $this->_lineItemExportItemsFilters[$publicKey];
                    $value = call_user_func(array($this, $callback), $value);
                }
                if (is_float($value)) {
                    $value = $this->_filterAmount($value);
                }
                $request[sprintf($privateFormat, $i)] = $value;
            }
            $i++;
        }
        return $result;
    }

These 2 lines:

$request[$privateKey] = $this->_filterAmount($total);
$value = $this->_filterAmount($value);

print out the amount in the list of variables so instead of the function _filterAmount I have written the following function that should convert the amount from any base currency to USD based on the exchange rates defined in backend:

protected function _convertAmounttoUSD($value)
    {
        $baseCode = Mage::app()->getBaseCurrencyCode();
        $fromCur = Mage::app()->getStore()->getCurrentCurrencyCode();
        $toCur = 'USD';
        $allowedCurrencies = Mage::getModel('directory/currency')->getConfigAllowCurrencies();
        $rates = Mage::getModel('directory/currency')->getCurrencyRates($baseCode, array_values($allowedCurrencies));

        $output = ( $value * $rates[$toCur] ) / $rates[$fromCur];

        return sprintf('%.2F', $output);
    }

And I have replaced the lines above with the following:

$request[$privateKey] = $this->_convertAmounttoUSD($total);
$value = $this->_convertAmounttoUSD($value);

The problem is that the values do not get converted.

1
Is your issue solved? could you pls help me @ magento.stackexchange.com/q/186198/51361Gem

1 Answers

2
votes

In magento when user get redirected to paypal it magento send store currency to charge but paypal use currency which associated in paypal account so we need to convert it to paypal account currency.

It will charge 100RON but convert it into USD currency.

you need to change in below file with below function: app\code\core\Mage\Paypal\Model\Standard.php Replace the getStandardCheckoutFormFields function with below function:

public function getStandardCheckoutFormFields()
{
    $orderIncrementId = $this->getCheckout()->getLastRealOrderId();
    $order = Mage::getModel('sales/order')->loadByIncrementId($orderIncrementId);
    $api = Mage::getModel('paypal/api_standard')->setConfigObject($this->getConfig());
    $api->setOrderId($orderIncrementId)
        ->setCurrencyCode($order->getBaseCurrencyCode())
        //->setPaymentAction()
        ->setOrder($order)
        ->setNotifyUrl(Mage::getUrl('paypal/ipn/'))
        ->setReturnUrl(Mage::getUrl('paypal/standard/success'))
        ->setCancelUrl(Mage::getUrl('paypal/standard/cancel'));

    // export address
    $isOrderVirtual = $order->getIsVirtual();
    $address = $isOrderVirtual ? $order->getBillingAddress() : $order->getShippingAddress();
    if ($isOrderVirtual) {
        $api->setNoShipping(true);
    } elseif ($address->validate()) {
        $api->setAddress($address);
    }

    // add cart totals and line items
    $api->setPaypalCart(Mage::getModel('paypal/cart', array($order)))
        ->setIsLineItemsEnabled($this->_config->lineItemsEnabled)
    ;
    $api->setCartSummary($this->_getAggregatedCartSummary());


    $result = $api->getStandardCheckoutRequest();

    $baseCode = Mage::app()->getBaseCurrencyCode();
    $fromCur = Mage::app()->getStore()->getCurrentCurrencyCode();
    $toCur = 'USD';

    $allowedCurrencies = Mage::getModel('directory/currency')->getConfigAllowCurrencies();
    $rates = Mage::getModel('directory/currency')->getCurrencyRates($baseCode, array_values($allowedCurrencies));
    $result['amount'] = round((($order->getGrandTotal() * $rates[$toCur])/$rates[$fromCur]),2);

    $result['currency_code'] = $toCur;

    $j = 0;
    $items = $order->getAllItems();

    foreach ($items as $itemId => $item)
    {
        if ($item->getParentItem()) {
            continue;
        }
        $j ++;
        $result['amount_'.$j] = round((($item->getPrice() * $rates[$toCur])/$rates[$fromCur]),2);
    }
    $j++;
    $result['country']          = $order->getBillingAddress()->getCountryId();
    $shippingSpo            = $order->getBaseShippingAmount();
    $result['shipping']         = round((($shippingSpo * $rates[$toCur])/$rates[$fromCur]),2);
    $result['discount_amount']  = -1*round((($order->getDiscountAmount() * $rates[$toCur])/$rates[$fromCur]),2);
    $result['discount_amount_cart'] = $result['discount_amount'];

    $result['amount_'.$j] = $result['shipping'];

    unset($result['discount_amount']);
    unset($result['shipping']);
    unset($result['discount_amount_cart']);
    unset($result['amount_'.$j]);
    return $result;
}