first commit

This commit is contained in:
2026-01-14 16:40:33 +03:00
commit f803480f7b
184 changed files with 5573 additions and 0 deletions

75
src/Sbp/SbpConnector.php Normal file
View File

@@ -0,0 +1,75 @@
<?php
namespace Gemini\AlfaBank\Sbp;
use Gemini\AlfaBank\Enums\Environment;
use Saloon\Http\Connector;
use Saloon\Http\PendingRequest;
use Saloon\Traits\Plugins\HasTimeout;
class SbpConnector extends Connector
{
use HasTimeout;
public function __construct(
protected string $certificatePath,
protected string $privateKeyPath,
protected string $keyNameAlias, // 'key-name' header
protected Environment $environment = Environment::SANDBOX
) {}
public function resolveBaseUrl(): string
{
return match ($this->environment) {
Environment::SANDBOX => 'https://217.12.103.132:2443/fsCryptoProxy',
Environment::PRODUCTION => 'https://pay.alfabank.ru/fsCryptoProxy', // Placeholder, user needs to confirm
};
}
protected function defaultConfig(): array
{
return [
'cert' => $this->certificatePath,
'ssl_key' => $this->privateKeyPath,
'verify' => true,
];
}
protected function defaultHeaders(): array
{
return [
'Content-Type' => 'application/x-www-form-urlencoded', // As per doc, despite body being JSON
'key-name' => $this->keyNameAlias,
];
}
public function boot(PendingRequest $pendingRequest): void
{
// Calculate Signature
$body = $pendingRequest->body()?->all();
if (empty($body)) {
return;
}
// Minify JSON for signature
$jsonBody = json_encode($body, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
// Remove spaces/newlines as per doc requirement "exclude all spaces, tabs, newlines"
// Standard json_encode without pretty print usually does this, but let's be sure.
// The doc example: `{"command":"GetQRCd",...}` implies no spaces after colons/commas.
$privateKey = file_get_contents($this->privateKeyPath);
$pkeyId = openssl_get_privatekey($privateKey);
openssl_sign($jsonBody, $signature, $pkeyId, OPENSSL_ALGO_SHA256);
$signatureBase64 = base64_encode($signature);
$pendingRequest->headers()->add('Authorization', $signatureBase64);
// Ensure the body sent is the exact string we signed?
// Saloon will encode the array to JSON again.
// We should enforce the body to be the string we just signed to ensure consistency.
$pendingRequest->body()->set($jsonBody);
}
}