Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/otherguy/php-currency-api

Standardized wrapper for popular currency rate APIs. Currently supports FixerIO, CurrencyLayer, Open Exchange Rates and Exchange Rates API.
https://github.com/otherguy/php-currency-api

api-wrapper composer-package currency currency-api currency-conversion currency-converter currency-converter-php currency-exchange currency-exchange-rates currency-rate-apis exchange-rate-api exchange-rates exchange-rates-api fluent-interface php-library php-package php73 php74 php8

Last synced: 2 days ago
JSON representation

Standardized wrapper for popular currency rate APIs. Currently supports FixerIO, CurrencyLayer, Open Exchange Rates and Exchange Rates API.

Awesome Lists containing this project

README

        

# 💱 Wrapper for popular Currency Exchange Rate APIs

_A PHP API Wrapper to offer a unified programming interface for popular Currency Rate APIs._

[![Version](https://img.shields.io/packagist/v/otherguy/php-currency-api.svg?style=flat-square)](https://packagist.org/packages/otherguy/php-currency-api)
[![Installs](https://img.shields.io/packagist/dt/otherguy/php-currency-api?color=blue&label=installs&style=flat-square)](https://packagist.org/packages/otherguy/php-currency-api)
[![PHP version](https://img.shields.io/packagist/php-v/otherguy/php-currency-api?style=flat-square)](https://packagist.org/packages/otherguy/php-currency-api)
[![Travis CI](https://img.shields.io/travis/com/otherguy/php-currency-api.svg?style=flat-square)](https://travis-ci.com/otherguy/php-currency-api)
[![Coverage](https://img.shields.io/coveralls/otherguy/php-currency-api.svg?style=flat-square)](https://coveralls.io/github/otherguy/php-currency-api?branch=master)
[![Coverage](https://img.shields.io/codeclimate/coverage-letter/otherguy/php-currency-api.svg?style=flat-square)](https://codeclimate.com/github/otherguy/php-currency-api)
[![Maintainability](https://img.shields.io/codeclimate/maintainability/otherguy/php-currency-api.svg?style=flat-square)](https://codeclimate.com/github/otherguy/php-currency-api)
[![License](https://img.shields.io/github/license/otherguy/php-currency-api.svg?style=flat-square&color=orange)](LICENSE.md)

Dont worry about your favorite currency conversion service suddenly shutting down or switching plans on you. Switch away easily, without changing your code.

## Inspiration 💅

I needed a currency conversion API for my travel website but could not find a good PHP package. The idea of the
[`Rackbeat/php-currency-api`](https://github.com/Rackbeat/php-currency-api) package came closest but unfortunately it
was just a stub and not implemented.

## Features 🌈

* Support for [multiple different APIs](#supported-apis-) through the use of drivers
* A [fluent interface](#fluent-interface) to make retrieving exchange rates convenient and fast
* Consistent return interface that is independent of the driver being used
* [Calculations](#conversion-result) can be made based on the returned data

## Supported APIs 🌐

| Service | Identifier |
|------------------------------------------------------|---------------------|
| [FixerIO](https://fixer.io) | `fixerio` |
| [CurrencyLayer](https://currencylayer.com) | `currencylayer` |
| [Open Exchange Rates](https://openexchangerates.org) | `openexchangerates` |
| [Exchange Rates API](https://exchangeratesapi.io) | `exchangeratesapi` |

_If you want to see more services added, feel free to [open an issue](https://github.com/otherguy/php-currency-api/issues)!_

## Prerequisites 📚

* `PHP 8.x` or `PHP 7.3+` or higher (tested on both `7.3` and `7.4`)
* The [`composer`](https://getcomposer.org) dependency manager for PHP
* An account with one or more of the [API providers](#supported-apis-) listed above

## Installation 🚀

Simply require the package using `composer` and you're good to go!

```bash
$ composer require otherguy/php-currency-api
```

## Usage 🛠

### Currency Symbol Helper

The [`Otherguy\Currency\Symbol`](src/Symbol.php) class provides constants for each supported currency.

> !**Note:** You are not required to use `Otherguy\Currency\Symbol` to specify symbols. It's simply a convenience helper
> and does not need to be used. You can simply pass strings like `'USD', 'EUR', ...` to all methods.

```php
// 'USD'
$symbol = Otherguy\Currency\Symbol::USD;
```

Use the `all()` method to retrieve an array of all currency symbols:

```php
// [ 'AED', 'AFN', ... 'ZWL' ]
$symbols = Otherguy\Currency\Symbol::all();
```

The `names()` method returns an associative array with currency names instead:

```php
// [ 'AED' => 'United Arab Emirates Dirham', 'AFN' => 'Afghan Afghani', ... ]
$symbols = Otherguy\Currency\Symbol::names();
```

To get the name of a single currency, use the `name()` method:

```php
// 'United States Dollar'
$symbols = Otherguy\Currency\Symbol::name(Otherguy\Currency\Symbol::USD);
```

### Initialize API Instance

```php
$currency = Otherguy\Currency\DriverFactory::make('fixerio'); // driver identifier from supported drivers.
```

To get a list of supported drivers, use the `getDrivers()` method:

```php
// [ 'mock', 'fixerio', 'currencylayer', ... ]
$drivers = Otherguy\Currency\DriverFactory::getDrivers()
```

### Set Access Key

Most API providers require you to sign up and use your issued access key to authenticate against their API. You can
specify your access key like so:

```php
$currency->accessKey('your-access-token-goes-here');
```

### Set Configuration Options

To set further configuration options, you can use the `config()` method. An example is
[CurrencyLayer's JSON formatting option](https://currencylayer.com/documentation#format).

```php
$currency->config('format', '1');
```

### Set Base Currency

You can use either `from()` or `source()` to set the base currency. The methods are identical.

> !**Note:** Each driver sets its own default base currency. [FixerIO](https://fixer.io) uses `EUR` as base currency
> while [CurrencyLayer](https://currencylayer.com) uses `USD`.

Most services only allow you to change the base currency in their paid plans. The driver will throw a
`Otherguy\Currency\Exceptions\ApiException` if your current plan does not allow changing the base currency.

```php
$currency->source(Otherguy\Currency\Symbol::USD);
$currency->from(Otherguy\Currency\Symbol::USD);
```

### Set Return Currencies

You can use either `to()` or `symbols()` to set the return currencies. The methods are identical. Pass a single currency
or an array of currency symbols to either of these methods.

> !**Note:** Pass an empty array to return all currency symbols supported by this driver. This is the default if you
> don't call the method at all.

```php
$currency->to(Otherguy\Currency\Symbol::BTC);
$currency->symbols([Otherguy\Currency\Symbol::BTC, Otherguy\Currency\Symbol::EUR, Otherguy\Currency\Symbol::USD]);
```

### Latest Rates

This retrieves the most recent exchange rates and returns a [`ConversionResult`](#conversion-result) object.

```php
$currency->get(); // Get latest rates for selected symbols, using set base currency
$currency->get('DKK'); // Get latest rates for selected symbols, using DKK as base currency
```

### Historical Rates

To retrieve historical exchange rates, use the `historical()` method. Note that you need to specify a date either as a
method parameter or by using the `date()` methods. See [Fluent Interface](#fluent-interface) for more information.

```php
$currency->date('2010-01-01')->historical();
$currency->historical('2018-07-01');
```

### Convert Amount

Use the `convert()` method to convert amounts between currencies.

> !**Note:** Most API providers don't allow access to this method using your free account. You can still use the
> [Latest Rates](#latest-rates) or [Historical Rates](#historical-rates) endpoints and perform calculations or conversions
> on the [`ConversionResult`](#conversion-result) object.

```php
$currency->convert(10.00, 'USD', 'THB'); // Convert 10 USD to THB
$currency->convert(122.50, 'NPR', 'EUR', '2019-01-01'); // Convert 122.50 NPR to EUR using the rates from January 1st, 2019
```

### Fluent Interface

Most methods can be used with a _fluent interface_, allowing you to chain method calls for more readable code:

```php
// Namespaces are omitted for readability!
DriverFactory::make('driver')->from(Symbol::USD)->to(Symbol::EUR)->get();
DriverFactory::make('driver')->from(Symbol::USD)->to(Symbol::NPR)->date('2013-03-02')->historical();
DriverFactory::make('driver')->from(Symbol::USD)->to(Symbol::NPR)->amount(12.10)->convert();
```

### Conversion Result

The [`get()`](#latest-rates) and [`historical()`](#historical-rates) endpoints return a
[`ConversionResult`](src/Results/ConversionResult.php) object. This object allows you to perform calculations and
conversions easily.

> !**Note:** Even though free accounts of most providers do not allow you to change the base currency, you can still
> use the `ConversionResult` object to change the base currency later. This might not be as accurate as changing the
> base currency directly, though.

> !**Note:** To convert between two currencies, you need to request both of them in your initial [`get()`](#latest-rates)
> or [`historical()`](#historical-rates) request. You can not convert between currencies that have not been fetched!

See the following code for some examples of what you can do with the `ConversionResult` object.

```php
$result = DriverFactory::make('driver')->from(Symbol::USD)->to([Symbol::EUR, Symbol::GBP])->get();

// [ 'USD' => 1.00, 'EUR' => 0.89, 'GBP' => 0.79 ]
$result->all();

// 'USD'
$result->getBaseCurrency();

// '2019-06-11'
$result->getDate();

// 0.89
$result->rate(Symbol::EUR);

// CurrencyException("No conversion result for BTC!");
$result->rate(Symbol::BTC);

// 5.618
$result->convert(5.0, Symbol::EUR, Symbol::USD);

// [ 'USD' => 1.13, 'EUR' => 1.00, 'GBP' => 0.89 ]
$result->setBaseCurrency(Symbol::EUR)->all();

// 1.12
$result->setBaseCurrency(Symbol::GBP)->rate(Symbol::EUR);
```

## Contributing 🚧

[Pull Requests](https://github.com/otherguy/php-currency-api/pulls) are more than welcome! I'm striving for 100% test
coverage for this repository so please make sure to add tests for your code.