Здравствуйте, ребята. Мучаюсь уже два дня. Никак не могу правильно сформировать sha256 Цифровая подпись. Образуется как sha256(method + "{up}" + params + "{up}" + secretKey), где sha256 - метод шифрования; "{up}" - разделитель параметров в хеш-функции; method - тип вызова (check, pay, error); params - значения параметров из массива params, объединенные разделителем "{up}". Все параметры должны быть предварительно отсортированы по ключу, в склейке не участвуют параметры sign и signature; secretKey - секретный ключ проекта (доступен в личном кабинете); Пример расчета подписи для запроса http://partnerUrl?method=check & params=bob & params[c]=sam & params[a]=todи секретного ключа "a1b1c1d1" sha256("check{up}tod{up}bob{up}sam{up}a1b1c1d1") Ответ UnitPay PHP: array ()array ( 'action' => 'unitpay', 'method' => 'pay', 'params' => array ( 'account' => 'test', 'date' => '2021-01-17 17:50:12', 'ip' => '93.80.3.62', 'isPreauth' => '0', 'operator' => 'mts', 'orderCurrency' => 'RUB', 'orderSum' => '10.00', 'payerCurrency' => 'RUB', 'payerSum' => '10.00', 'paymentType' => 'mc', 'phone' => '0', 'profit' => '8', 'projectId' => '123456', 'signature' => '65f56854115sadfdfa103798a8c34b6cd0ad55ccf9caf91f70e7745ad8bd1e76f93a54aad', 'sum' => '10', 'test' => '1', 'unitpayId' => '175', ),) Вот таким образом у меня правильно формируется подпись, но только для одного метода платежа. Если метод платежа меняется, то параметры могут немного меняться, поэтому подпись уже неверна. PHP: $canal = 'unitpay'; $amount_value = $_GET['params']['payerSum']; //сумма платежа $payment_id_unitpay = $_GET['params']['account']; // № транзакции $CURRENCY = Config_Payment::UNITPAY_CURRENCY; // валюта. Для проверки платежа $UNITPAY_PROJECTID = Config_Payment::UNITPAY_PROJECTID; // номер магазина. Для проверки платежа $secret_key = Config_Payment::UNITPAY_SECRETKEY; // секретный ключ if (stripos($payment_id_unitpay, ':')) { // передавали uid и транзакцию в одном параметре. Теперь разбираем из ответа $payment_id_unitpay_2 = explode(":", $payment_id_unitpay); $account = (int) $payment_id_unitpay_2[0]; // id $billId = (int) $payment_id_unitpay_2[1]; // транзакция } // sha256. Старт. Написано для теста. При типе платежа "Мобильная коммерция" ключ совпадает. При других типах массив имеет другие параметры. $method = $_GET['method']; $date = $_GET['params']['date']; $ip = $_GET['params']['ip']; $isPreauth = $_GET['params']['isPreauth']; $operator = $_GET['params']['operator']; $orderCurrency = $_GET['params']['orderCurrency']; $orderSum = $_GET['params']['orderSum']; $payerCurrency = $_GET['params']['payerCurrency']; $payerSum = $_GET['params']['payerSum']; $paymentType = $_GET['params']['paymentType']; $phone = $_GET['params']['phone']; $profit = $_GET['params']['profit']; $projectId = $_GET['params']['projectId']; $sum = $_GET['params']['sum']; $test = $_GET['params']['test']; $unitpayId = $_GET['params']['unitpayId']; $sha256_hash_header = $_GET['params']['signature']; function getFormSignature($method, $payment_id_unitpay, $date, $ip, $isPreauth, $operator, $orderCurrency, $orderSum, $payerCurrency, $payerSum, $paymentType, $phone, $profit, $projectId, $sum, $test, $unitpayId, $secret_key) { $hashStr = $method.'{up}'.$payment_id_unitpay.'{up}'.$date.'{up}'.$ip.'{up}'.$isPreauth.'{up}'.$operator.'{up}'.$orderCurrency.'{up}'.$orderSum.'{up}'.$payerCurrency.'{up}'.$payerSum.'{up}'.$paymentType.'{up}'.$phone.'{up}'.$profit.'{up}'.$projectId.'{up}'.$sum.'{up}'.$test.'{up}'.$unitpayId.'{up}'.$secret_key; return hash('sha256', $hashStr); } $sha256_hash = getFormSignature($method, $payment_id_unitpay, $date, $ip, $isPreauth, $operator, $orderCurrency, $orderSum, $payerCurrency, $payerSum, $paymentType, $phone, $profit, $projectId, $sum, $test, $unitpayId, $secret_key); // sha256. Финиш if ($sha256_hash_header == $sha256_hash && !empty($sha256_hash_header)) { // Сравнение sha256 $userID = (int) $account; $defint = (int) $billId; $amount = $amount_value; } else { die(json_encode(array("error" => array("message" => "Invalid data")))); } //if($_GET['params']['sum'] != (float) $_GET['params']['orderSum']) { // die(json_encode(array("error" => array("message" => "Invalid amount transferred ")))); //} if($_GET['params']['orderCurrency'] != $CURRENCY) { die(json_encode(array("error" => array("message" => "Invalid transferred currency")))); } if($_GET['params']['projectId'] != $UNITPAY_PROJECTID) { die(json_encode(array("error" => array("message" => "Invalid project id")))); } if($_GET['method'] == 'check'){ die(json_encode(array("result" => array("message" => "Successful check")))); } if($_GET['method'] == 'preauth'){ die(json_encode(array("result" => array("message" => "Pre-authorization. Waiting for payment")))); } if($_GET['method'] == 'error'){ die(json_encode(array("result" => array("message" => "Payment error. Expectation")))); } if($_GET['method'] == 'pay'){ $this->addBalance($canal, $userID, $amount, $defint); // Начисляем баланс die(json_encode(array("result" => array("message" => "Success")))); } Вот кусок кода из sdk unitpay, но у себя подобное я сделать не смог: PHP: private $params = array();function getSignature(array $params, $method = null) { ksort($params); unset($params['sign']); unset($params['signature']); array_push($params, $this->secretKey); if ($method) { array_unshift($params, $method); } return hash('sha256', join('{up}', $params)); }list($method, $params) = array($_GET['method'], $_GET['params']); if (!in_array($method, $this->supportedPartnerMethods)) { throw new UnexpectedValueException('Method is not supported'); } if (!isset($params['signature']) || $params['signature'] != $this->getSignature($params, $method)) { throw new InvalidArgumentException('Wrong signature'); } https://help.unitpay.ru/payments/payment-handler
PHP: $method = filter_input(INPUT_GET, 'method');$params = filter_input(INPUT_GET, 'params', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY);$secret_key = Config_Payment::UNITPAY_SECRETKEY;ksort($params);unset($params['sign']);unset($params['signature']);array_push($params, $secret_key);if( $method ) array_unshift($params, $method);$sha256_hash = hash('sha256', join('{up}', $params));
Unitpay не выключает теперь проверку подписи и я столкнулся с такой проблемой, при запросе пишет wrong signature, вот сам файл, помогите дописать? Буду очень признателен. Я так понимаю мне надо запихнуть в функцию эти строки: Вот сам код функции: Code: <?php function getSha1sign($method, $params) { ksort($params); unset($params['sign']); unset($params['signature']); array_push($params, Flux::config('up_secret_key')); array_unshift($params, $method); return hash('sha256', join('{up}', $params)); } function checkHandlerRequest() { $ip = $_SERVER['REMOTE_ADDR']; if (!isset($_GET['method'])) { throw new Exception('Method is null'); } if (!isset($_GET['params'])) { throw new InvalidArgumentException('Params is null'); } list($method, $params) = array($_GET['method'], $_GET['params']); if (!in_array($method, Flux::config('up_supportedPartnerMethods')->toArray())) { throw new UnexpectedValueException('Method is not supported'); } if ($params['signature'] != getSha1sign($_GET['method'], $params)) { throw new InvalidArgumentException('Wrong signature'); } /** * IP address check * @link https://unitpay.ru/doc#overview */ if (!in_array($ip, Flux::config('up_supportedUnitpayIp')->toArray())) { throw new InvalidArgumentException('IP address Error'); } return true; } /** * Response for UnitPay if handle success * * @param $message * * @return string */ function getSuccessHandlerResponse($message) { return json_encode(array( "result" => array( "message" => $message ) )); } /** * Response for UnitPay if handle error * * @param $message * * @return string */ function getErrorHandlerResponse($message) { return json_encode(array( "error" => array( "message" => $message ) )); }
В функции function getSha1sign у вас итак все формируется. Может просто секретный ключ неверный указали в конфиге? Плюс юнитпею без разницы проверяете вы хеш или не проверяете. Это нужно только для вас.