Skip to content

Commit

Permalink
fix code style
Browse files Browse the repository at this point in the history
  • Loading branch information
igor-netFantom committed Nov 27, 2023
1 parent a7f89d8 commit 2ed51a9
Showing 1 changed file with 123 additions and 121 deletions.
244 changes: 123 additions & 121 deletions src/RobokassaApi.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,36 +77,19 @@ private function checkPsr18Client(): void
public static function getInvoicePayResultFromRequestArray(array $requestParameters): InvoicePayResult
{
return new InvoicePayResult(
outSum: $requestParameters['OutSum'] ?? throw new InvalidArgumentException(
'OutSum request parameter required'
),
outSum: $requestParameters['OutSum']
?? throw new InvalidArgumentException(
'OutSum request parameter required'
),
invId: isset($requestParameters['InvId']) ? (int)$requestParameters['InvId'] : null,
signatureValue: $requestParameters['SignatureValue'] ?? throw new InvalidArgumentException(
'SignatureValue request parameter required'
),
signatureValue: $requestParameters['SignatureValue']
?? throw new InvalidArgumentException(
'SignatureValue request parameter required'
),
userParameters: self::getUserParametersFromRequestArray($requestParameters),
);
}

/**
* Получение пользовательских параметров (shp_...) из массива GET или POST параметров
* @param array<string,string> $requestParameters
* @return array<string, string>
*/
private static function getUserParametersFromRequestArray(array $requestParameters): array
{
$userParameters = array_filter(
$requestParameters,
static fn($key) => str_starts_with(strtolower((string)$key), 'shp_'),
ARRAY_FILTER_USE_KEY
);
$userParametersWithoutPrefix = [];
foreach ($userParameters as $index => $userParameter) {
$userParametersWithoutPrefix[substr_replace($index, '', 0, 4)] = $userParameter;
}
return $userParametersWithoutPrefix;
}

public static function getVatsFromItems(array $items): array
{
$vats = [];
Expand All @@ -121,38 +104,6 @@ public function checkSignature(InvoicePayResult $invoicePayResult): bool
return $this->getValidSignatureForResult($invoicePayResult) === strtolower($invoicePayResult->signatureValue);
}

/**
* Получение правильной подписи для параметров результата {@see InvoicePayResult} от Робокассы
*/
private function getValidSignatureForResult(InvoicePayResult $invoicePayResult): string
{
$signature = "$invoicePayResult->outSum:$invoicePayResult->invId";
$signature .= ":$this->password2";
if (!empty($invoicePayResult->userParameters)) {
$signature .= ':' . $this->implodeUserParameters($invoicePayResult->userParameters);
}

return strtolower($this->encryptSignature($signature));
}

/**
* @param array<array-key, string> $additionalUserParameters
* @return string
*/
private function implodeUserParameters(array $additionalUserParameters): string
{
ksort($additionalUserParameters);
foreach ($additionalUserParameters as $key => $value) {
$additionalUserParameters[$key] = $key . '=' . $value;
}
return implode(':', $additionalUserParameters);
}

private function encryptSignature(string $signature): string
{
return hash($this->hashAlgo, $signature);
}

public function getPaymentUrl(InvoiceOptions $invoiceOptions): string
{
return $this->paymentUrl . '?' . http_build_query($this->getPaymentParameters($invoiceOptions));
Expand Down Expand Up @@ -194,43 +145,6 @@ public function smsRequest(int $phone, string $message): RequestInterface
return $this->getPsr18Client()->createRequest('GET', $requestUri);
}

/**
* Формирование и кодирование подписи:
*
* Минимальный вариант подписи до кодирования
* MerchantLogin:OutSum:Пароль#1
*
* Максимальный вариант подписи до кодирования
* MerchantLogin:OutSum:InvId:OutSumCurrency:UserIp:Receipt:Пароль#1:Shp_...=...:Shp_...=...
*/
private function generateSignatureForPayment(InvoiceOptions $invoiceOptions): string
{
$signature = "$this->merchantLogin:$invoiceOptions->outSum:$invoiceOptions->invId";
$signature .= isset($invoiceOptions->outSumCurrency) ? ":{$invoiceOptions->outSumCurrency->value}" : '';
$signature .= isset($invoiceOptions->userIP) ? ":$invoiceOptions->userIP" : '';
$receipt = self::getEncodedReceipt($invoiceOptions);
$signature .= isset($receipt) ? ":$receipt" : '';
$signature .= ":$this->password1";
$userParameters = $invoiceOptions->getFormattedUserParameters();
$signature .= !empty($userParameters) ? ':' . $this->implodeUserParameters($userParameters) : '';

return strtolower($this->encryptSignature($signature));
}

/**
* @throws JsonException
*/
private static function getEncodedReceipt(InvoiceOptions $instance): ?string
{
if (is_string($instance->receipt)) {
return $instance->receipt;
}
return is_null($instance->receipt) ? null : json_encode(
$instance->receipt,
JSON_THROW_ON_ERROR | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE
);
}

public function getReceiptAttachResult(ResponseInterface $response): ReceiptAttachResult
{
$jsonObject = $this->parseResponseToJsonObject($response);
Expand All @@ -241,18 +155,6 @@ public function getReceiptAttachResult(ResponseInterface $response): ReceiptAtta
);
}

private function parseResponseToJsonObject(ResponseInterface $response): object
{
/** @var object $jsonObject */
$jsonObject = json_decode(
(string)$response->getBody(),
false,
512,
JSON_THROW_ON_ERROR
);
return $jsonObject;
}

