Skip to main content
Version: LIFE PAY Online 1.0

Алгоритм формирования подписи для API v 2.0

Создать нормализованную строку запроса для использования на следующих стадиях:

  1. Отсортировать параметры по имени в utf­8, сравнивая побайтово. Параметры берутся из GET URI или из тела POST­ запроса (когда Content­Type = application/x­www­form­urlencoded)
  2. URL­кодировать имена и значения параметров по следующим правилам:
    • Не кодировать определённые в RFC 3986 незарезервированные символы. Эти символы: A­z, a­z, 0­9, минус ­-, подчёркивание _, точка . и тильда ~.
    • Все остальные символы должны быть закодированы как %XY, где X и Y ­это шестнадцатеричные символы от 0 до 9 и от A до F (заглавные). Расширенные utf­8 символы кодируются как %XY%ZA…
    • Пробел кодируется как %20 (и не как +, как обычно делается в URL)
    • Кодированные имена параметров отделяются от кодированных значений знаком равно (=, ASCII­код 61), даже если параметр имеет пустое значение.
    • Пары имя – значение разделяются символом амперсанда (&, ASCII – код 38).
  3. Создать строку для подписи в соответствии со следующей псевдо–грамматикой (где \n это ASCII – символов перевода строки):
    StringToSign = HTTPVerb + "\n" +
    ValueOfHostHeaderInLowercase + "\n" +
    HTTPRequestURI + "\n" +
    CanonicalizedQueryString

    # HTTPVerb ­- метод POST, GET, PUT или DELETE.
    # ValueOfHostHeaderInLowercase - параметр host из заголовка HTTP запроса.
    # HTTPRequestURI ­- компонент URI, абсолютный путь до, но не включая GET­-параметров.
    # Для пустого пути ожидается '/'.
    # CanonicalizedQueryString - строка с предыдущего шага.
  4. Рассчитать совместимый с RFC 2104 HMAC по только что созданной строке StringToSign, используя секретный ключ партнёра как ключ алгоритма, и SHA256 как способ хэширования.
  5. Сконвертировать полученную подпись в base64.
  6. Использовать результат как значение параметра check.

Пример расчёта

function http_build_query_rfc_3986($queryData, $argSeparator='&')
{
$r = '';
$queryData = (array) $queryData;
if(!empty($queryData))
{
foreach($queryData as $k=>$queryVar)
{
$r .= $argSeparator.$k.'='.rawurlencode($queryVar);
}
}
return trim($r,$argSeparator);
}
function sign($method, $url, $params, $secretKey, $skipPort=False)
{
ksort($params, SORT_LOCALE_STRING);
$urlParsed = parse_url($url);
$path = $urlParsed['path'];
$host = isset($urlParsed['host'])? $urlParsed['host']: "";
if (isset($urlParsed['port']) && $urlParsed['port'] != 80) {
if (!$skipPort) {
$host .= ":{$urlParsed['port']}";
}
}

$method = strtoupper($method) == 'POST'? 'POST': 'GET';

$data = implode("\n",
array(
$method,
$host,
$path,
http_build_query_rfc_3986($params)
)
);

$signature = base64_encode(
hash_hmac("sha256",
"{$data}",
"{$secretKey}",
TRUE
)
);

return $signature;
}

// Пример вызова, где $req - массив с параметрами транзакции:
sign("GET", "https://partner.life-pay.ru/alba/input/", $req, 'secret');