Support the ongoing development of Laravel.io →
Article Hero Image

How to Get Currency Exchange Rates in Laravel

21 Oct, 2021 7 min read

Photo by Ibrahim Boran on Unsplash

Introduction

Sometimes when you're building web applications, you might need some functionality that deals with different currencies from around the world. To be able to work with different currencies, you need to find the exchange rates.

In this article, we're going to look at how to use the Laravel Exchange Rates package to interact with the exchangeratesapi.io API. We'll also take a look at how to use it to get the latest or historical exchange rates and convert monetary values between different currencies.

<p align="center"> <img src="https://ashallendesign.co.uk/images/custom/laravel-exchange-rates-logo.png" alt="Laravel Exchange Rates" width="600"> </p>

Installation

To get started with using the Laravel Exchange Rates package, we'll first need to run the following command to install it using Composer:

composer require ashallendesign/laravel-exchange-rates

Getting Your API Key

Now that we have the package installed, we'll need to get an API key from from https://exchangeratesapi.io/pricing. You can sign up for free or use the paid tiers, depending on which of the features you need to access.

Configuration

You can now publish the package's config file by using the following command:

php artisan vendor:publish --provider="AshAllenDesign\LaravelExchangeRates\Providers\ExchangeRatesProvider"

You should now have a new config/laravel-exchange-rates.php file. By default, the package's config is set up to make requests via HTTP. But, if you're in a production environment and are using one of the paid tiers of the API, I'd highly recommend using HTTPS instead. To do this, you can simply update the config file to and change the api_url field to start with https:// rather than http://:

return [
  
    // ...

    'api_url' => env('EXCHANGE_RATES_API_URL', 'http://api.exchangeratesapi.io/v1/'),

    // ...
  
];

You'll also need to make sure that you add your API key to your .env:

EXCHANGE_RATES_API_KEY={Your-API-Key-Here}

Getting Exchange Rates For a Single Date

To get the exchange for one currency to another, we can use the package's ->exchangeRate() method.

If we wanted to get the exchange rate for today from 'GBP' to 'EUR', we could write something like this:

$exchangeRates = new ExchangeRate();
$result = $exchangeRates->exchangeRate('GBP', 'EUR');

// $result: '1.10086'

However, if we wanted to get the exchange for a specific date, we could pass a Carbon date object of the day we wanted. As an example, if we wanted to get the exchange rate from 'GBP' to 'EUR' on the 1st January 2021, we could use the following:

$exchangeRates = new ExchangeRate();
$result = $exchangeRates->exchangeRate('GBP', 'EUR', Carbon::create('2021-01-01'));

// $result: '1.10086'

Getting the Exchange Rate Between Two Dates

If we want to get exchange rates between two currencies between a given date range, we can use the package's ->exchangeRateBetweenDateRange() method.

Let's imagine that we want to get the exchange rates from 'GBP' to 'EUR' for the past 3 days. We could write our code like so:

$exchangeRates = new ExchangeRate();
$result = $exchangeRates->exchangeRateBetweenDateRange(
    'GBP',
    'EUR',
    Carbon::now()->subDays(3),
    Carbon::now(),
);

// $result: [
//     '2021-07-07' => 1.1092623405
//     '2021-07-08' => 1.1120625424
//     '2021-07-09' => 1.1153867604
// ];

Converting Currencies For a Single Date

Not only does the package allow us to grab the exchange rates between currencies, it also allows us to convert monetary value from one currency to another. To do this we can use the ->convert() method.

For example, we could convert £1 'GBP' to 'EUR' at today's exchange rate:

$exchangeRates = new ExchangeRate();
$result = $exchangeRates->convert(100, 'GBP', 'EUR', Carbon::now());

// $result: 110.15884906

You might have noticed that we passed 100 as the first parameter. This is because the package requires us to pass monetary values in the currencies lowest denomination. For example, in this case, we wanted to convert £1, so we passed 100 because £1 is equal to 100 pence.

Converting Currencies Between Two Dates

Similar to getting the exchange rates between a date range, you can also convert monetary values from one currency to another using the package. To do this we can use the ->convertBetweenDateRange() method.

Let's imagine that we want to convert £1 'GBP' to 'EUR' using the exchange rates for the past 3 days. We could write our code like so:

$exchangeRates = new ExchangeRate();
$exchangeRates->convertBetweenDateRange(
    100,
    'GBP',
    'EUR',
    Carbon::now()->subDays(3),
    Carbon::now()
);

// $result: [
//     '2020-07-07' => 110.92623405,
//     '2020-07-08' => 111.20625424,
//     '2020-07-09' => 111.53867604,
// ];

