28 March, 2024
Currency Conversion

Currency Conversion – Fixer API is Not Working in Magento 2

As of March 6th 2018, the legacy Fixer API (api.fixer.io) is deprecated and a completely re-engineered API is now accessible at https://data.fixer.io/api/ The core structure of the old API has remained unchanged, and need to perform a few simple changes in integration.

Existing api format :  http://api.fixer.io/latest?base={{CURRENCY_FROM}}&symbols={{CURRENCY_TO}

its mentioned in core module, path : [root]/vendor/magento/module-directory/Model/Currency/Import/FixerIo.php

Updated api format : http://data.fixer.io/api/latest?access_key=FIXER_API_KEY={{CURRENCY_FROM}}&symbols={{CURRENCY_TO}

We can not change directly in core module and it’s not a best practice. For that create a custom module with <mymodule>/<mypackage> and in app/code/[Vendor]/[Module]/etc/adminhtml/system.xml

Add the below code, to configure new API key from admin panel

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">

      <system>

       <section id=”currency” translate=”label” sortOrder=”60″ showInDefault=”1″ showInWebsite=”1″ showInStore=”1″>

           <tab>general</tab>

           <group id=”fixerio” sortOrder=”35″ showInDefault=”1″ showInWebsite=”0″ showInStore=”0″>

               <field id=”api_key” translate=”label,comment” type=”text” sortOrder=”0″ showInDefault=”1″ showInWebsite=”0″ showInStore=”0″>

                   <label>Api key</label>

                   <comment><![CDATA[New updated API now requires an access key and a new URL.]]></comment>

               </field>

           </group>

       </section>

   </system>

</config>

New API key is integrated in admin panel. Admin panel > Store > Configuration > Currency Setup > Fixer.io > Api key

In app/code/[Vendor]/[Module]/Model/Currency/Import/FixFixerIo.php file paste the below code :

<?php

namespace <mymodule>\<mypackage>\Model\Currency\Import;

use \Magento\Store\Model\ScopeInterface;

class FixFixerIo extends \Magento\Directory\Model\Currency\Import\FixerIo

{

   private $scopeConfig;

   const CURRENCY_CONVERTER_URL = ‘http://data.fixer.io/api/latest?base={{CURRENCY_FROM}}&symbols={{CURRENCY_TO}}&access_key=‘; // changed constant

   const API_KEY_CONFIG_PATH = ‘currency/fixerio/api_key’;

   public function __construct(

       \Magento\Directory\Model\CurrencyFactory $currencyFactory,

       \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,

       \Magento\Framework\HTTP\ZendClientFactory $httpClientFactory

   ) {

       $this->scopeConfig = $scopeConfig;

       parent::__construct($currencyFactory, $scopeConfig, $httpClientFactory);

   }

   /**

    * @return array

    * @override

    * @see \Magento\Directory\Model\Currency\Import\FixerIo::fetchRates()

    */

   public function fetchRates()

   {

       $data = [];

       $currencies = $this->_getCurrencyCodes();

       $defaultCurrencies = $this->_getDefaultCurrencyCodes();

       foreach ($defaultCurrencies as $currencyFrom) {

           if (!isset($data[$currencyFrom])) {

               $data[$currencyFrom] = [];

           }

           $data = $this->convertBatch($data, $currencyFrom, $currencies);

           ksort($data[$currencyFrom]);

       }

       return $data;

   }

   /**

    * @param array $data

    * @param string $currencyFrom

    * @param array $currenciesTo

    * @return array

    * @override

    * @see \Magento\Directory\Model\Currency\Import\FixerIo::convertBatch()

    */

   private function convertBatch($data, $currencyFrom, $currenciesTo)

   {

       $currenciesStr = implode(‘,’, $currenciesTo);

       $url = str_replace(‘{{CURRENCY_FROM}}’, $currencyFrom, self::CURRENCY_CONVERTER_URL);

       $url = str_replace(‘{{CURRENCY_TO}}’, $currenciesStr, $url);

       set_time_limit(0);

       try {

           $response = $this->getServiceResponse($url);

       } finally {

           ini_restore(‘max_execution_time’);

       }

       foreach ($currenciesTo as $currencyTo) {

           if ($currencyFrom == $currencyTo) {

               $data[$currencyFrom][$currencyTo] = $this->_numberFormat(1);

           } else {

               if (empty($response[‘rates’][$currencyTo])) {

                   $this->_messages[] = __(‘We can\’t retrieve a rate from %1 for %2.’, $url, $currencyTo);

                   $data[$currencyFrom][$currencyTo] = null;

               } else {

                   $data[$currencyFrom][$currencyTo] = $this->_numberFormat(

                       (double)$response[‘rates’][$currencyTo]

                   );

               }

           }

       }

       return $data;

   }

   /**

    * @param string $url

    * @param int $retry

    * @return array|mixed

    * @override

    * @see \Magento\Directory\Model\Currency\Import\FixerIo::convertBatch()

    */

   private function getServiceResponse($url, $retry = 0)

   {

       $accessKey = $this->scopeConfig->getValue(self::API_KEY_CONFIG_PATH, ScopeInterface::SCOPE_STORE);

       $url .= $accessKey;

       /** @var \Magento\Framework\HTTP\ZendClient $httpClient */

       $httpClient = $this->httpClientFactory->create();

       $response = [];

       try {

           $jsonResponse = $httpClient->setUri(

               $url

           )->setConfig(

               [

                   ‘timeout’ => $this->scopeConfig->getValue(

                       ‘currency/fixerio/timeout’,

                       \Magento\Store\Model\ScopeInterface::SCOPE_STORE

                   ),

               ]

           )->request(

               ‘GET’

           )->getBody();

           $response = json_decode($jsonResponse, true);

       } catch (\Exception $e) {

           if ($retry == 0) {

               $response = $this->getServiceResponse($url, 1);

           }

       }

       return $response;

   }

}

The code will rewrite the core model API structure into an updated format.

The Currency conversion API is based on the API plan purchased from https://apilayer.com/. If the currency symbol value is not converting from fixer api, then the changes can be carried through certain modifications in the admin panel. Select the list of unused currency symbol restricted in the admin panel and make the changes as given. Admin panel > Store > Configuration > Currency Setup >  Currency Options > Allowed currencies OR upgrade your plan.

The overall solution for the customization module for the above-stated issues can be in GitHub:

https://github.com/Nayana-chandran/magento2-fixerapi

 

Thanks for reading! Hope the entire solution would rectify issues of Fixer API.

Alex Sam is a digital marketer by choice & profession. He munches on topics relating to technology, eCommerce, enterprise mobility, Cloud Solutions and Internet of Things. His other interests lies in SEO, Online Reputation Management and Google Analytics. Follow Me Socially: Habr , Dev.to & Viblo .

Leave a Reply

Your email address will not be published. Required fields are marked *