Files
alfa-bank-sdk/src/Core/AlfaBankConnector.php
2026-01-18 23:56:48 +03:00

123 lines
4.3 KiB
PHP

<?php
declare(strict_types=1);
namespace Apoloz\AlfaBank\Core;
// <SECTION name="module_imports" intent="Import necessary contracts, services, and base framework components for the connector's operation.">
// <BELIEF_STATE "Saloon's plugin architecture requires importing traits for features like retries and timeouts. Local contracts (SignerInterface) are imported for dependency injection.">
use Apoloz\AlfaBank\Contracts\SignerInterface;
use Apoloz\AlfaBank\Http\Middleware\RequestIdMiddleware;
use Apoloz\AlfaBank\Http\Pagination\AlfaOffsetPaginator;
use Apoloz\AlfaBank\Requests\Auth\GetTokenRequest;
use Apoloz\AlfaBank\Traits\HasAlfaErrorHandling;
use Saloon\Http\Connector;
use Saloon\Http\Request;
use Saloon\PaginationPlugin\Contracts\HasPagination;
use Saloon\PaginationPlugin\OffsetPaginator;
use Saloon\Traits\Plugins\AlwaysThrowOnErrors;
use Saloon\Traits\RequestProperties\HasTries;
use Saloon\Traits\Plugins\HasTimeout;
class AlfaBankConnector extends Connector implements HasPagination
{
use HasTimeout;
use HasTries;
use AlwaysThrowOnErrors;
use HasAlfaErrorHandling;
public function __construct(
protected AlfaConfig $alfaConfig,
protected ?SignerInterface $signer = null
) {
$this->tries = 3;
$this->retryInterval = 500;
}
public function resolveBaseUrl(): string
{
return $this->alfaConfig->baseUrl;
}
protected function defaultConfig(): array
{
$config = [
'cert' => $this->alfaConfig->certificatePath,
'ssl_key' => $this->alfaConfig->privateKeyPath,
'verify' => true,
];
if ($this->alfaConfig->caBundlePath) {
$config['verify'] = $this->alfaConfig->caBundlePath;
}
return $config;
}
protected function defaultMiddleware(): array
{
return [
new RequestIdMiddleware(),
];
}
public function boot(\Saloon\Http\PendingRequest $pendingRequest): void
{
//
}
public function paginate(Request $request): OffsetPaginator
{
return new AlfaOffsetPaginator($this, $request);
}
public function login(?string $clientId = null, ?string $clientSecret = null): static
{
// Allow overriding config via method arguments
$clientId = $clientId ?? $this->alfaConfig->clientId;
$clientSecret = $clientSecret ?? $this->alfaConfig->clientSecret;
if (!$clientId || !$clientSecret) {
throw new \RuntimeException("Client ID/Secret not configured.");
}
$request = new GetTokenRequest(
clientId: $clientId,
clientSecret: $clientSecret,
grantType: 'client_credentials'
);
// Send request (using self to reuse cert/ssl config)
// We temporarily disable auth middleware if we had any,
// but here we are raw, so it's fine.
$response = $this->send($request);
$data = $response->dto();
$this->authenticate(new \Saloon\Http\Auth\TokenAuthenticator($data->access_token));
return $this;
}
// </SECTION>
// <SECTION name="signer_accessor" intent="Provide access to the configured signing service for requests that require a digital signature.">
// <BELIEF_STATE "Requests should not instantiate their own signing logic. The connector acts as a service locator, providing the globally-configured Signer service. This ensures that all signatures are generated consistently.">
public function getSigner(): SignerInterface
{
if (!$this->signer) {
throw new \RuntimeException("No signer configured for this connector.");
}
return $this->signer;
}
// </SECTION>
// <SECTION name="logging_mutator" intent="Allow attaching a PSR-3 logger to the connector for debugging.">
// <BELIEF_STATE "Logging should be an optional, opt-in feature. This method provides a fluent interface to attach a logging middleware, which will automatically sanitize sensitive data before output.">
public function withLogging(\Psr\Log\LoggerInterface $logger): static
{
$this->middleware()->onRequest(new \Apoloz\AlfaBank\Http\Middleware\LoggingRequestMiddleware($logger));
$this->middleware()->onResponse(new \Apoloz\AlfaBank\Http\Middleware\LoggingResponseMiddleware($logger));
return $this;
}
// </SECTION>
}