Improving Performance by Using the Package's Caching

By default, all of the API responses from the exchangeratesapi.io API are cached by the package. This allows for significant performance improvements and reduced bandwidth from your server. It is also beneficial because it prevents you from using some of your monthly API requests if you've already fetched the exchange rate in the past.

However, if for any reason you require a fresh result from the API and not a cached result, the pacakge provides a ->shouldBustCache() method that we can use.

Let's take a look at how we could grab a fresh exchange rate from the API and ignore any cached rates:

$exchangeRates = new ExchangeRate();
$exchangeRates->shouldBustCache()->convert(100, 'GBP', 'EUR', Carbon::now());

Using the Package's Validation Rule

There may be times that you allow your users to choose currencies that are going to be converted. In this case, it's important to ensure that your users can only input a currency that is supported by the Exchange Rates API.

To help with this, Laravel Exchange Rates comes with its own ValidCurrency rule for validating currencies.

Let's imagine that we have a form request that is being used to validate a currency that is sent in a request. Our form request might look a bit like this:

<?php

namespace App\Http\Requests;

use AshAllenDesign\LaravelExchangeRates\Rules\ValidCurrency;
use Illuminate\Foundation\Http\FormRequest;

class MyAwesomeRequest extends FormRequest
{
    // ...
  
    public function rules(): array
    {
        return [
            'currency' => ['required', new ValidCurrency()],
        ];
    }
  
    // ...
}

Tests

If you're writing tests for code that deals with the Laravel Exchange Rates package, you'll likely want to prevent any API requests actually being made. For this reason, you'll probably want to instantiate the ExchangeRate class using dependency injection or using the package's provided facade. In fact, if you're interested in reading more about this type of thing, I'd recommend giving my How to Make Your Laravel App More Testable article a read.

Let's take a quick look at how we could write a basic test for a controller method that is fetching the exchange rate from 'GBP' to 'EUR' for today. Our controller might look like this:

use AshAllenDesign\LaravelExchangeRates\Classes\ExchangeRate;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class MyAwesomeController extends Controller
{
    public function __invoke(Request $request, ExchangeRate $exchangeRate): JsonResponse
    {
        $rate = $exchangeRates->exchangeRate('GBP', 'EUR');

        return response()->json(['rate' => $rate]);
    }
}

Now, let's write a test for this controller method. We'll make the assumption that the route name for the method is awesome.route. Our test could look something like this:

use AshAllenDesign\LaravelExchangeRates\Classes\ExchangeRate;
use Mockery\MockInterface;
use Tests\TestCase;

class MyAwesomeControllerTest extends TestCase
{
    /** @test */
    public function success_response_is_returned(): void
    {
        // Create the mock of the service class.
        $this->mock(ExchangeRate::class, function (MockInterface $mock): void {
            $mock->shouldReceive('exchangeRate')
                ->once()
                ->withArgs(['GBP', 'EUR'])
                ->andReturn(123.456);
        });
	
        $this->postJson(route('awesome.route'))
            ->assertExactJson([
                'rate' => 123.456
            ]);
    }
}

Conclusion

Hopefully, this article should have shown you how to use the Laravel Exchange Rates package to interact with the Exchange Rates API to get exchange rates and currency conversions. It should have also given you a brief insight into how to write tests for code that use the package.

If this post helped you out, I'd love to hear about it. Likewise, if you have any feedback to improve this post, I'd also love to hear that too.

If you're interested in getting updated each time I publish a new post, feel free to sign up for my newsletter.

Keep on building awesome stuff! 🚀

Last updated 3 weeks ago.

joedixon, bdsumon4u liked this article

2
Like this article? Let the author know and give them a clap!
ash-jc-allen (Ash Allen) I'm a freelance Laravel web developer from Preston, UK. I maintain the Ash Allen Design blog and get to work on loads of cool and exciting projects 🚀

Other articles you might like

Article Hero Image November 18th 2024

Laravel Custom Query Builders Over Scopes

Hello 👋 Alright, let's talk about Query Scopes. They're awesome, they make queries much easier to r...

Read article
Article Hero Image November 19th 2024

Access Laravel before and after running Pest tests

How to access the Laravel ecosystem by simulating the beforeAll and afterAll methods in a Pest test....

Read article
Article Hero Image November 11th 2024

🍣 Sushi — Your Eloquent model driver for other data sources

In Laravel projects, we usually store data in databases, create tables, and run migrations. But not...

Read article

We'd like to thank these amazing companies for supporting us

Your logo here?

Laravel.io

The Laravel portal for problem solving, knowledge sharing and community building.

© 2024 Laravel.io - All rights reserved.