Add Custom Currency to Magento 2

As we all know Magento 2 does not support CryptoCurrency yet, so here we are going to learn how we can add a new currency.

The very first step to start with is to modify your module’s registration.php file

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Webkul_CryptoCurrency',
    __DIR__
);
require_once(__DIR__ . '/Override/CurrencyBundle.php');

Here is the code for the CurrencyBundle.php file, keep this fine in app/code/Vendor/Module/Override/CurrencyBundle.php

<?php
namespace Magento\Framework\Locale\Bundle;
class CurrencyBundle extends DataBundle
{
    /**
     * @var string
     */
    protected $path = 'ICUDATA-curr';
    /**
     * @var string
     */
    public function toArray($bundle)
    {
        $aux = [];
        foreach ($bundle as $k => $v) {
            $aux[$k] = is_object($v) ? $this->toArray($v) : $v;
        }
        return $aux;
    }
    /**
     * Method to get currency bundle
     *
     * @param string $locale
     * @return array
     */
    public function get($locale)
    {
        $bundle = parent::get($locale);
        $bundleAsArray = $this->toArray($bundle);
        $bundleAsArray['Currencies']['BTC'] = [
            'BTC',
            'Bitcoin',
        ];
        $bundleAsArray['CurrencyPlurals']['BTC'] = [
            'one' => 'Bitcoin',
            'other' => 'Bitcoin',
        ];
        return $bundleAsArray;
    }
}

Now we will add some plugins in order to add currency and its formating in Magento 2
Create a di.xml inside etc folder

<?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\Framework\Locale\Config">
        <plugin name="crypto_locale" type="Webkul\CryptoCurrency\Plugin\LocaleConfig" sortOrder="1" />
    </type>
    <type name="Magento\Framework\App\Config">
        <plugin name="crypto_config" type="Webkul\CryptoCurrency\Plugin\ConfigPlugin" sortOrder="1" />
    </type>
    <type name="Magento\Framework\Pricing\Render\Amount">
        <plugin name="crypto_framework_pricing_render_amount" type="Webkul\CryptoCurrency\Plugin\Framework\Pricing\Render\Amount" />
    </type>
    <type name="Magento\Directory\Model\PriceCurrency">
        <plugin name="crypto_directory_model_pricecurrency" type="Webkul\CryptoCurrency\Plugin\Directory\Model\PriceCurrency" />
    </type>
    
    <type name="Magento\Framework\Locale\Format">
        <plugin name="crypto_framework_locale_format" type="Webkul\CryptoCurrency\Plugin\Framework\Locale\Format" />
    </type>
</config>

Following the above we need to create 5 plugins as follows

LocaleConfig.php

<?php
namespace Webkul\CryptoCurrency\Plugin;
class LocaleConfig
{
    /**
     * After get allowed currencies
     *
     * @param \Magento\Framework\Locale\Config $config
     * @param array $currencies
     * @return array
     */
    public function afterGetAllowedCurrencies(\Magento\Framework\Locale\Config $config, $currencies)
    {
        return array_merge($currencies, ['BTC']);
    }
}

ConfigPlugin.php

<?php
namespace Webkul\CryptoCurrency\Plugin;
class ConfigPlugin
{
    /**
     * After get currency config value
     *
     * @param \Magento\Framework\App\Config\ScopeConfigInterface $subject
     * @param string $result
     * @param string $path
     * @param string $scope
     * @param string $scopeCode
     * @return string
     */
    public function afterGetValue(\Magento\Framework\App\Config\ScopeConfigInterface $subject,
        $result,
        $path = null,
        $scope = \Magento\Framework\App\Config\ScopeConfigInterface::SCOPE_TYPE_DEFAULT,
        $scopeCode = null
    )
    {
        if ($path === 'system/currency/installed') {
            return $result . ',' . 'BTC';
        }
        return $result;
    }
}

Amount.php

<?php
namespace Webkul\CryptoCurrency\Plugin\Framework\Pricing\Render;
use Magento\Framework\Pricing\PriceCurrencyInterface;
class Amount
{
  public function beforeFormatCurrency(
    $subject,
    $amount,
    $includeContainer = true,
    $precision = PriceCurrencyInterface::DEFAULT_PRECISION
  ) {
    return [$amount, $includeContainer, 4];
  }
}

PriceCurrency.php

<?php
namespace Webkul\CryptoCurrency\Plugin\Directory\Model;
class PriceCurrency
{
  public function beforeConvertAndRound(
    $subject,
    $amount,
    $scope = null,
    $currency = null,
    $precision = \Magento\Directory\Model\PriceCurrency::DEFAULT_PRECISION
  ) {
    return [$amount, $scope, $currency, 4];
  }
  public function beforeFormat(
    $subject,
    $amount,
    $includeContainer = true,
    $precision = \Magento\Directory\Model\PriceCurrency::DEFAULT_PRECISION,
    $scope = null,
    $currency = null
  ) {
    return [$amount, $includeContainer, 4, $scope, $currency];
  }
}

Format.php

<?php
namespace Webkul\CryptoCurrency\Plugin\Framework\Locale;
class Format
{
  public function afterGetPriceFormat($subject, $result) {
    $result['precision'] = 4;
    $result['requiredPrecision'] = 4;
    return $result;
  }
}

Using the above we are able to add a new currency in Magento 2
And It can be viewed on the admin side as new currency added

Leave a comment

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