跳到主要内容

Настройка сервера для получения уведомлений

Чтобы получать уведомления в режиме реального времени, вам необходимо создать безопасный сервер. Для этого выполните шаги, перечисленные ниже.

Подготовьте сервер

Для получения уведомлений разверните сервер, который будет:

  • принимать уведомления в формате POST-запросов от RuStore;
  • отвечать на запросы HTTP-кодом 200 ОК, если уведомление принято;
  • отвечать на запросы HTTP-кодами ошибок 4xx или 5xx, если не удалось получить уведомление и необходимо повторить отправку.

Ваш сервер отвечает за отправку ответов на все уведомления, а также анализ и интерпретацию уведомлений.

Добавьте IP-адрес RuStore в белый список

Создайте правило Firewall, разрешающее вашему серверу получать уведомления от IP-адреса RuStore 95.163.133.1:8080. Обработку запросов с остальных IP-адресов рекомендуем запретить.

Привяжите домен и выпустите сертификат

Определите URL-адрес для сервера, который будет получать уведомления. Сервис по отправке уведомлений работает только с теми адресами, которые начинаются на https://.

Ваш сервер должен поддерживать TLS-соединение сертификатом, который выпущен центром сертификации. Например, Let’s Encrypt. Подходят в том числе сертификаты, выпущенные Национальным удостоверяющим центром Минцифры РФ.

Если ваш сервер развёрнут в публичном облаке, сертификат также можно получить у облачного провайдера.

Настройте расшифровку уведомления

В целях безопасности информация о платежах шифруется с помощью механизма симметричного шифрования AES-256 с параметрами:

  • AES/GCM/NoPadding;
  • длина вектора инициализации (IV) — 12;
  • длина тега — 16.
备注

Подробности об этом алгоритме шифрования вы можете посмотреть, например, тут.

При получении уведомления ваш алгоритм должен расшифровывать строку payload из body. Ключ для расшифровки вы получаете в RuStore Консоль после настройки отправки уведомлений или при обновлении ключа шифрования.

Пример расшифровки уведомления на Java

//длина Initialization vector
private static final int GCM_IV_LENGTH = 12;
//длина тега
private static final int GCM_TAG_LENGTH = 16;
//алгоритм
private static final String CIPHER_ALGORITHM = "AES/GCM/NoPadding";

public String decrypt(
//строка, которая приходит в запросе от RuStore
String encryptedInput,
//ключ, который копируем из консоли
String secretKey
) {
try {
//декодируем входящее ecrypt сообщение
byte[] decoded = Base64.getDecoder().decode(encryptedInput.getBytes(StandardCharsets.UTF_8));
//выделяем вектор из последовательности байт
byte[] ivDecrypt = Arrays.copyOfRange(decoded, 0, GCM_IV_LENGTH);
//инициализируем объект параметров GCM
GCMParameterSpec ivSpec = new GCMParameterSpec(GCM_TAG_LENGTH * Byte.SIZE, ivDecrypt);
//получаем инстанс объекта по алгоритму шифрования
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
//инициализируем объект шифрования в режиме decrypt, ключом и вектором
cipher.init(Cipher.DECRYPT_MODE, convertStringToSecretKey(secretKey), ivSpec);
//дешифруем набор байт начиная с окончания вектора
byte[] ciphertext = cipher.doFinal(decoded, GCM_IV_LENGTH, decoded.length - GCM_IV_LENGTH);
//возвращаем ответ в формате String UTF_8
return new String(ciphertext, StandardCharsets.UTF_8);
} catch (Exception e) {
//в случае ошибки логируем проблему
logger.warn("Something went wrong with decrypting", e);
throw new RuntimeException(e);
}
}

//десериализуем ключ из текстового формата Base64(UTF_8) в объект SecretKey
private SecretKey convertStringToSecretKey(String secretKey) {
byte[] decodedKey = Base64.getDecoder().decode(secretKey.getBytes(StandardCharsets.UTF_8));
return new SecretKeySpec(decodedKey, 0, decodedKey.length, "AES");
}

Что дальше

Настройте и протестируйте отправку уведомлений в RuStore Консоль, чтобы убедиться в корректности конфигурации сервера.