Skip to content

Commit 773e7f7

Browse files
authored
Merge pull request #64 from florianv/sponsorship/fastforex
docs: integrate fastFOREX as the project sponsor and recommended provider
2 parents 6622cb3 + 28a56bb commit 773e7f7

2 files changed

Lines changed: 84 additions & 99 deletions

File tree

README.md

Lines changed: 50 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -7,37 +7,32 @@
77

88
> _Drop-in Symfony bundle for currency conversion. Multi-provider exchange rates with fallback, caching, and Symfony Cache integration. Maintained since 2014._
99
10+
<table>
11+
<tr>
12+
<td width="220" align="center">
13+
<a href="https://www.fastforex.io" target="_blank" rel="noopener">
14+
<img src="https://console.fastforex.io/img/fastforex/logo-bk-1k.svg" width="180px" alt="fastFOREX"/>
15+
</a>
16+
</td>
17+
<td>
18+
<strong>Sponsored by <a href="https://www.fastforex.io" target="_blank" rel="noopener">fastFOREX</a>.</strong> Real-time JSON API, 160+ currencies, 55+ years of history, 500+ cryptocurrencies. <strong>Free tier</strong>; paid plans from $18/month.
19+
<a href="https://www.fastforex.io" target="_blank" rel="noopener"><strong>→ Get a free fastFOREX API key</strong></a>
20+
</td>
21+
</tr>
22+
</table>
23+
1024
**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.**
1125

12-
Symfony Swap is a drop-in package for **Symfony currency conversion**. Install it, configure providers in `config/packages/florianv_swap.yaml`, and pull **Symfony 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. Used in real-world Symfony applications since 2014.
26+
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.
1327

1428
## 💡 What is Symfony Swap?
1529

