Implementing a Custom Exchange Rate Provider

This tutorial will show you how to add a custom exchange rate provider by implementing the ExchangeRateProvider interface.

An exchange rate provider uses a data source to perform the exchange calculation between currencies. Liferay Commerce provides one exchange rate provider out-of-the-box, ECBExchangeRateProvider.

Out-of-the-box exchange rate provider


  1. Deploy an Example

  2. Walk Through the Example

  3. Additional Information

Deploy an Example

In this section, we will get an example exchange rate provider up and running on your instance of Liferay Commerce.

Start a new Liferay instance by running

docker run -it -m 8g -p 8080:8080 liferay/portal:

Sign in to Liferay at http://localhost:8080. Use the email address and the password test. When prompted, change the password to learn.

Then, follow these steps:

  1. Download and unzip the Acme Commerce Exchange Rate Provider.

    curl -O
  2. Go to liferay-f2y1.

    cd liferay-f2y1
  3. Build and deploy the example.

    ./gradlew deploy$(docker ps -lq)


    This command is the same as copying the deployed jars to /opt/liferay/osgi/modules on the Docker container.

  4. Confirm the deployment in the Docker container console.

    STARTED com.acme.f2y1.impl_1.0.0
  5. Verify that the example exchange rate provider was added. Open your browser to https://localhost:8080. Then click the Applications Menu (Applications Menu) and navigate to CommerceCurrencies. The new exchange rate provider (“f2y1”) will be present under the Exchange Rate Provider dropdown.


In Liferay Commerce 2.1 and earlier, find the exchange rates by navigating to Control PanelCommerceSettingsCurrenciesExchange Rate. The new exchange rate provider (“f2y1”) will be present under the Exchange Rate Provider dropdown.

New exchange rate provider

Congratulations, you’ve successfully built and deployed a new exchange rate provider that implements ExchangeRateProvider.

Next, let’s dive deeper to learn more.

Walk Through the Example

In this section, we will review the example we deployed. First, we will annotate the class for OSGi registration. Second, we will review the ExchangeRateProvider interface. And third, we will complete our implementation of ExchangeRateProvider.

Annotate the Class for OSGi Registration

    immediate = true, property = "",
    service = ExchangeRateProvider.class
public class F2Y1ExchangeRateProvider implements ExchangeRateProvider {

It is important to provide a distinct key for the exchange rate provider so that Liferay Commerce can distinguish the new exchange rate provider from others in the exchange rate provider registry. Reusing a key that is already in use will override the existing associated exchange rate provider.

Review the ExchangeRateProvider Interface

Implement the following method:

public BigDecimal getExchangeRate(
        CommerceCurrency primaryCommerceCurrency,
        CommerceCurrency secondaryCommerceCurrency)
    throws Exception;

This method is called to calculate the exchange rate between currencies. The chosen data source for the rates must be able to handle any of the currencies that may be used in your instance of Liferay Commerce.

Complete the Exchange Rate Provider

The exchange rate provider is comprised of logic to calculate the exchange rates between two currencies. Do the following:

Implement the Exchange Rate Calculation Logic

public BigDecimal getExchangeRate(
        CommerceCurrency primaryCommerceCurrency,
        CommerceCurrency secondaryCommerceCurrency)
    throws Exception {

    return new BigDecimal(
        _getExchangeRate(secondaryCommerceCurrency) /

private Double _getExchangeRate(CommerceCurrency commerceCurrency) {
    String code = StringUtil.toUpperCase(commerceCurrency.getCode());

    return _exchangeRates.get(code);

private Map<String, Double> _exchangeRates = new HashMap<String, Double>() {
        put("AUD", 1.9454);
        put("BRL", 5.15262);
        put("CAD", 1.84981);
        put("CHF", 1.36562);
        put("CLP", 947.813);
        put("CNY", 9.49073);
        put("CZK", 31.0599);
        put("DKK", 9.04642);
        put("EUR", 1.21177);
        put("GBP", 1.09733);
        put("HKD", 10.9628);
        put("HUF", 390.23);
        put("IDR", 19698.8);
        put("ILS", 5.12143);
        put("INR", 98.562);
        put("JPY", 150.862);
        put("KRW", 1567.74);
        put("MXN", 26.7972);
        put("MYR", 5.72459);
        put("NOK", 11.8138);
        put("NZD", 2.05827);
        put("PHP", 73.2097);
        put("PKR", 194.073);
        put("PLN", 5.22207);
        put("RUB", 93.4562);
        put("SEK", 12.4178);
        put("SGD", 1.88797);
        put("THB", 44.6128);
        put("USD", 1.39777);
        put("ZAR", 19.3996);

This example uses a map of exchange rates. See ECBExchangeRateProvider for a more practical use case. See _getStaticExchangeRates and _getRateForCode by visiting

Use the CommerceCurrency object for the two currencies to get the information needed, like their currency codes. See and to find more methods you can use with a CommerceCurrency object.


Congratulations! You now know the basics for implementing the ExchangeRateProvider interface, and have added a new exchange rate provider to Liferay Commerce.

Additional Information