Proxies and Dummy Services#

Proxies and Dummy Services are defined in the core library, peso/core.

ChainService#

\Peso\Core\Services\ChainService($service1, $service2, ...)

Chain service allows you to request data from several sources:

<?php

use Peso\Core\Services\ChainService;
use Peso\Peso\CurrencyConverter;
use Peso\Services\CzechNationalBankService;
use Peso\Services\EuropeanCentralBankService;

$converter = new CurrencyConverter(new ChainService(
    new EuropeanCentralBankService(),
    new CzechNationalBankService(),
));

// ECB doesn't know that
echo $converter->convertOnDate('1.20', 'USD', 'CZK', 2, '2025-06-13'); // 25.88

TrivialService#

Added in version 1.2.

TrivialService returns rate of 1 when currency is exchanged to itself. Use it when the service does not contain a self-reference entry for the currency or to prefix a service with limits to avoid pointless calls:

<?php

use Peso\Core\Services\TrivialService;
use Peso\Peso\CurrencyConverter;

$service = new TrivialService();
$peso = new CurrencyConverter($service);

echo $peso->convert('123.45', 'EUR', 'EUR', 2), PHP_EOL; // 123.45

ReversibleService#

\Peso\Core\Services\ReversibleService

Note

Values returned by a Reversible Service are calculated and therefore informational only. Never use them for precise conversions.

In case a service defines only a single base or quote currency, Reversible Service can make it bi-directional by calculating a reverse value:

<?php

use Peso\Core\Services\ReversibleService;
use Peso\Peso\CurrencyConverter;
use Peso\Services\EuropeanCentralBankService;

$converter = new CurrencyConverter(
    new ReversibleService(new EuropeanCentralBankService())
);

echo $converter->convertOnDate('123.45', 'USD', 'EUR', 2, '2025-06-13'); // 107.24

IndirectExchangeService#

\Peso\Core\Services\IndirectExchangeService

Note

Values returned by an Indirect Exchange Service are calculated and therefore informational only. Never use them for precise conversions.

In case a service defines only conversion rates back and forth for a single currency, Indirect Exchange Service can make it every-to-every by using the selected currency as an intermediary:

<?php

use Peso\Core\Services\IndirectExchangeService;
use Peso\Core\Services\ReversibleService;
use Peso\Peso\CurrencyConverter;
use Peso\Services\EuropeanCentralBankService;

$converter = new CurrencyConverter(
    new IndirectExchangeService(
        new ReversibleService( // To and from EUR
            new EuropeanCentralBankService(), // Only EUR base
        ),
        'EUR',
    ),
);

// USD -> EUR -> PLN
echo $converter->convertOnDate('123.45', 'USD', 'PLN', 2, '2025-06-13'); // 458.38

ConversionService#

Added in version 1.1.

\Peso\Core\Services\ConversionService

Accepts an instance of CurrentConversionRequest / HistoricalConversionRequest and calculates the conversion amount by sending CurrentExchangeRateRequest / HistoricalConversionRequest to a wrapped service:

<?php

use Peso\Core\Requests\CurrentConversionRequest;
use Peso\Core\Services\ConversionService;
use Peso\Core\Types\Decimal;
use Peso\Services\EuropeanCentralBankService;

$service = new ConversionService(new EuropeanCentralBankService());

echo $service->send(
    new CurrentConversionRequest(new Decimal('123.45'), 'EUR', 'PHP')
)->amount->value; // 8167.57545 (2025-06-30)

ArrayService#

\Peso\Core\Services\ArrayService($currentRates = [], $historicalRates = [])

Array Service holds static exchange rates:

<?php

use Peso\Core\Services\ArrayService;
use Peso\Peso\CurrencyConverter;

$service = new ArrayService(
    currentRates: [
        // Base Currencies
        'EUR' => [
            // Quote => rate
            'USD' => '1.12',
        ],
    ],
    historicalRates: [
        // Y-m-d dates
        '2025-06-13' => [
            // Base Currencies
            'EUR' => [
                // Quote => rate
                'USD' => '1.09',
            ],
        ],
    ]
);
$converter = new CurrencyConverter($service);

echo
    $converter->convert('150.00', 'EUR', 'USD', 2), PHP_EOL, // 168.00
    $converter->convertOnDate('150.00', 'EUR', 'USD', 2, '2025-06-13'), PHP_EOL; // 163.50

Callback Service#

Added in version 1.3.

\Peso\Core\Services\CallbackService

Callback service is a wrapper for a closure to quickly create a simple test service:

<?php

use Arokettu\Date\Date;
use Peso\Core\Exceptions\RequestNotSupportedException;
use Peso\Core\Requests\CurrentExchangeRateRequest;
use Peso\Core\Responses\ErrorResponse;
use Peso\Core\Responses\ExchangeRateResponse;
use Peso\Core\Services\CallbackService;
use Peso\Core\Types\Decimal;
use Peso\Peso\CurrencyConverter;

$peso = new CurrencyConverter(new CallbackService(function ($request) {
    if (
        $request instanceof CurrentExchangeRateRequest &&
        $request->quoteCurrency === 'GBP' &&
        $request->baseCurrency === 'EUR'
    ) {
        return new ExchangeRateResponse(Decimal::init('1.5'), Date::today());
    }

    return new ErrorResponse(RequestNotSupportedException::fromRequest($request));
}));

echo $peso->convert('1200', 'EUR', 'GBP', 2); // 1800.00

NullService and BlackHoleService#

Added in version 1.4: BlackHoleService

\Peso\Core\Services\NullService
\Peso\Core\Services\BlackHoleService

Null Service does not support any requests. Black Hole Service supports all standard requests but returns only apporopriate ErrorResponses. They may be useful for testing purposes:

<?php

use Arokettu\Date\Date;
use Peso\Core\Requests\CurrentExchangeRateRequest;
use Peso\Core\Services\BlackHoleService;
use Peso\Core\Services\NullService;
use Peso\Peso\CurrencyConverter;

$converter = new CurrencyConverter(new NullService());
// Peso\Core\Exceptions\RequestNotSupportedException
$converter->getExchangeRate('USD', 'EUR');

$converter = new CurrencyConverter(new BlackHoleService());
// Peso\Core\Exceptions\ExchangeRateNotFoundException
$converter->getExchangeRate('USD', 'EUR');

// "Support" only specific requests
$converter = new CurrencyConverter(new BlackHoleService(CurrentExchangeRateRequest::class));
// Peso\Core\Exceptions\ExchangeRateNotFoundException
$converter->getExchangeRate('USD', 'EUR');
// Peso\Core\Exceptions\RequestNotSupportedException
$converter->getHistoricalExchangeRate('USD', 'EUR', Date::today());