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.
Leave a Reply