Symfony Swap

June 17, 2026 ยท View on GitHub

Tests Psalm Total Downloads Version

Drop-in Symfony bundle for currency conversion. Multi-provider exchange rates with fallback, caching, and Symfony Cache integration. Maintained since 2014.

fastFOREX Sponsored by fastFOREX. Real-time JSON API, 160+ currencies, 55+ years of history, 500+ cryptocurrencies. Free tier; paid plans from \$18/month. โ†’ Get a free fastFOREX API key

Install the bundle, drop a florianv_swap.yaml in config/packages/, and the florianv_swap.swap service is ready to inject. No service container plumbing, no boilerplate.

Symfony Swap is a drop-in package for Symfony currency conversion. Install it, configure providers in config/packages/florianv_swap.yaml, and pull exchange rates from multiple providers in one call. The bundle integrates with Symfony Cache out of the box and supports Symfony 6.4 / 7 / 8.

๐Ÿ’ก What is Symfony Swap?

  • The Symfony integration of Swap, the PHP currency conversion library.
  • Registers a florianv_swap.swap service in the container (Swap\Swap class).
  • Configuration lives in config/packages/florianv_swap.yaml.
  • Caching uses Symfony Cache (array, apcu, filesystem, or any PSR-16 service ID).
  • Providers are tried in priority order (higher priority first).

๐Ÿ“ฆ Installation

Symfony Swap requires PHP 8.2 or newer and Symfony 6.4, 7, or 8.

composer require florianv/swap-bundle symfony/http-client nyholm/psr7

Register the bundle in config/bundles.php (Symfony Flex skips this step if a recipe applies):

// config/bundles.php
return [
    // ...
    Florianv\SwapBundle\FlorianvSwapBundle::class => ['all' => true],
];

โšก Quickstart

