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(7mo ago)035MITPHPPHP ^8.3

Since Oct 19Pushed 7mo agoCompare

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

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

31

—

LowBetter than 68% of packages

Maintenance65

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

211d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/858f92afec0ff81e6888c9ae6f363b56ebf82e45a32d9e1b37341569c5d1b267?d=identicon)[tetthys](/maintainers/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

[wenzhixin/bootstrap-table

An extended table to integration with some of the most widely used CSS frameworks. (Supports Bootstrap, Semantic UI, Bulma, Material Design, Foundation)

11.8k283.4k1](/packages/wenzhixin-bootstrap-table)[derekdowling/stubborn

Configurable call handler that is persistent against failures.

3615.7k](/packages/derekdowling-stubborn)[spatie/sidecar-shiki

Run Shiki highlighting with Sidecar

3610.2k](/packages/spatie-sidecar-shiki)

PHPackages © 2026

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