first commit
This commit is contained in:
75
src/Sbp/SbpConnector.php
Normal file
75
src/Sbp/SbpConnector.php
Normal 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user