C# Tinkoff Эквайринг

Отправка запроса на https://securepay.tinkoff.ru/v2/Init, чтобы получить ссылку на оплату.

Чтобы после успешной оплаты тинькофф отправлял запрос на мой сервер (отправляю линк в notificationurl в init).

Но я не понимаю, как проверять токен. В запросе, который мне на сервер присылает, токен не сходится с тем, который я генерирую.

private string GenerateTinkoffToken(Dictionary<string, string> dataForToken)
{
    // 1. Сортируем ключи массива по алфавиту
    var sortedDataKeys = dataForToken.Keys.OrderBy(k => k).ToList();
    var sortedData = new Dictionary<string, string>();
    foreach (var key in sortedDataKeys)
    {
        sortedData.Add(key, dataForToken[key]);
    }

    // 2. Конкатенируем только значения пар в одну строку (без разделителей)
    var concatenatedString = string.Join("", sortedData.Values);

    // 3. Применяем хэш-функцию SHA-256 (с поддержкой UTF-8 - по умолчанию в C#)
    string calculatedToken;
    using (SHA256 sha256Hash = SHA256.Create())
    {
        byte[] bytes = sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(concatenatedString));
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < bytes.Length; i++)
        {
            builder.Append(bytes[i].ToString("x2"));
        }
        calculatedToken = builder.ToString();
    }
    return calculatedToken;
}

Ответы (1 шт):

Автор решения: aepot

Здесь мало чего можно посоветовать. Могу только предположить, что вы почему-то подумали, что Dictionary, в который вы собираете значения - это сортированная коллекция и он будет сохранять порядок ключей так, как вы их добавили. Это далеко не всегда правда. Словарь не гарантирует порядок ключей.

Переписать метод, чтобы он стал более надёжным, если я правильно понял логику из документации, можно так:

private string GenerateTinkoffToken(Dictionary<string, string> dataForToken)
{
    string text = string.Concat(dataForToken.OrderBy(p => p.Key).Select(p => p.Value));
    byte[] hash = SHA256.HashData(Encoding.UTF8.GetBytes(text));
    
    return Convert.ToHexStringLower(hash);
}

Вы не указали версию .NET, поэтому будем считать, что у вас актуальный на текущий момент .NET 9.

Но мне кажется, что ваша проблема где-то за пределами показанного кода.

→ Ссылка