Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Iso Currencies Laravel Package

moneyphp/iso-currencies

Provides an up-to-date ISO 4217 currency list sourced from the official ISO Maintenance Agency (currency-iso.org). Designed primarily for moneyphp/money, with composer commands to install and fetch updates for currency data.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Install the Package Add the package to your Laravel project via Composer:

    composer require moneyphp/iso-currencies
    

    For Laravel, also install the optional moneyphp/money package if not already present:

    composer require moneyphp/money
    
  2. Update Currencies Fetch the latest ISO 4217 currency data (including historical flags like BGN):

    composer fetch-update
    

    This updates the static currency dataset from the ISO Maintenance Agency.

  3. First Use Case: Validate a Currency Use the CurrencyRepository to check if a currency code is valid and its status (active/historic):

    use Money\Currency\CurrencyRepository;
    use Money\Currency\ISO4217;
    
    $repository = new CurrencyRepository();
    $currency = $repository->getCurrency('EUR'); // Returns ISO4217 object
    $isValid = $repository->exists('EUR'); // true
    $isHistoric = $repository->getCurrency('BGN')->isHistoric(); // true (post-2026)
    
  4. Laravel Integration (Optional) Bind the CurrencyRepository to Laravel’s service container in AppServiceProvider:

    use Illuminate\Support\ServiceProvider;
    use Money\Currency\CurrencyRepository;
    
    class AppServiceProvider extends ServiceProvider
    {
        public function register()
        {
            $this->app->singleton(CurrencyRepository::class, function () {
                return new CurrencyRepository();
            });
        }
    }
    

    Now inject CurrencyRepository into controllers/services:

    use Money\Currency\CurrencyRepository;
    
    class PaymentController
    {
        public function __construct(private CurrencyRepository $currencyRepo) {}
    
        public function process()
        {
            if (!$this->currencyRepo->exists('XXX')) {
                abort(400, 'Invalid currency');
            }
        }
    }
    

Implementation Patterns

Core Workflows

  1. Currency Validation Validate user input (e.g., API requests, forms) against ISO 4217 standards:

    $repository = app(CurrencyRepository::class);
    $currencyCode = request('currency');
    
    if (!$repository->exists($currencyCode)) {
        return response()->json(['error' => 'Invalid currency'], 400);
    }
    
    // Check for historical currencies (e.g., BGN post-2026)
    $currency = $repository->getCurrency($currencyCode);
    if ($currency->isHistoric()) {
        logger()->warning("Using historic currency: {$currencyCode}");
    }
    
  2. Dynamic Currency Selection Fetch all active currencies for dropdowns or reporting:

    $activeCurrencies = $repository->getAll()->filter(fn ($c) => !$c->isHistoric());
    return view('pricing', ['currencies' => $activeCurrencies]);
    
  3. Integration with moneyphp/money Use the repository to create Money objects with validated currencies:

    use Money\Money;
    use Money\Currency\Currency;
    
    $amount = Money::EUR(100); // Throws exception if currency is invalid/historic
    $currency = $repository->getCurrency('EUR');
    $money = new Money(100, $currency);
    
  4. Historical Currency Handling Flag or reject transactions using deprecated currencies (e.g., BGN after 2026):

    $transactionCurrency = 'BGN';
    $now = new DateTime();
    $effectiveDate = new DateTime('2026-01-01');
    
    if ($repository->getCurrency($transactionCurrency)->isHistoric() &&
        $now >= $effectiveDate) {
        throw new \RuntimeException("Currency {$transactionCurrency} is no longer valid");
    }
    