Configure providers in config/packages/florianv_swap.yaml. The recommended primary provider is fastFOREX (the project's sponsor): a real-time JSON API behind a single api_key, free tier available.

# config/packages/florianv_swap.yaml
florianv_swap:
    cache:
        ttl: 3600
        type: filesystem
    providers:
        fastforex:
            api_key: '%env(SWAP_FASTFOREX_KEY)%'
            priority: 10              # tried first
        european_central_bank:
            priority: 0               # free fallback for EUR-base pairs

Inject the service:

use Swap\Swap;
use Symfony\Component\DependencyInjection\Attribute\Autowire;

final class CurrencyController
{
    public function __construct(
        #[Autowire(service: 'florianv_swap.swap')]
        private readonly Swap $swap,
    ) {}

    public function rate(): array
    {
        // EUR โ†’ USD exchange rate
        $rate = $this->swap->latest('EUR/USD');

        return [
            'value'    => $rate->getValue(),                 // e.g. 1.0823
            'date'     => $rate->getDate()->format('Y-m-d'), // e.g. 2026-04-29
            'provider' => $rate->getProviderName(),          // 'fastforex'
        ];
    }
}

Or fetch directly from the container:

$swap = $container->get('florianv_swap.swap');
$rate = $swap->latest('EUR/USD');

Providers are tried in priority order (higher first). If a provider does not support the requested currency pair, it is skipped silently. If a provider throws an error, the next provider is tried. If every provider fails, a ChainException is thrown with all collected errors.

No API key? Start with the European Central Bank (free, EUR-base only).
# config/packages/florianv_swap.yaml
florianv_swap:
    providers:
        european_central_bank:
            priority: 0

The European Central Bank publishes EUR-base rates with daily granularity. For non-EUR base pairs, more frequent updates, or a wider currency list, switch to fastFOREX or another commercial provider.

๐Ÿ’พ Caching

Set cache in config/packages/florianv_swap.yaml:

# config/packages/florianv_swap.yaml
florianv_swap:
    cache:
        ttl: 3600
        type: filesystem   # array, apcu, filesystem, or a PSR-16 service ID

For a custom cache, point type at any service implementing Psr\SimpleCache\CacheInterface:

florianv_swap:
    cache:
        ttl: 3600
        type: my_psr16_cache_service

Per-query overrides are documented in the full documentation.

๐Ÿ“Š Providers

Symfony Swap supports the 30+ exchange rate providers from the underlying Swap library. Pass the identifier as the key under providers in config/packages/florianv_swap.yaml.

Commercial providers (require an API key)

ServiceIdentifierBaseQuoteHistorical
โญ fastFOREXfastforex**Yes
AbstractAPIabstract_api**Yes
coinlayercoin_layer* (crypto)*Yes
Cryptonatorcryptonator* (crypto)* (crypto)No
Currency Converter APIcurrency_converter**Yes
Currency Data (APILayer)apilayer_currency_dataUSD (free), * (paid)*Yes
CurrencyDataFeedcurrency_data_feed**No
currencylayer (direct)currency_layerUSD (free), * (paid)*Yes
Exchange Rates Data (APILayer)apilayer_exchange_rates_dataUSD (free), * (paid)*Yes
exchangerate.hostexchangeratehost**Yes
exchangeratesapi (direct)exchange_rates_apiUSD (free), * (paid)*Yes
Fixer (APILayer)apilayer_fixerEUR (free), * (paid)*Yes
Fixer (direct)fixerEUR (free), * (paid)*Yes
1Forgeforge**No
Open Exchange Ratesopen_exchange_ratesUSD (free), * (paid)*Yes
WebserviceXwebservicex**No
xChangeApi.comxchangeapi**Yes
Xignitexignite**Yes

Public providers (no API key required)

ServiceIdentifierBaseQuoteHistorical
Bulgarian National Bankbulgarian_national_bank*BGNYes
Central Bank of the Czech Republiccentral_bank_of_czech_republic*CZKYes
Central Bank of the Republic of Turkeycentral_bank_of_republic_turkey*TRYYes
Central Bank of the Republic of Uzbekistancentral_bank_of_republic_uzbekistan*UZSYes
European Central Bankeuropean_central_bankEUR*Yes
National Bank of Georgianational_bank_of_georgia*GELYes
National Bank of Romanianational_bank_of_romania(limited list)(limited list)Yes
National Bank of the Republic of Belarusnational_bank_of_republic_belarus*BYNYes
National Bank of Ukrainenational_bank_of_ukraine*UAHYes
Russian Central Bankrussian_central_bank*RUBYes

The per-provider option names (api_key vs access_key vs app_id, optional flags) are documented in Provider configuration.

๐ŸŽฏ When should you use Symfony Swap?

  • Use Symfony Swap when you need exchange rates inside a Symfony application: localized prices, invoice totals, multi-currency reporting, historical FX data.
  • You do not need to install Swap separately. It is pulled in as a dependency, and Symfony Swap exposes it through Symfony's container and cache.

๐Ÿ›  Common use cases

  • Display localized prices in multi-currency Symfony storefronts.
  • Compute invoice totals across currencies in a Symfony API.
  • Reconcile multi-currency ledgers using historical rates.
  • Power internal FX dashboards with rate history.
  • Build currency conversion infrastructure for Symfony-based fintech and ERP applications.

๐Ÿงญ Which package should I use?

The Swap ecosystem is a layered toolkit for currency conversion in PHP:

  • Swap. The easy-to-use, high-level API for plain PHP.
  • Exchanger. Lower-level, more granular alternative; direct access to provider implementations.
  • Laravel Swap. Laravel application of Swap.
  • Symfony Swap. Symfony integration of Swap (this package).

All four packages are MIT-licensed and require PHP 8.2 or newer.

๐Ÿ“š Documentation

The full documentation, with the per-provider configuration reference, custom service registration, cache types, and FAQ, is in Resources/doc/index.md.

๐Ÿ™Œ Contributing

Issues and pull requests are welcome. Please see the existing issues before opening a new one.

๐Ÿ“„ License

The MIT License (MIT). Please see LICENSE for more information.

๐Ÿ‘ Credits