feat: moneta 2.0, MONETA.Assistant payment module for PHPShop 6.7+

This commit is contained in:
2026-10-27 11:45:22 +03:00
parent 78b7405637
commit f8c12ce44a
82 changed files with 7387 additions and 58 deletions
+116
View File
@@ -0,0 +1,116 @@
<?php
declare(strict_types=1);
namespace MonetaPhpShop\protocol;
use InvalidArgumentException;
use MonetaPhpShop\Money;
/**
* Òðè ôîðìóëû ïîäïèñè MONETA.Assistant (`MONETA.Assistant.ru.pdf`, ãë. 3–5).
*
* Âåçäå MD5 îò êîíêàòåíàöèè çíà÷åíèé áåç ðàçäåëèòåëåé ïëþñ êîä ïðîâåðêè
* öåëîñòíîñòè; îòñóòñòâóþùèé ïàðàìåòð — ïóñòàÿ ñòðîêà. Ýêçåìïëÿð äåðæèò êîä,
* ÷òîáû îí íå ãóëÿë ïî ñèãíàòóðàì ìåòîäîâ è íå ïîïàäàë â òðàññèðîâêè.
*/
final class Signature
{
private const PATTERN = '/\A[0-9a-f]{32}\z/i';
/** @var string */
private $integrityCode;
public function __construct(
#[\SensitiveParameter]
string $integrityCode
) {
if ($integrityCode === '') {
throw new InvalidArgumentException('Êîä ïðîâåðêè öåëîñòíîñòè íå çàäàí.');
}
$this->integrityCode = $integrityCode;
}
/**
* Ôîðìóëà 1 — ïëàò¸æíàÿ ôîðìà (ìîäóëü -> ñåðâèñ).
*
* md5(MNT_ID + MNT_TRANSACTION_ID + MNT_AMOUNT + MNT_CURRENCY_CODE + MNT_SUBSCRIBER_ID + MNT_TEST_MODE + ÊÎÄ)
*/
public function forPaymentForm(
string $accountId,
string $transactionId,
Money $amount,
string $currency,
string $subscriberId,
bool $testMode
): string {
return $this->hash(
$accountId
. $transactionId
. $amount->toDecimal()
. $currency
. $subscriberId
. AssistantProtocol::testModeFlag($testMode),
);
}
/**
* Ôîðìóëà 2 — âõîäÿùèé çàïðîñ íà Check URL / Pay URL (ñåðâèñ -> ìîäóëü).
*
* md5(MNT_COMMAND + MNT_ID + MNT_TRANSACTION_ID + MNT_OPERATION_ID + MNT_AMOUNT
* + MNT_CURRENCY_CODE + MNT_SUBSCRIBER_ID + MNT_TEST_MODE + ÊÎÄ)
*
* Çíà÷åíèÿ áåðóòñÿ èç çàïðîñà êàê ïðèøëè: ïîäïèñü ñâåðÿåòñÿ ñ òåì, ÷òî
* ïîäïèñàë ñåðâèñ, à íå ñ íàøèì ïðåäñòàâëåíèåì î çàêàçå.
*/
public function forNotification(CallbackNotification $notification): string
{
return $this->hash(
$notification->getCommand()
. $notification->getAccountId()
. $notification->getTransactionId()
. $notification->getOperationId()
. $notification->getRawAmount()
. $notification->getCurrency()
. $notification->getSubscriberId()
. $notification->getRawTestMode(),
);
}
/**
* Ôîðìóëà 3 — îòâåò ìîäóëÿ íà Check URL è Pay URL (XML è JSON).
*
* md5(MNT_RESULT_CODE + MNT_ID + MNT_TRANSACTION_ID + ÊÎÄ)
*/
public function forResponse(ResultCode $resultCode, string $accountId, string $transactionId): string
{
return $this->hash((string) $resultCode->getValue() . $accountId . $transactionId);
}
/**
* Ñðàâíåíèå áåç óòå÷êè ïî âðåìåíè; ðåãèñòð hex-ñòðîêè íå âàæåí.
*/
public static function equals(string $expected, string $received): bool
{
if (preg_match(self::PATTERN, $received) !== 1) {
return false;
}
return hash_equals(strtolower($expected), strtolower($received));
}
/**
* Êîä ïðîâåðêè öåëîñòíîñòè íå âûâîäèòñÿ â var_dump()/print_r() è æóðíàëû.
*
* @return array<string, string>
*/
public function __debugInfo(): array
{
return ['integrityCode' => '***'];
}
private function hash(string $payload): string
{
return md5($payload . $this->integrityCode);
}
}