Laravel-Specific Patterns

  1. Service Binding Extend the base CurrencyRepository to add Laravel-specific features (e.g., caching):

    namespace App\Services;
    
    use Money\Currency\CurrencyRepository as BaseRepository;
    use Illuminate\Support\Facades\Cache;
    
    class CurrencyRepository extends BaseRepository
    {
        public function getCurrency(string $code)
        {
            return Cache::remember("currency.{$code}", now()->addHours(1), function () {
                return parent::getCurrency($code);
            });
        }
    }
    

    Rebind in AppServiceProvider:

    $this->app->singleton(CurrencyRepository::class, function () {
        return new App\Services\CurrencyRepository();
    });
    
  2. Form Request Validation Use the repository in Laravel’s form requests:

    use Illuminate\Validation\Rule;
    use Money\Currency\CurrencyRepository;
    
    class StorePaymentRequest extends FormRequest
    {
        public function rules()
        {
            return [
                'currency' => [
                    'required',
                    Rule::exists('currency_repository', 'code')->where(function ($query) {
                        $query->where('is_historic', false);
                    }),
                ],
            ];
        }
    
        public function withValidator($validator)
        {
            $validator->after(function ($validator) {
                $repository = app(CurrencyRepository::class);
                if ($repository->getCurrency($this->currency)->isHistoric()) {
                    $validator->errors()->add('currency', 'Historical currency not allowed');
                }
            });
        }
    }
    
  3. API Responses Return standardized currency data in APIs:

    Route::get('/currencies', function () {
        $repository = app(CurrencyRepository::class);
        return response()->json([
            'data' => $repository->getAll()->map(function ($currency) {
                return [
                    'code' => $currency->getCode(),
                    'name' => $currency->getName(),
                    'symbol' => $currency->getSymbol(),
                    'is_historic' => $currency->isHistoric(),
                ];
            }),
        ]);
    });
    
  4. Migration Helper Use the package to validate currency fields in database migrations:

    use Money\Currency\CurrencyRepository;
    use Illuminate\Database\Migrations\Migration;
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Support\Facades\Schema;
    
    class CreatePaymentsTable extends Migration
    {
        public function up()
        {
            $repository = app(CurrencyRepository::class);
            $validCodes = $repository->getAll()->pluck('code')->all();
    
            Schema::create('payments', function (Blueprint $table) use ($validCodes) {
                $table->string('currency')->required();
                $table->foreign('currency')
                      ->references('code')
                      ->on('currencies')
                      ->whereIn('code', $validCodes);
            });
        }
    }
    

Gotchas and Tips

Pitfalls

  1. Historical Currency Logic

    • Issue: The isHistoric() flag is not time-aware by default. For example, BGN is marked as historic, but you may need to check if a transaction occurred before the deprecation date (2026-01-01).
    • Fix: Combine with a date check:
      $currency = $repository->getCurrency('BGN');
      $transactionDate = new DateTime('2025-12-31');
      $effectiveDate = new DateTime('2026-01-01');
      
      if ($currency->isHistoric() && $transactionDate >= $effectiveDate) {
          throw new \RuntimeException("Currency {$currency->getCode()} is invalid for transactions on or after {$effectiveDate->format('Y-m-d')}");
      }
      
  2. Composer Update Quirks

    • Issue: Running composer fetch-update overwrites the local currency data. If you’ve customized the data (e.g., added internal currencies), these changes will be lost.
    • Fix: Avoid modifying the package’s resources/currencies directory. For custom currencies, extend the repository:
      class ExtendedCurrencyRepository extends CurrencyRepository
      {
          protected function getCurrencies(): array
          {
              $currencies = parent::getCurrencies();
              $currencies['INTERNAL'] = new ISO4217('INTERNAL', 'Internal Units', 'IU', 2);
              return $currencies;
          }
      }
      
  3. PHP Version Constraints

    • Issue: The package drops support for PHP < 8.1. If your Laravel app uses an older version, you’ll need to pin to an older release (e.g., 3.4.0 for PHP 8.0).
    • Fix: Check composer.json for PHP requirements and pin the version:
      "require": {
          "moneyphp/iso-currencies": "3.4.0"
      }
      
  4. Caching Static Data

    • Issue: The currency data is static and loaded on every request if not cached. For high-traffic apps, this can cause performance bottlenecks.
    • Fix:
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium