Проверить sha256 в ответе платежной системы UnitPay
17.01.2021, 20:14. Просмотров 373. Ответов 1
Здравствуйте, ребята. Мучаюсь уже два дня. Никак не могу правильно сформировать 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 | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| 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 | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
| $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 | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| 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
0
|