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 (string link, string signatureValue) GenerateRobokassaLink(decimal amount, string description, int invoiceId, RobokassaReceiptModel receipt) { bool isTest = true; string roboShopName = _appSettings.RobokassaShopName; string roboFirstPassw = _appSettings.RobokassaFirstPassw; JsonSerializerOptions jsonOptions = new JsonSerializerOptions { Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, IgnoreNullValues = true }; string jsStringReceipt = JsonSerializer.Serialize <RobokassaReceiptModel>(receipt, jsonOptions); // кодировать Receipt нужно 1 раз для расчета сигнатуры и 2 раза для добавления в ссылку, // т.к. браузер автоматически декодирует его (так сказали в техподдержке робокассы) string signatureReceipt = WebUtility.UrlEncode(jsStringReceipt); string urlReceipt = WebUtility.UrlEncode(signatureReceipt); string amountStr = amount.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture), invoiceIdStr = invoiceId.ToString(), srcBase = $"{roboShopName}:{amountStr}:{invoiceIdStr}:{signatureReceipt}:{roboFirstPassw}"; //srcBase = $"{roboShopName}:{amountStr}:{invoiceIdStr}:{roboFirstPassw}"; string signatureValue = generateSHA256Hash(srcBase); string authPaymentString; if (isTest) { authPaymentString = "https://auth.robokassa.ru/Merchant/Index.aspx" + "?isTest=1" + "&MrchLogin="******"&OutSum=" + amountStr + "&InvId=" + invoiceIdStr + "&Receipt=" + urlReceipt + "&Description=" + description + "&SignatureValue=" + signatureValue + "&Culture=ru"; } else { authPaymentString = "https://auth.robokassa.ru/Merchant/Index.aspx" + "?MrchLogin="******"&OutSum=" + amountStr + "&InvId=" + invoiceIdStr + "&Receipt=" + urlReceipt + "&Description=" + description + "&SignatureValue=" + signatureValue + "&Culture=ru"; } return(authPaymentString, signatureValue); }