request = $request; $this->data = $data; if (strtolower($this->getSignatureValue(false)) !== $this->generateSignature()) { if (strtolower($this->getSignatureValue(true) !== $this->generateSignature())) { throw new InvalidResponseException('Invalid hash'); } } } public function generateSignature(bool $includeCurrency = false): string { $params = [ $this->getAmount(), $this->getTransactionReference(), $this->request->getSecretKey2() ]; foreach ($this->getCustomFields($includeCurrency) as $field => $value) { $params[] = "$field=$value"; } return md5(implode(':', $params)); } public function getCustomFields(bool $includeCurrency = false): array { $fields = array_filter([ 'Shp_TransactionId' => $this->getTransactionId(), 'Shp_Client' => $this->getClient(), 'Shp_Currency' => $includeCurrency ? $this->getCurrency() : null, ]); ksort($fields); return $fields; } public function getSignatureValue() { return $this->data['SignatureValue']; } public function getClient() { return $this->data['Shp_Client']; } public function getAmount() { return $this->data['OutSum']; } public function getPayer() { return $this->data['PaymentMethod']; } public function getTransactionId() { return $this->data['Shp_TransactionId']; } public function getCurrency() { return $this->data['OutSumCurrency'] ?? 'RUB'; } /** * RoboKassa does not provide real transaction reference (ID of payment on RoboKassa side) 😕 * * @return string The InvId property, or 0 (zero) if InvId is not set. */ public function getTransactionReference() { return $this->data['InvId'] ?? '0'; } public function getInvId() { return $this->getTransactionReference(); } public function isSuccessful() { return true; } }