PHPackages                             tetthys/currency - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. tetthys/currency

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

tetthys/currency
================

Lightweight, framework-agnostic currency converter (fixed-scale decimal, PHP 8.3+).

0.0.1(8mo ago)035MITPHPPHP ^8.3

Since Oct 19Pushed 8mo agoCompare

[ Source](https://github.com/tetthys/currency)[ Packagist](https://packagist.org/packages/tetthys/currency)[ RSS](/packages/tetthys-currency/feed)WikiDiscussions dev Synced today

READMEChangelog (1)DependenciesVersions (2)Used By (0)

tetthys/currency
================

[](#tetthyscurrency)

> Lightweight, framework-agnostic currency converter for PHP 8.3+.
> Uses fixed-scale decimal math (`bcmath`) and pluggable exchange-rate providers.

---

📦 Installation
--------------

[](#-installation)

```
composer require tetthys/currency
```

Requires **PHP 8.3+** and the **bcmath** extension.

---

🚀 Quick Example
---------------

[](#-quick-example)

```
use Tetthys\Currency\Providers\CallableExchangeRateProvider;
use Tetthys\Currency\Services\CurrencyConverter;

$provider = new CallableExchangeRateProvider(
    fn(string $code) => match ($code) {
        'USD' => '1',
        'KRW' => '1380.00',
        'JPY' => '152.00',
        default => throw new RuntimeException("Unknown currency: {$code}"),
    }
);

$converter = new CurrencyConverter($provider);

echo $converter->amount('100')->from('USD')->to('KRW')->convert(); // "138000.00"
echo $converter->amount('138000')->from('KRW')->to('USD')->convert(); // "100.00"
```

---

🧩 Core Concepts
---------------

[](#-core-concepts)

### `ExchangeRateProviderInterface`

[](#exchangerateproviderinterface)

An interface that returns the *per-USD* rate for a given currency:

```
public function getPerUsd(string $currency): string;
```

Example: `getPerUsd('KRW')` → `"1380.00"` means **1 USD = 1380 KRW**.

### `CallableExchangeRateProvider`

[](#callableexchangerateprovider)

A tiny adapter that wraps a closure:

```
$provider = new CallableExchangeRateProvider(
    fn(string $currency) => match (strtoupper($currency)) {
        'USD' => '1',
        'EUR' => '0.91',
        'GBP' => '0.78',
        default => throw new RuntimeException('Unknown currency'),
    }
);
```

### `CurrencyConverter`

[](#currencyconverter)

Performs fixed-scale conversions using `bcmath`:

```
$converter = new CurrencyConverter($provider);

$result = $converter
    ->amount('250.50')
    ->from('USD')
    ->to('EUR')
    ->scale(4)
    ->convert(); // e.g. "227.9550"
```

---

⚙️ Creating Your Own Provider
-----------------------------

[](#️-creating-your-own-provider)

Implement `Tetthys\Currency\Contracts\ExchangeRateProviderInterface`:

```
use Tetthys\Currency\Contracts\ExchangeRateProviderInterface;
use Tetthys\Currency\Exceptions\CurrencyApiException;

final class MyApiProvider implements ExchangeRateProviderInterface
{
    public function getPerUsd(string $currency): string
    {
        $response = file_get_contents("https://example.com/api/latest/USD");
        $data = json_decode($response, true);

        return (string)($data['rates'][strtoupper($currency)]
            ?? throw new CurrencyApiException('Missing rate'));
    }
}
```

---

🧮 Notes
-------

[](#-notes)

- All arithmetic uses **BCMath** for precision and consistency.
- Scale (decimal places) defaults to **2**, configurable via `->scale(n)`.
- Same-currency conversions simply return the normalized value.

---

🪪 License
---------

[](#-license)

MIT © Tetthys Labs

###  Health Score

29

—

LowBetter than 57% of packages

Maintenance60

Regular maintenance activity

Popularity7

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity40

Maturing project, gaining track record

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

257d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/115064626?v=4)[tetthys](/maintainers/tetthys)[@tetthys](https://github.com/tetthys)

### Embed Badge

![Health badge](/badges/tetthys-currency/health.svg)

```
[![Health](https://phpackages.com/badges/tetthys-currency/health.svg)](https://phpackages.com/packages/tetthys-currency)
```

###  Alternatives

[silverstripe/subsites

Run multiple sites from a single SilverStripe install.

64400.9k21](/packages/silverstripe-subsites)[ayesh/php-timer

High-resolution and monotonic stop-watch for all your needs. Supports timer start, pause, resume, stop, read, and minimal conversion.

25235.3k13](/packages/ayesh-php-timer)[paxha/laravel-reportable

This Laravel Eloquent extension provides record according to dates using models.

111.3k](/packages/paxha-laravel-reportable)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
