0

I am currently developing an application using PHP that users could change the money currency of the products, like ebay or aliexpress do. So, if the user change his currency to USD all products prices are going to be converted to USD.

I have searched for an API to get real time currencies called CurrencyLayer. The API offers the following structure:

"success": true,
  "terms": "https://currencylayer.com/terms",
  "privacy": "https://currencylayer.com/privacy",
  "timestamp": 1432480209,
  "source": "USD",
  "quotes": {
    "USDAED": 3.67315,
    "USDAFN": 60.790001,
    "USDALL": 126.194504,
    "USDAMD": 477.359985,
    "USDANG": 1.790403,
    [...]
  }

My plan is to save this quotes every hour in my database. Considering a function that converts currencies, what would be the correct algorithm to convert one to other? I know it is not difficult but I could not figure it out.

function convertCurrency($currency1 = 'USD', $currency2 = 'EUR', $value){
   //Search the currency value and algorithm to convert   
   $newValue = (????)
   return $newValue;
}
fabionvs
  • 197
  • 12

2 Answers2

1

Quick heads up, since the result looks to be in JSON format, you first may want to call json_decode on the result to get it in PHP Object format.

Your API example after json_decode would look like this:

    // var_dump($api_result)
    stdClass Object
    (
        [success] => 1
        [terms] => https://currencylayer.com/terms
        [privacy] => https://currencylayer.com/privacy
        [timestamp] => 1432480209
        [source] => USD
        [quotes] => stdClass Object
            (
                [USDAED] => 3.67315
                [USDAFN] => 60.790001
                [USDALL] => 126.194504
                [USDAMD] => 477.359985
                [USDANG] => 1.790403
            )
    )

Next step is to use your function to combine both parameters to access the (for example) USDAED result:

<?php

    function convertCurrency($currency1 = 'USD', $currency2 = 'EUR', $value) {
        //Search the currency value and algorithm to convert
        $combined_currencies = $currency1.$currency2;
        return $api_result->quotes->$combined_currencies * $value;
    }

    echo convertCurrency("USD", "AED", 1); // 3.67315
Gary Thomas
  • 2,291
  • 1
  • 9
  • 21
  • Thank you bro! But, if I want to convert for exemple EUR to BRL with the information provided considering the source is USD? – fabionvs May 11 '18 at 00:44
  • @fabionvs Check out the REST API documentation. There is a title "Source Currency Switching", in which it shows you must request "&source=EUR" to the URL when making a request. Check it out here, about half way down: https://currencylayer.com/documentation – Gary Thomas May 11 '18 at 03:30
1

As mentioned by Gary Thomas already, the CurrencyLayer API documentation has a source currency switching parameter that allows you to switch the base currency from USD to whatever your $currency1 parameter is set to.

As I understand however, you want to be able to periodically query the CurrencyLayer API with only USD as the source currency, and perform the rate calculation yourself.

To achieve this, you need to convert:

  1. from CURRENCY 1 to USD
  2. from USD to CURRENCY 2

Which translates into code as:

function convertCurrency($currency1, $currency2, $value)
{
    $baseCurrency = 'USD';

    $quotes = [
        'USDCAD' => 1.28024,
        'USDEUR' => 0.838313,
        // ...
    ];

    $quote1 = $quotes[$baseCurrency . $currency1];
    $quote2 = $quotes[$baseCurrency . $currency2];

    return $value / $quote1 * $quote2;
}

convertCurrency('EUR', 'CAD', 10); // 15.271622890257

You can also use a money library such as brick/money, that handles these calculations (and much more) for you:

use Brick\Math\RoundingMode;
use Brick\Money\CurrencyConverter;
use Brick\Money\ExchangeRateProvider\ConfigurableProvider;
use Brick\Money\ExchangeRateProvider\BaseCurrencyProvider;
use Brick\Money\Money;

$provider = new ConfigurableProvider();
$provider->setExchangeRate('USD', 'CAD', 1.28024);
$provider->setExchangeRate('USD', 'EUR', 0.838313);

// This is where the magic happens!
$provider = new BaseCurrencyProvider($provider, 'USD');

$converter = new CurrencyConverter($provider);

$money = Money::of(10, 'EUR');
$converter->convert($money, 'CAD', RoundingMode::DOWN); // CAD 15.27

The BaseCurrencyProvider is designed for this very purpose, when you have a list of rates relative to a single currency, and want to convert between two arbitrary currencies in the list.

Note that in a real-world app, you would probably use a PDOProvider to load exchange rates directly from your database, instead of the ConfigurableProvider used above.

BenMorel
  • 34,448
  • 50
  • 182
  • 322