public string BuySubscription(int accountId, string subscriptionType)
        {
            string subscriptionTypes = System.IO.File.ReadAllText("SubscriptionTypes.json");
            int    subscriptionCost;
            int    subscriptionDuration;
            string subscriptionDescription;

            using (JsonDocument doc = JsonDocument.Parse(subscriptionTypes))
            {
                JsonElement root       = doc.RootElement;
                JsonElement jsSubsType = root.GetProperty(subscriptionType);

                subscriptionCost        = jsSubsType.GetProperty("cost").GetInt32();
                subscriptionDuration    = jsSubsType.GetProperty("duration").GetInt32();
                subscriptionDescription = jsSubsType.GetProperty("description").GetString();
            }

            if (subscriptionCost == 0 || subscriptionDuration == 0)
            {
                throw new AppException("Ошибка в указании типа подписки");
            }

            // 1. Сохраняем информацию о покупке в БД и формируем ссылку для оплаты

            Subscription newSubscription = new Subscription
            {
                UserId    = accountId,
                Type      = subscriptionType,
                Duration  = subscriptionDuration,
                Cost      = subscriptionCost,
                OrderDate = DateTime.Now
            };

            _context.Subscriptions.Add(newSubscription);
            _context.SaveChanges();

            int invoiceId = _context.Subscriptions.SingleOrDefault(x =>
                                                                   x.UserId == newSubscription.UserId &&
                                                                   x.OrderDate == newSubscription.OrderDate)
                            .Id;

            RobokassaItemModel[] robokassaItems = new RobokassaItemModel[] {
                new RobokassaItemModel {
                    name     = subscriptionDescription,
                    quantity = 1,
                    sum      = subscriptionCost,
                    tax      = "none"
                }
            };

            RobokassaReceiptModel robokassaReceipt = new RobokassaReceiptModel {
                items = robokassaItems
            };

            var robokassaInfo = GenerateRobokassaLink(subscriptionCost, subscriptionDescription, invoiceId, robokassaReceipt);

            newSubscription.OrderId = robokassaInfo.signatureValue;
            _context.Subscriptions.Update(newSubscription);
            _context.SaveChanges();

            // 2. Перенаправляем пользователя на страницу оплаты
            string url = robokassaInfo.link;

            return(url);
        }
        private async void SendSecondReceipt(int invId, int outSum, string emailClient)
        {
            string       subscriptionTypes = System.IO.File.ReadAllText("SubscriptionTypes.json");
            Subscription paidSubscription  = _context.Subscriptions.SingleOrDefault(x => x.Id == invId);
            string       subscriptionType  = paidSubscription.Type;
            string       subscriptionDescription;

            using (JsonDocument doc = JsonDocument.Parse(subscriptionTypes))
            {
                JsonElement root       = doc.RootElement;
                JsonElement jsSubsType = root.GetProperty(subscriptionType);

                subscriptionDescription = jsSubsType.GetProperty("description").GetString();
            }

            RobokassaItemModel[] robokassaItems = new RobokassaItemModel[] {
                new RobokassaItemModel {
                    name           = subscriptionDescription,
                    quantity       = 1,
                    sum            = outSum,
                    tax            = "none",
                    payment_method = "full_payment"
                }
            };

            RobokassaClientModel robokassaClient = new RobokassaClientModel {
                email = emailClient
            };

            RobokassaPaymentModel[] robokassaPayments = new RobokassaPaymentModel[] {
                new RobokassaPaymentModel {
                    type = 2,
                    sum  = outSum
                }
            };

            RobokassaVatModel[] robokassaVats = new RobokassaVatModel[] {
                new RobokassaVatModel {
                    type = "none",
                    sum  = 0
                }
            };

            string roboShopName = _appSettings.RobokassaShopName;
            RobokassaResultReceiptModel robokassaResultReceipt = new RobokassaResultReceiptModel {
                merchantId = roboShopName,
                originId   = invId,
                id         = invId + 1,
                operation  = "sell",
                url        = "https:__usa-invest.ru", // запрос придется кодировать в base64, так что сразу заменим "/" на "_"
                total      = outSum,
                items      = robokassaItems,
                client     = robokassaClient,
                payments   = robokassaPayments,
                vats       = robokassaVats
            };

            JsonSerializerOptions jsonOptions = new JsonSerializerOptions
            {
                Encoder          = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
                IgnoreNullValues = true
            };

            string jsStrSecondReceipt = JsonSerializer.Serialize <RobokassaResultReceiptModel>(robokassaResultReceipt, jsonOptions);
            var    secondReciptBytes  = Encoding.UTF8.GetBytes(jsStrSecondReceipt);
            string firstBase64string  = Convert.ToBase64String(secondReciptBytes).Replace("=", "");

            string signature       = generateSHA256Hash(firstBase64string + _appSettings.RobokassaFirstPassw);
            var    signatureBytes  = Encoding.UTF8.GetBytes(signature);
            string signatureBase64 = Convert.ToBase64String(signatureBytes).Replace("=", "");

            string finalBase64Request = firstBase64string + "." + signatureBase64;

            try
            {
                var stringContent = new StringContent(finalBase64Request, Encoding.UTF8, "text/plain");
                var response      = await new HttpClient().PostAsync("https://ws.roboxchange.com/RoboFiscal/Receipt/Attach", stringContent);

                string strResponse = await response.Content.ReadAsStringAsync();

                Log($" Method = SendSecondReceipt, InvoiceId = {invId}, SecondReceipt = {jsStrSecondReceipt}, Response = {strResponse}");
            }
            catch (Exception ex)
            {
                Log($" EXCEPTION: Method = SendSecondReceipt, Ex.message = {ex.Message}, InvoiceId = {invId}, SecondReceipt = {jsStrSecondReceipt}");
            }
        }