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. * * md5(MNT_RESULT_CODE + MNT_ID + MNT_TRANSACTION_ID + КОД) */ public function forResponse(ResultCode $resultCode, string $accountId, string $transactionId): string { return $this->hash((string) $resultCode->value . $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)); } private function hash(string $payload): string { return md5($payload . $this->integrityCode); } }