Fixer.io API – Free Currency Converter Stopped Working

apicurrencycurrency-ratesmagento2.2.3

Magento ver. 2.2.3

Seems today fixer.io stopped working.
It was the only service that still works for currency rates.
If I try to reach the url from web browser I get this

0   "#################################################################################################################################"
1   "#                                                                                                                               #"
2   "# IMPORTANT - PLEASE UPDATE YOUR API ENDPOINT                                                                                   #"
3   "#                                                                                                                               #"
4   "# This API endpoint is deprecated and has now been shut down. To keep using the Fixer API, please update your integration       #"
5   "# to use the new Fixer API endpoint, designed as a simple drop-in replacement.                                                  #"
6   "# You will be required to create an account at https://fixer.io and obtain an API access key.                                   #"
7   "#                                                                                                                               #"
8   "# For more information on how to upgrade please visit our Github Tutorial at: https://github.com/fixerAPI/fixer#readme          #"
9   "#                                                                                                                               #"
a   "#################################################################################################################################"

You can still get a free account, but code change needed to make it works with new API.

Does anybody know if a fix coming with the next upgrade of Magento?

Alternatively in Magento 1.9.3.8 I'm getting currency rates from here, by custom module.

Does one already exist that use this service?

If there are no answers to these questions, the only solution will be to write a new custom module.

I hope for an escape…

Best Answer

The Free Currency Converter API module:

app/code/MyCompany/FreeCurrencyConverter/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="MyCompany_FreeCurrencyConverter" setup_version="1.0.0">
        <sequence>
            <module name="Magento_Directory"/>
        </sequence>
    </module>
</config>

app/code/MyCompany/FreeCurrencyConverter/etc/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Directory\Model\Currency\Import\Config">
        <arguments>
            <argument name="servicesConfig" xsi:type="array">
                <item name="fcc" xsi:type="array">
                    <item name="label" xsi:type="string">Free Currency Converter</item>
                    <item name="class" xsi:type="string">MyCompany\FreeCurrencyConverter\Model\Currency\Import\Fcc</item>
                </item>
            </argument>
        </arguments>
    </type>
</config>

app/code/MyCompany/FreeCurrencyConverter/etc/config.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
    <default>
        <currency>
            <fcc>
                <timeout>100</timeout>
                <delay>1</delay>
            </fcc>
        </currency>
    </default>
</config>

app/code/MyCompany/FreeCurrencyConverter/etc/adminhtml/system.xml

<?xml version="1.0"?>
<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">
            <group id="fcc" translate="label" sortOrder="41" showInDefault="1" showInWebsite="0" showInStore="0">
                <label>Free Currency Converter</label>
                <field id="timeout" translate="label" type="text" sortOrder="0" showInDefault="1" showInWebsite="0" showInStore="0">
                    <label>Connection Timeout in Seconds</label>
                </field>
                <field id="delay" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="0" showInStore="0">
                    <label>Connection Delay Time in Seconds</label>
                </field>
            </group>
        </section>
    </system>
</config>

app/code/MyCompany/FreeCurrencyConverter/Model/Currency/Import/Fcc.php

<?php
namespace MyCompany\FreeCurrencyConverter\Model\Currency\Import;
class Fcc extends \Magento\Directory\Model\Currency\Import\AbstractImport
{
    /**
     * @var string
     */
    const CURRENCY_CONVERTER_URL = 'https://free.currencyconverterapi.com/api/v3/convert?q={{CURRENCY_FROM}}_{{CURRENCY_TO}}';
    /**
     * HTTP client
     *
     * @var \Magento\Framework\HTTP\ZendClient
     */
    protected $_httpClient;
    /**
     * Core store config
     *
     * @var \Magento\Framework\App\Config\ScopeConfigInterface
     */
    protected $_scopeConfig;
    /**
     * @param \Magento\Directory\Model\CurrencyFactory $currencyFactory
     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
     */
    protected $jsonHelper;

    public function __construct(
        \Magento\Directory\Model\CurrencyFactory $currencyFactory,
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        \Magento\Framework\Json\Helper\Data $jsonHelper
    ) {
        parent::__construct($currencyFactory);
        $this->_scopeConfig = $scopeConfig;
        $this->_httpClient = new \Magento\Framework\HTTP\ZendClient();
        $this->jsonHelper = $jsonHelper;
    }
    /**
     * @param string $currencyFrom
     * @param string $currencyTo
     * @param int $retry
     * @return float|null
     */
    protected function _convert($currencyFrom, $currencyTo, $retry = 0)
    {
        $url = str_replace('{{CURRENCY_FROM}}', $currencyFrom, self::CURRENCY_CONVERTER_URL);
        $url = str_replace('{{CURRENCY_TO}}', $currencyTo, $url);
        try {
            sleep($this->_scopeConfig->getValue(
                'currency/fcc/delay',
                \Magento\Store\Model\ScopeInterface::SCOPE_STORE
            ));
            $response = $this->_httpClient->setUri(
                $url
            )->setConfig(
                [
                    'timeout' => $this->_scopeConfig->getValue(
                        'currency/fcc/timeout',
                        \Magento\Store\Model\ScopeInterface::SCOPE_STORE
                    ),
                ]
            )->request(
                'GET'
            )->getBody();
            $resultKey = $currencyFrom.'_'.$currencyTo;
            $data = $this->jsonHelper->jsonDecode($response);
            $results = $data['results'][$resultKey];
            $queryCount = $data['query']['count'];
            if( !$queryCount &&  !isset($results)) {
                $this->_messages[] = __('We can\'t retrieve a rate from %1.', $url);
                return null;
            }
            return (float)$results['val'];
        } catch (\Exception $e) {
            if ($retry == 0) {
                $this->_convert($currencyFrom, $currencyTo, 1);
            } else {
                $this->_messages[] = __('We can\'t retrieve a rate from %1.', $url);
            }
        }
    }
}

enjoy!

EDIT:

as Bizzy Bee says:

Don't forget the following file to get it all going properly:

app/code/MyCompany/FreeCurrencyConverter/registration.php

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'MyCompany_FreeCurrencyConverter',
    __DIR__
);
?>