16-
- Symfony Swap is the Symfony integration of [Swap](https://github.com/florianv/swap), the PHP currency conversion library.
17-
- It registers a `florianv_swap.swap` service in the container (`Swap\Swap` class).
30+
- The Symfony integration of [Swap](https://github.com/florianv/swap), the PHP currency conversion library.
31+
- Registers a `florianv_swap.swap` service in the container (`Swap\Swap` class).
1832
- Configuration lives in `config/packages/florianv_swap.yaml`.
1933
- Caching uses Symfony Cache (`array`, `apcu`, `filesystem`, or any PSR-16 service ID).
2034
- Providers are tried in priority order (higher priority first).
2135

22-
## 🎯 When should you use Symfony Swap?
23-
24-
- Use Symfony Swap when you need exchange rates inside a Symfony application: localized prices, invoice totals, multi-currency reporting, historical FX data.
25-
- You do not need to install [Swap](https://github.com/florianv/swap) separately. It is pulled in as a dependency, and Symfony Swap exposes it through Symfony's container and cache.
26-
27-
## 🧠 Why Symfony Swap and not raw Swap?
28-
29-
Using [Swap](https://github.com/florianv/swap) directly inside a Symfony app means three pieces of plumbing on every project: registering the builder and the Swap service yourself, wiring Symfony Cache to the PSR-16 contract, and configuring providers in PHP rather than in the container. Doable, but boilerplate every project pays for.
30-
31-
Symfony Swap does this for you:
32-
33-
- **Drop-in.** Add the bundle to `config/bundles.php` and you are set.
34-
- **Symfony Cache integration.** Choose `array`, `apcu`, `filesystem`, or any PSR-16 service ID under `cache.type`.
35-
- **Container service.** `florianv_swap.swap` is ready to inject from any controller, service, or command.
36-
- **Configurable.** `config/packages/florianv_swap.yaml` exposes providers, options, and the cache.
37-
- **Priority-ordered providers.** Each provider has a `priority`; the bundle sorts them (higher priority tried first).
38-
39-
If you are not on Symfony, use [Swap](https://github.com/florianv/swap) directly.
40-
4136
## 📦 Installation
4237

4338
Symfony Swap requires PHP 8.2 or newer and Symfony 6.4, 7, or 8.
@@ -56,22 +51,22 @@ return [
5651
];
5752
```
5853

59-
Skip to [Quickstart](#-quickstart).
60-
61-
---
62-
63-
_Optional: any PSR-18 HTTP client paired with a PSR-17 factory works. If your app already uses Guzzle, swap `symfony/http-client` for `php-http/guzzle7-adapter`. See the [documentation](Resources/doc/index.md) for alternatives._
64-
6554
## ⚡ Quickstart
6655

67-
Configure at least one provider in `config/packages/florianv_swap.yaml`. The European Central Bank works without an API key:
56+
Configure providers in `config/packages/florianv_swap.yaml`. The recommended primary provider is **[fastFOREX](https://www.fastforex.io)** (the project's sponsor): a real-time JSON API behind a single `api_key`, [free tier available](https://www.fastforex.io).
6857

6958
```yaml
7059
# config/packages/florianv_swap.yaml
7160
florianv_swap:
61+
cache:
62+
ttl: 3600
63+
type: filesystem
7264
providers:
65+
fastforex:
66+
api_key: '%env(SWAP_FASTFOREX_KEY)%'
67+
priority: 10 # tried first
7368
european_central_bank:
74-
priority: 0
69+
priority: 0 # free fallback for EUR-base pairs
7570
```
7671
7772
Inject the service:
@@ -95,7 +90,7 @@ final class CurrencyController
9590
return [
9691
'value' => $rate->getValue(), // e.g. 1.0823
9792
'date' => $rate->getDate()->format('Y-m-d'), // e.g. 2026-04-29
98-
'provider' => $rate->getProviderName(), // 'european_central_bank'
93+
'provider' => $rate->getProviderName(), // 'fastforex'
9994
];
10095
}
10196
}
@@ -108,26 +103,21 @@ $swap = $container->get('florianv_swap.swap');
108103
$rate = $swap->latest('EUR/USD');
109104
```
110105

111-
Add commercial providers under `providers:` and they will be chained with the configured priority order:
106+
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.
107+
108+
<details>
109+
<summary>No API key? Start with the European Central Bank (free, EUR-base only).</summary>
112110

113111
```yaml
114112
# config/packages/florianv_swap.yaml
115113
florianv_swap:
116-
cache:
117-
ttl: 3600
118-
type: filesystem
119114
providers:
120-
apilayer_fixer:
121-
api_key: '%env(SWAP_FIXER_KEY)%'
122-
priority: 10 # tried first
123-
open_exchange_rates:
124-
app_id: '%env(SWAP_OER_APP_ID)%'
125-
priority: 5 # tried second
126115
european_central_bank:
127-
priority: 0 # free fallback for EUR-base pairs
116+
priority: 0
128117
```
129118
130-
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.
119+
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.
120+
</details>
131121
132122
## 💾 Caching
133123
@@ -150,7 +140,18 @@ florianv_swap:
150140
type: my_psr16_cache_service
151141
```
152142

153-
Per-query overrides are documented in the [full documentation](Resources/doc/index.md#-caching).
143+
Per-query overrides are documented in the [full documentation](Resources/doc/index.md#-per-query-options).
144+
145+
## 📊 Providers
146+
147+
Symfony Swap supports the 30 exchange rate providers from the underlying [Swap](https://github.com/florianv/swap) library. The recommended starting point for new projects is **[fastFOREX](https://www.fastforex.io)** (`fastforex`), the project's sponsor: live rates across 160+ fiat currencies and 500+ cryptocurrencies, with up to 55 years of history.
148+
149+
The full per-provider configuration reference (option name, optional flags, capabilities) is in the [documentation](Resources/doc/index.md#provider-configuration).
150+
151+
## 🎯 When should you use Symfony Swap?
152+
153+
- Use Symfony Swap when you need exchange rates inside a Symfony application: localized prices, invoice totals, multi-currency reporting, historical FX data.
154+
- You do not need to install [Swap](https://github.com/florianv/swap) separately. It is pulled in as a dependency, and Symfony Swap exposes it through Symfony's container and cache.
154155

155156
## 🛠 Common use cases
156157

@@ -164,37 +165,16 @@ Per-query overrides are documented in the [full documentation](Resources/doc/ind
164165

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

167-
- **Swap.** The easy-to-use, high-level API for plain PHP.
168-
- **Exchanger.** Lower-level, more granular alternative; direct access to provider implementations.
169-
- **Laravel Swap.** Laravel application of Swap.
170-
- **Symfony Swap.** Symfony integration of Swap (this package).
168+
- [**Swap**](https://github.com/florianv/swap). The easy-to-use, high-level API for plain PHP.
169+
- [**Exchanger**](https://github.com/florianv/exchanger). Lower-level, more granular alternative; direct access to provider implementations.
170+
- [**Laravel Swap**](https://github.com/florianv/laravel-swap). Laravel application of Swap.
171+
- [**Symfony Swap**](https://github.com/florianv/symfony-swap). Symfony integration of Swap (this package).
171172

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

174175
## 📚 Documentation
175176

176-
The full documentation, with the per-provider configuration reference, custom service registration, cache types, and FAQ, is in [Resources/doc/index.md](Resources/doc/index.md). The full provider list with capabilities is in the [Swap README](https://github.com/florianv/swap#-providers).
177-
178-
## 🧩 Related packages
179-
180-
The Swap ecosystem:
181-
182-
- [**Swap**](https://github.com/florianv/swap): easy-to-use PHP currency conversion library.
183-
- [**Exchanger**](https://github.com/florianv/exchanger): exchange rate provider layer.
184-
- [**Laravel Swap**](https://github.com/florianv/laravel-swap): Laravel application of Swap.
185-
- [**Symfony Swap**](https://github.com/florianv/symfony-swap): Symfony integration of Swap (this package).
186-
187-
## 🤝 Sponsorship
188-
189-
The Swap ecosystem is open to selected sponsorships from exchange rate API providers and financial infrastructure companies.
190-
191-
Sponsorship can include:
192-
193-
- Documentation visibility
194-
- Integration examples
195-
- Ecosystem-level visibility across Swap, Exchanger, Laravel Swap, and Symfony Swap
196-
197-
For inquiries, contact the maintainer via [GitHub](https://github.com/florianv).
177+
The full documentation, with the per-provider configuration reference, custom service registration, cache types, and FAQ, is in [Resources/doc/index.md](Resources/doc/index.md).
198178

199179
## 🙌 Contributing
200180

Resources/doc/index.md

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,20 @@
11
# Documentation
22

3-
## 💡 What is Symfony Swap?
4-
5-
- Symfony Swap is the Symfony integration of [Swap](https://github.com/florianv/swap), the PHP currency conversion library.
6-
- It registers a `florianv_swap.swap` service in the container (`Swap\Swap` class).
7-
- Configuration lives in `config/packages/florianv_swap.yaml`.
8-
- Caching uses Symfony Cache (`array`, `apcu`, `filesystem`, or any PSR-16 service ID).
9-
- Providers are tried in priority order (higher priority first).
10-
11-
For the wider ecosystem (Swap, Exchanger, Laravel Swap), see the [README](../../README.md).
12-
13-
## 🎯 When should you use Symfony Swap?
14-
15-
- Use Symfony Swap when you need exchange rates inside a Symfony application: localized prices, invoice totals, multi-currency reporting, historical FX data.
16-
- You do not need to install [Swap](https://github.com/florianv/swap) separately. It is pulled in as a dependency, and Symfony Swap exposes it through Symfony's container and cache.
17-
18-
## 🧠 Why Symfony Swap and not raw Swap?
19-
20-
- **Drop-in.** Add the bundle to `config/bundles.php` and you are set.
21-
- **Symfony Cache integration.** Choose `array`, `apcu`, `filesystem`, or any PSR-16 service ID under `cache.type`.
22-
- **Container service.** `florianv_swap.swap` is ready to inject from any controller, service, or command.
23-
- **Configurable.** `config/packages/florianv_swap.yaml` exposes providers, options, and the cache.
24-
- **Priority-ordered providers.** Each provider has a `priority`; the bundle sorts them (higher priority tried first), unlike Swap and Laravel Swap, which use declaration order.
3+
<table>
4+
<tr>
5+
<td width="220" align="center">
6+
<a href="https://www.fastforex.io" target="_blank" rel="noopener">
7+
<img src="https://console.fastforex.io/img/fastforex/logo-bk-1k.svg" width="180px" alt="fastFOREX"/>
8+
</a>
9+
</td>
10+
<td>
11+
<strong>Sponsored by <a href="https://www.fastforex.io" target="_blank" rel="noopener">fastFOREX</a>.</strong> Real-time JSON API, 160+ currencies, 55+ years of history, 500+ cryptocurrencies. <strong>Free tier</strong>; paid plans from $18/month.
12+
<a href="https://www.fastforex.io" target="_blank" rel="noopener"><strong>→ Get a free fastFOREX API key</strong></a>
13+
</td>
14+
</tr>
15+
</table>
16+
17+
This is the technical reference for Symfony Swap. For the project overview and ecosystem (Swap, Exchanger, Laravel Swap), see the [README](../../README.md).
2518

2619
## Index
2720

@@ -73,22 +66,27 @@ Create the configuration file at `config/packages/florianv_swap.yaml` (see [Conf
7366

7467
### Config tree
7568

69+
A typical config pins fastFOREX (the project's sponsor) as the primary provider, with the European Central Bank as a free fallback:
70+
7671
```yaml
7772
# config/packages/florianv_swap.yaml
7873
florianv_swap:
7974
cache:
8075
ttl: 3600
8176
type: filesystem
8277
providers:
78+
fastforex:
79+
api_key: '%env(SWAP_FASTFOREX_KEY)%'
80+
priority: 10 # tried first
8381
european_central_bank:
84-
priority: 0
82+
priority: 0 # free fallback for EUR-base pairs
8583
```
8684
8785
At least one provider is required. Each provider accepts a `priority` integer (higher priority is tried first) and the provider-specific options listed below.
8886

8987
### Provider configuration
9088

91-
Public providers (central banks, national banks, `cryptonator`, `webservicex`) need only a `priority`:
89+
Public providers (central banks, national banks) need only a `priority`:
9290

9391
```yaml
9492
florianv_swap:
@@ -99,10 +97,12 @@ florianv_swap:
9997
priority: 0
10098
```
10199

102-
Commercial providers require an API key. The option name varies by provider:
100+
Commercial providers require an API key. The option name varies by provider. The project's sponsor [fastFOREX](https://www.fastforex.io) (`fastforex`) is the recommended starting point.
103101

104102
| Identifier | Required option | Optional flags |
105103
| -------------------------------- | --------------- | --------------------- |
104+
| ⭐ **`fastforex`** | **`api_key`** | |
105+
| | | |
106106
| `abstract_api` | `api_key` | |
107107
| `apilayer_currency_data` | `api_key` | |
108108
| `apilayer_exchange_rates_data` | `api_key` | |
@@ -118,11 +118,16 @@ Commercial providers require an API key. The option name varies by provider:
118118
| `xchangeapi` | `api-key` | (note the hyphen) |
119119
| `xignite` | `token` | |
120120

121-
Example:
121+
> Note: `cryptonator`, `exchangeratehost` and `webservicex` are commercial upstream services but the current Exchanger wrapper does not enforce any option for them. They can be added with only a `priority`.
122+
123+
Example chaining fastFOREX as the primary provider with a couple of fallbacks:
122124

123125
```yaml
124126
florianv_swap:
125127
providers:
128+
fastforex:
129+
api_key: '%env(SWAP_FASTFOREX_KEY)%'
130+
priority: 20
126131
apilayer_fixer:
127132
api_key: '%env(SWAP_FIXER_KEY)%'
128133
priority: 10
@@ -226,7 +231,7 @@ $rate->getCurrencyPair(); // Exchanger\CurrencyPair
226231
$rate->getProviderName(); // string, the identifier that returned the rate
227232
```
228233

229-
`getProviderName()` is useful when several providers are configured: the returned value is the identifier of the provider that actually answered, for example `european_central_bank`.
234+
`getProviderName()` is useful when several providers are configured: the returned value is the identifier of the provider that actually answered, for example `fastforex`.
230235

231236
## 💾 Per-query options
232237

@@ -354,7 +359,7 @@ Swap throws an `Exchanger\Exception\ChainException`. Calling `$exception->getExc
354359

355360
#### Can I use Symfony Swap without an API key?
356361

357-
Yes. The European Central Bank, the national banks, `cryptonator`, and `webservicex` do not require an API key. See the [Swap README's Providers table](https://github.com/florianv/swap#-providers) for the full list.
362+
Yes. The European Central Bank and the national banks listed in the [Provider configuration](#provider-configuration) section require no key. A few commercial providers (`cryptonator`, `exchangeratehost`, `webservicex`) can also currently be used without one, since the Exchanger wrapper does not yet enforce an option for them.
358363

359364
#### How does Symfony Swap relate to Swap?
360365

@@ -374,4 +379,4 @@ Implement `Exchanger\Contract\ExchangeRateService` (or extend `HttpService` / `S
374379

375380
#### Where is the full provider list with capabilities?
376381

377-
In the [Swap README's Providers table](https://github.com/florianv/swap#-providers). It lists every supported identifier with its base currency, quote currency, and historical support.
382+
In the [Provider configuration](#provider-configuration) section above (option reference) and the [Swap README's Providers table](https://github.com/florianv/swap#-providers) (base currency, quote currency, historical support).

0 commit comments

Comments
 (0)