Convert price in Magento

The story

You have the best web shop in the world and you want to make your customers shopping experience like at their local stores: kind, friendly, shop in their native language with local currency. Good customer service is the key to upping your conversion rate.

But(like every story with a point, there is but), your payment processor does not support all currencies that your shop supports.
So, the natural solution would be to convert order total into one of the supported currencies by your payment processor.

The general solution

Converting price in Magento is fairly easy:

  1. // Convert million dollar order into euros ($_$)
  2. $priceUSD = $order->getGrandTotal(); // $1 000 000
  3. $fromCurrency = 'USD';
  4. $toCurrency = 'EUR';
  5. $priceEUR = Mage::helper('directory')->currencyConvert($priceUSD, $fromCurrency, $toCurrency);

The Fatal Error

You broke your site when you tried to convert currency, didn't you?

  1. Fatal error: Call to a member function getCode() on a non-object in app/code/core/Mage/Directory/Model/Currency.php on line 194

This means that your $toCurrency currency rate is missing in the database. There are 2 reasons for this:

  1. You are trying to convert into currency which is not in the list of Allowed Currencies in "System > Configuration > Currency setup" - in this case just select your favourite currencies, import rates and you are good to go.
  2. Your currency is already in Allowed Currencies list but you are trying to convert from foreign currency into the Base currency of the store.

Just open directory_currency_rate table in the database and you will see that your combination of 'From' => 'To' conversion is missing.
The reason for this simple: There is no need to convert to base currency(at least for prices in products,quotes, orders, ...) because the prices are already converted from base currency into needed foreign currency.

The solution

But you still need that currency conversion, right?
Don't worry, there is a solution :)

I said that there is no need to convert to base currency because Magento keeps these prices in the object with Base prefix.
Let's assume that your store's base currency is Euro, but your customer made million dollar order in US Dollars. Let's modify previous example:

  1. // Convert million dollar order into euros ($_$)
  2. $priceUSD = $order->getGrandTotal(); // $1 000 000
  3. $priceEUR = $order->getBaseGrandTotal(); // 801 680.33 €

Now you can send $priceEUR to your payment processor and let your customer complete his order.