Skip to main content

Receiving server configuration

To receive real-time notifications, you need a secure server. To achieve this, follow the steps below.

Prepare the server

To receive notifications, deploy a server that will:

  • receive notifications as POST requests from RuStore;
  • response to requests with HTTP code 200 ОК, if a notification is received;
  • response to requests with HTTP codes 4xx or 5xx, if it fails to receive a notification and the notification has to be sent again.

Your server is responsible for sending response for all notifications as well as for analysis and interpretation of the notifications.

Add the RuStore IP address in the white list

Create a Firewall rule that allows your server to receive notifications from the RuStore IP address 95.163.133.1:8080. We recommend to disallow processing other IP addresses.

Bind domain and issue a certificate

Define a URL address for the server that will receive notifications. Notification service works only with addresses that begin with https://.

Your server must support TLS connection by a certificate that was issued by a certificate authority. For example, Let’s Encrypt. Certificates issued by the Ministry of Digital Development, Communications and Mass Media of the Russian Federation are also supported.

If your server is deployed i a public cloud, the certificate can also be obtained from the cloud provider.

Configure notification decryption

For security, payment information is encrypted with AES-256 with the following parameters:

  • AES/GCM/NoPadding;
  • initialization vector length (IV) — 12;
  • tag length — 16.
note

You can read more about this algorithm, for example, here.

On receiving a notification your algorithm must decrypt the payload string from body. You get the decryption key from the RuStore Console after configuring notifications or on encryption key update.

Notification decryption example for Java

//Initialization vector length
private static final int GCM_IV_LENGTH = 12;
//tag length
private static final int GCM_TAG_LENGTH = 16;
//algorithm
private static final String CIPHER_ALGORITHM = "AES/GCM/NoPadding";

public String decrypt(
//string, that is passed in the request from RuStore
String encryptedInput,
//the key copied from the console
String secretKey
) {
try {
//decoding incoming ecrypt message
byte[] decoded = Base64.getDecoder().decode(encryptedInput.getBytes(StandardCharsets.UTF_8));
//get the vector from the byte sequence
byte[] ivDecrypt = Arrays.copyOfRange(decoded, 0, GCM_IV_LENGTH);
//initialize GCM parameters object
GCMParameterSpec ivSpec = new GCMParameterSpec(GCM_TAG_LENGTH * Byte.SIZE, ivDecrypt);
//get object instance using the encryption algorithm
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
//initializing encryption object in the decrypt mode using the key and the vector
cipher.init(Cipher.DECRYPT_MODE, convertStringToSecretKey(secretKey), ivSpec);
//decrypt the byte sequence starting from where the vector ended
byte[] ciphertext = cipher.doFinal(decoded, GCM_IV_LENGTH, decoded.length - GCM_IV_LENGTH);
//return response in the String UTF_8 format
return new String(ciphertext, StandardCharsets.UTF_8);
} catch (Exception e) {
//log the problem in case of an error
logger.warn("Something went wrong with decrypting", e);
throw new RuntimeException(e);
}
}

//deserialize Base64(UTF_8) in the SecretKey object
private SecretKey convertStringToSecretKey(String secretKey) {
byte[] decodedKey = Base64.getDecoder().decode(secretKey.getBytes(StandardCharsets.UTF_8));
return new SecretKeySpec(decodedKey, 0, decodedKey.length, "AES");
}

What next

Configure and test notifications in the RuStore Console to make sure the server is configured correctly.