public function getReceiptStatusResult(ResponseInterface $response): ReceiptStatusResult
{
$jsonObject = $this->parseResponseToJsonObject($response);
Expand Down Expand Up @@ -320,21 +222,6 @@ public function getBase64SignedPostData(SecondReceiptOptions|ReceiptStatusOption
return $encodedSecondReceipt . '.' . $this->generateSignatureForSecondReceipt($encodedSecondReceipt);
}

/**
* Робокасса требует удаление знаков "=" из результата кодирования base64
* @param string $string
* @return string
*/
private function clearBase64Encode(string $string): string
{
return rtrim(base64_encode($string), '=');
}

private function generateSignatureForSecondReceipt(string $encodedSecondReceipt): string
{
return $this->clearBase64Encode($this->encryptSignature($encodedSecondReceipt . $this->password1));
}

public function sendSecondReceiptAttach(SecondReceiptOptions $secondReceiptOptions): ResponseInterface
{
$request = $this->secondReceiptAttachRequest($secondReceiptOptions);
Expand Down Expand Up @@ -375,4 +262,119 @@ public function setPsr18Client(?ClientInterface $psr18Client): void
{
$this->psr18Client = $psr18Client;
}

/**
* Получение пользовательских параметров (shp_...) из массива GET или POST параметров
* @param array<string,string> $requestParameters
* @return array<string, string>
*/
private static function getUserParametersFromRequestArray(array $requestParameters): array
{
$userParameters = array_filter(
$requestParameters,
static fn($key) => str_starts_with(strtolower((string)$key), 'shp_'),

Check failure on line 275 in src/RobokassaApi.php

View workflow job for this annotation

GitHub Actions / Unit Tests (PHP 8.2 coverage ubuntu-latest)

RedundantCastGivenDocblockType

src/RobokassaApi.php:275:59: RedundantCastGivenDocblockType: Redundant cast to string given docblock-provided type (see https://psalm.dev/263)
ARRAY_FILTER_USE_KEY
);
$userParametersWithoutPrefix = [];
foreach ($userParameters as $index => $userParameter) {
$userParametersWithoutPrefix[substr_replace($index, '', 0, 4)] = $userParameter;
}
return $userParametersWithoutPrefix;
}

/**
* Получение правильной подписи для параметров результата {@see InvoicePayResult} от Робокассы
*/
private function getValidSignatureForResult(InvoicePayResult $invoicePayResult): string
{
$signature = "$invoicePayResult->outSum:$invoicePayResult->invId";
$signature .= ":$this->password2";
if (!empty($invoicePayResult->userParameters)) {
$signature .= ':' . $this->implodeUserParameters($invoicePayResult->userParameters);
}

return strtolower($this->encryptSignature($signature));
}

/**
* @param array<array-key, string> $additionalUserParameters
* @return string
*/
private function implodeUserParameters(array $additionalUserParameters): string
{
ksort($additionalUserParameters);
foreach ($additionalUserParameters as $key => $value) {
$additionalUserParameters[$key] = $key . '=' . $value;
}
return implode(':', $additionalUserParameters);
}

private function encryptSignature(string $signature): string
{
return hash($this->hashAlgo, $signature);
}

private function parseResponseToJsonObject(ResponseInterface $response): object
{
/** @var object $jsonObject */
$jsonObject = json_decode(
(string)$response->getBody(),
false,
512,
JSON_THROW_ON_ERROR
);
return $jsonObject;
}

/**
* @throws JsonException
*/
private static function getEncodedReceipt(InvoiceOptions $instance): ?string
{
if (is_string($instance->receipt)) {
return $instance->receipt;
}
return is_null($instance->receipt) ? null : json_encode(
$instance->receipt,
JSON_THROW_ON_ERROR | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE
);
}

/**
* Робокасса требует удаление знаков "=" из результата кодирования base64
* @param string $string
* @return string
*/
private function clearBase64Encode(string $string): string
{
return rtrim(base64_encode($string), '=');
}

/**
* Формирование и кодирование подписи:
*
* Минимальный вариант подписи до кодирования
* MerchantLogin:OutSum:Пароль#1
*
* Максимальный вариант подписи до кодирования
* MerchantLogin:OutSum:InvId:OutSumCurrency:UserIp:Receipt:Пароль#1:Shp_...=...:Shp_...=...
*/
private function generateSignatureForPayment(InvoiceOptions $invoiceOptions): string
{
$signature = "$this->merchantLogin:$invoiceOptions->outSum:$invoiceOptions->invId";
$signature .= isset($invoiceOptions->outSumCurrency) ? ":{$invoiceOptions->outSumCurrency->value}" : '';
$signature .= isset($invoiceOptions->userIP) ? ":$invoiceOptions->userIP" : '';
$receipt = self::getEncodedReceipt($invoiceOptions);
$signature .= isset($receipt) ? ":$receipt" : '';
$signature .= ":$this->password1";
$userParameters = $invoiceOptions->getFormattedUserParameters();
$signature .= !empty($userParameters) ? ':' . $this->implodeUserParameters($userParameters) : '';

return strtolower($this->encryptSignature($signature));
}

private function generateSignatureForSecondReceipt(string $encodedSecondReceipt): string
{
return $this->clearBase64Encode($this->encryptSignature($encodedSecondReceipt . $this->password1));
}
}

0 comments on commit 2ed51a9

Please sign in to comment.