diff --git a/VkNet.Tests/Categories/Store/StoreCategoryTest.cs b/VkNet.Tests/Categories/Store/StoreCategoryTest.cs
new file mode 100644
index 000000000..a3f3e21b3
--- /dev/null
+++ b/VkNet.Tests/Categories/Store/StoreCategoryTest.cs
@@ -0,0 +1,169 @@
+using System;
+using FluentAssertions;
+using VkNet.Enums.StringEnums;
+using VkNet.Tests.Infrastructure;
+using Xunit;
+
+namespace VkNet.Tests.Categories.Store;
+
+public class StoreCategoryTest : CategoryBaseTest
+{
+ protected override string Folder => "Store";
+
+ [Fact]
+ public void AddStickersToFavorite()
+ {
+ Url = "https://api.vk.com/method/store.addStickersToFavorite";
+
+ ReadCategoryJsonPath(nameof(AddStickersToFavorite));
+
+ var result = Api.Store.AddStickersToFavorite(new()
+ {
+ StickerIds = ["126", "70"]
+ });
+
+ result.Should()
+ .BeTrue();
+ }
+
+ [Fact]
+ public void GetFavoriteStickers()
+ {
+ Url = "https://api.vk.com/method/store.getFavoriteStickers";
+
+ ReadCategoryJsonPath(nameof(GetFavoriteStickers));
+
+ var result = Api.Store.GetFavoriteStickers();
+
+ result.Count.Should()
+ .Be(2);
+
+ var first = result[0];
+
+ first.Id.Should()
+ .Be(126);
+
+ first.InnerType.Should()
+ .Be("base_sticker_new");
+
+ first.IsAllowed.Should()
+ .BeTrue();
+
+ var second = result[1];
+
+ second.Id.Should()
+ .Be(70);
+
+ second.InnerType.Should()
+ .Be("base_sticker_new");
+
+ second.IsAllowed.Should()
+ .BeFalse();
+ }
+
+ [Fact]
+ public void GetProducts()
+ {
+ Url = "https://api.vk.com/method/store.getProducts";
+
+ ReadCategoryJsonPath(nameof(GetProducts));
+
+ var result = Api.Store.GetProducts(new()
+ {
+ Type = ProductType.Stickers,
+ ProductIds = ["148"],
+ Filters = [ProductStatusFilter.Purchased, ProductStatusFilter.Active],
+ Extended = true
+ });
+
+ result.Count.Should()
+ .Be(1);
+
+ var product = result[0];
+
+ product.Id.Should()
+ .Be(148);
+
+ product.Type.Should()
+ .Be(ProductType.Stickers);
+
+ product.IsNew.Should()
+ .BeFalse();
+
+ product.Copyright.Should()
+ .Be("ООО «ВКонтакте» 2017");
+
+ product.Purchased.Should()
+ .BeTrue();
+
+ product.Active.Should()
+ .BeTrue();
+
+ product.PurchaseDate.Should()
+ .Be(DateTime.Parse("2024-01-10 12:52:23 PM"));
+
+ product.Title.Should()
+ .Be("#ПушкинНашеВсё");
+
+ product.Stickers.Count.Should()
+ .Be(24);
+
+ product.Icon.BaseUrl.Should()
+ .Be("https://vk.com/sticker/packs/148/icon");
+
+ product.Previews.Count.Should()
+ .Be(5);
+ }
+
+ [Fact]
+ public void GetStickersKeywords()
+ {
+ Url = "https://api.vk.com/method/store.getStickersKeywords";
+
+ ReadCategoryJsonPath(nameof(GetStickersKeywords));
+
+ var result = Api.Store.GetStickersKeywords(new()
+ {
+ StickerIds = ["126"],
+ Aliases = true,
+ AllProducts = false,
+ NeedStickers = true
+ });
+
+ result.Dictionary.Count.Should()
+ .Be(1);
+
+ result.Dictionary[0].Words.Count.Should()
+ .Be(51);
+
+ result.Dictionary[0].UserStickers.Count.Should()
+ .Be(1);
+
+ var sticker = result.Dictionary[0].UserStickers[0];
+
+ sticker.InnerType.Should()
+ .Be("base_sticker_new");
+
+ sticker.Id.Should()
+ .Be(126);
+
+ sticker.IsAllowed.Should()
+ .BeTrue();
+ }
+
+ [Fact]
+ public void RemoveStickersFromFavorite()
+ {
+ Url = "https://api.vk.com/method/store.removeStickersFromFavorite";
+
+ ReadCategoryJsonPath(nameof(RemoveStickersFromFavorite));
+
+ var result = Api.Store.RemoveStickersFromFavorite(new()
+ {
+ StickerIds = ["126", "70"]
+ });
+
+ result.Should()
+ .BeTrue();
+ }
+}
\ No newline at end of file
diff --git a/VkNet.Tests/TestData/Categories/Store/AddStickersToFavorite.json b/VkNet.Tests/TestData/Categories/Store/AddStickersToFavorite.json
new file mode 100644
index 000000000..a318c4360
--- /dev/null
+++ b/VkNet.Tests/TestData/Categories/Store/AddStickersToFavorite.json
@@ -0,0 +1,3 @@
+{
+ "response": 1
+}
\ No newline at end of file
diff --git a/VkNet.Tests/TestData/Categories/Store/GetFavoriteStickers.json b/VkNet.Tests/TestData/Categories/Store/GetFavoriteStickers.json
new file mode 100644
index 000000000..8db6ff544
--- /dev/null
+++ b/VkNet.Tests/TestData/Categories/Store/GetFavoriteStickers.json
@@ -0,0 +1,17 @@
+{
+ "response": {
+ "count": 2,
+ "items": [
+ {
+ "inner_type": "base_sticker_new",
+ "sticker_id": 126,
+ "is_allowed": true
+ },
+ {
+ "inner_type": "base_sticker_new",
+ "sticker_id": 70,
+ "is_allowed": false
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/VkNet.Tests/TestData/Categories/Store/GetProducts.json b/VkNet.Tests/TestData/Categories/Store/GetProducts.json
new file mode 100644
index 000000000..c51e6aca0
--- /dev/null
+++ b/VkNet.Tests/TestData/Categories/Store/GetProducts.json
@@ -0,0 +1,169 @@
+{
+ "response": {
+ "count": 1,
+ "items": [
+ {
+ "id": 148,
+ "type": "stickers",
+ "is_new": false,
+ "copyright": "ООО «ВКонтакте» 2017",
+ "purchased": 1,
+ "active": 1,
+ "purchase_date": 1704891143,
+ "title": "#ПушкинНашеВсё",
+ "stickers": [
+ {
+ "inner_type": "base_sticker_new",
+ "sticker_id": 4639,
+ "is_allowed": true
+ },
+ {
+ "inner_type": "base_sticker_new",
+ "sticker_id": 4640,
+ "is_allowed": true
+ },
+ {
+ "inner_type": "base_sticker_new",
+ "sticker_id": 4641,
+ "is_allowed": true
+ },
+ {
+ "inner_type": "base_sticker_new",
+ "sticker_id": 4642,
+ "is_allowed": true
+ },
+ {
+ "inner_type": "base_sticker_new",
+ "sticker_id": 4643,
+ "is_allowed": true
+ },
+ {
+ "inner_type": "base_sticker_new",
+ "sticker_id": 4644,
+ "is_allowed": true
+ },
+ {
+ "inner_type": "base_sticker_new",
+ "sticker_id": 4645,
+ "is_allowed": true
+ },
+ {
+ "inner_type": "base_sticker_new",
+ "sticker_id": 4646,
+ "is_allowed": true
+ },
+ {
+ "inner_type": "base_sticker_new",
+ "sticker_id": 4647,
+ "is_allowed": true
+ },
+ {
+ "inner_type": "base_sticker_new",
+ "sticker_id": 4648,
+ "is_allowed": true
+ },
+ {
+ "inner_type": "base_sticker_new",
+ "sticker_id": 4649,
+ "is_allowed": true
+ },
+ {
+ "inner_type": "base_sticker_new",
+ "sticker_id": 4650,
+ "is_allowed": true
+ },
+ {
+ "inner_type": "base_sticker_new",
+ "sticker_id": 4651,
+ "is_allowed": true
+ },
+ {
+ "inner_type": "base_sticker_new",
+ "sticker_id": 4652,
+ "is_allowed": true
+ },
+ {
+ "inner_type": "base_sticker_new",
+ "sticker_id": 4653,
+ "is_allowed": true
+ },
+ {
+ "inner_type": "base_sticker_new",
+ "sticker_id": 4654,
+ "is_allowed": true
+ },
+ {
+ "inner_type": "base_sticker_new",
+ "sticker_id": 4655,
+ "is_allowed": true
+ },
+ {
+ "inner_type": "base_sticker_new",
+ "sticker_id": 4656,
+ "is_allowed": true
+ },
+ {
+ "inner_type": "base_sticker_new",
+ "sticker_id": 4657,
+ "is_allowed": true
+ },
+ {
+ "inner_type": "base_sticker_new",
+ "sticker_id": 4658,
+ "is_allowed": true
+ },
+ {
+ "inner_type": "base_sticker_new",
+ "sticker_id": 4659,
+ "is_allowed": true
+ },
+ {
+ "inner_type": "base_sticker_new",
+ "sticker_id": 4660,
+ "is_allowed": true
+ },
+ {
+ "inner_type": "base_sticker_new",
+ "sticker_id": 4661,
+ "is_allowed": true
+ },
+ {
+ "inner_type": "base_sticker_new",
+ "sticker_id": 4662,
+ "is_allowed": true
+ }
+ ],
+ "icon": {
+ "base_url": "https://vk.com/sticker/packs/148/icon"
+ },
+ "previews": [
+ {
+ "url": "https://vk.com/sticker/2-148-thumb-22-",
+ "width": 22,
+ "height": 22
+ },
+ {
+ "url": "https://vk.com/sticker/2-148-thumb-34-",
+ "width": 34,
+ "height": 34
+ },
+ {
+ "url": "https://vk.com/sticker/2-148-thumb-44-",
+ "width": 44,
+ "height": 44
+ },
+ {
+ "url": "https://vk.com/sticker/2-148-thumb-68-",
+ "width": 68,
+ "height": 68
+ },
+ {
+ "url": "https://vk.com/sticker/2-148-thumb-102-",
+ "width": 102,
+ "height": 102
+ }
+ ]
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/VkNet.Tests/TestData/Categories/Store/GetStickersKeywords.json b/VkNet.Tests/TestData/Categories/Store/GetStickersKeywords.json
new file mode 100644
index 000000000..5415d07b5
--- /dev/null
+++ b/VkNet.Tests/TestData/Categories/Store/GetStickersKeywords.json
@@ -0,0 +1,69 @@
+{
+ "response": {
+ "count": 1,
+ "dictionary": [
+ {
+ "words": [
+ "найс",
+ "найс делаешь",
+ "👍",
+ "класс",
+ "not bad",
+ "неплохо",
+ "не плохо",
+ "клево",
+ "ништяк",
+ "крутота",
+ "крутяк",
+ "волшебно",
+ "эпик",
+ "любо",
+ "отлично",
+ "супер",
+ "лайк",
+ "лойс",
+ "great",
+ "мне нравится",
+ "круто",
+ "круть",
+ "лукас",
+ "четко",
+ "чётко",
+ "четко сработано",
+ "чётко сработано",
+ "классно",
+ "нраица",
+ "шик",
+ "недурно",
+ "кул",
+ "cool",
+ "нот бэд",
+ "все супер",
+ "super",
+ "нравится",
+ "лайкосик",
+ "зачетно",
+ "зачот",
+ "yup",
+ "это лайк",
+ "ну это лайкла",
+ "лайкосики",
+ "стояще",
+ "like",
+ "отличненько",
+ "yosh",
+ "во",
+ "зачёт",
+ "прикольно"
+ ],
+ "user_stickers": [
+ {
+ "inner_type": "base_sticker_new",
+ "sticker_id": 126,
+ "is_allowed": true
+ }
+ ]
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/VkNet.Tests/TestData/Categories/Store/RemoveStickersFromFavorite.json b/VkNet.Tests/TestData/Categories/Store/RemoveStickersFromFavorite.json
new file mode 100644
index 000000000..a318c4360
--- /dev/null
+++ b/VkNet.Tests/TestData/Categories/Store/RemoveStickersFromFavorite.json
@@ -0,0 +1,3 @@
+{
+ "response": 1
+}
\ No newline at end of file
diff --git a/VkNet/Abstractions/Category/Async/IStoreCategoryAsync.cs b/VkNet/Abstractions/Category/Async/IStoreCategoryAsync.cs
new file mode 100644
index 000000000..b0fe941dd
--- /dev/null
+++ b/VkNet/Abstractions/Category/Async/IStoreCategoryAsync.cs
@@ -0,0 +1,72 @@
+using System.Threading;
+using System.Threading.Tasks;
+using VkNet.Model;
+using VkNet.Utils;
+
+namespace VkNet.Abstractions;
+
+///
+/// Методы для работы со стикерами и продуктами
+///
+public interface IStoreCategoryAsync
+{
+ ///
+ /// Добавляет стикер в избранные.
+ ///
+ /// Параметры запроса
+ /// Токен отмены операции.
+ ///
+ /// После успешного выполнения возвращает true.
+ ///
+ ///
+ /// Страница документации ВКонтакте https://dev.vk.com/ru/method/store.addStickersToFavorite
+ ///
+ Task AddStickersToFavoriteAsync(StoreAddStickerToFavoriteParams @params,
+ CancellationToken token = default);
+
+ ///
+ /// Возвращает список избранных стикеров.
+ ///
+ /// Токен отмены операции
+ /// После успешного выполнения возвращает список объектов Sticker
+ ///
+ /// Страница документации ВКонтакте https://dev.vk.com/ru/method/store.getFavoriteStickers
+ ///
+ Task> GetFavoriteStickersAsync(CancellationToken token = default);
+
+ ///
+ /// Возвращает список продуктов.
+ ///
+ /// Параметры запроса
+ /// Токен отмены операции
+ /// После успешного выполнения возвращает список объектов Product
+ ///
+ /// Страница документации ВКонтакте https://dev.vk.com/ru/method/store.getProducts
+ ///
+ Task> GetProductsAsync(StoreGetProductsParams @params,
+ CancellationToken token = default);
+
+ ///
+ /// Возвращает список ключевых слов для стикеров.
+ ///
+ /// Параметры запроса
+ /// Токен отмены операции
+ /// Возвращается объект StickersKeywords
+ ///
+ /// Страница документации ВКонтакте https://dev.vk.com/ru/method/store.getStickersKeywords
+ ///
+ Task GetStickersKeywordsAsync(StoreGetStickersKeywordsParams @params,
+ CancellationToken token = default);
+
+ ///
+ /// Удаляет стикер из избранных.
+ ///
+ /// Параметры запроса
+ /// Токен отмены операции
+ /// После успешного выполнения возвращает true
+ ///
+ /// Страница документации ВКонтакте https://dev.vk.com/ru/method/store.removeStickersFromFavorite
+ ///
+ Task RemoveStickersFromFavoriteAsync(StoreRemoveStickersFromFavoriteParams @params,
+ CancellationToken token = default);
+}
\ No newline at end of file
diff --git a/VkNet/Abstractions/Category/IStoreCategory.cs b/VkNet/Abstractions/Category/IStoreCategory.cs
new file mode 100644
index 000000000..f7b566c87
--- /dev/null
+++ b/VkNet/Abstractions/Category/IStoreCategory.cs
@@ -0,0 +1,25 @@
+using VkNet.Model;
+using VkNet.Utils;
+
+namespace VkNet.Abstractions.Category;
+
+///
+/// Методы для работы со стикерами и продуктами
+///
+public interface IStoreCategory : IStoreCategoryAsync
+{
+ ///
+ bool AddStickersToFavorite(StoreAddStickerToFavoriteParams @params);
+
+ ///
+ VkCollection GetFavoriteStickers();
+
+ ///
+ VkCollection GetProducts(StoreGetProductsParams @params);
+
+ ///
+ StickersKeywords GetStickersKeywords(StoreGetStickersKeywordsParams @params);
+
+ ///
+ bool RemoveStickersFromFavorite(StoreRemoveStickersFromFavoriteParams @params);
+}
\ No newline at end of file
diff --git a/VkNet/Abstractions/Core/IVkApiCategories.cs b/VkNet/Abstractions/Core/IVkApiCategories.cs
index ecbae7761..7f0b0ac3b 100644
--- a/VkNet/Abstractions/Core/IVkApiCategories.cs
+++ b/VkNet/Abstractions/Core/IVkApiCategories.cs
@@ -235,6 +235,11 @@ public interface IVkApiCategories
IShortVideoCategory ShortVideo { get; }
///
+ /// Store
+ ///
+ IStoreCategory Store { get; }
+
+ ///
/// Calls
///
ICallsCategory Calls { get; }
diff --git a/VkNet/Categories/Async/StoreCategoryAsync.cs b/VkNet/Categories/Async/StoreCategoryAsync.cs
new file mode 100644
index 000000000..ee524ffa1
--- /dev/null
+++ b/VkNet/Categories/Async/StoreCategoryAsync.cs
@@ -0,0 +1,45 @@
+using System.Threading;
+using System.Threading.Tasks;
+using VkNet.Abstractions;
+using VkNet.Abstractions.Category;
+using VkNet.Model;
+using VkNet.Utils;
+
+namespace VkNet.Categories;
+
+///
+public partial class StoreCategory
+{
+ private readonly IVkApiInvoke _vk;
+
+ ///
+ /// Инициализирует новый экземпляр класса
+ ///
+ public StoreCategory(IVkApiInvoke vk) => _vk = vk;
+
+ ///
+ public Task AddStickersToFavoriteAsync(StoreAddStickerToFavoriteParams @params,
+ CancellationToken token = default) =>
+ TypeHelper.TryInvokeMethodAsync(() =>
+ AddStickersToFavorite(@params), token);
+
+ ///
+ public Task> GetFavoriteStickersAsync(CancellationToken token = default) =>
+ TypeHelper.TryInvokeMethodAsync(
+ GetFavoriteStickers, token);
+
+ ///
+ public Task> GetProductsAsync(StoreGetProductsParams @params, CancellationToken token = default) =>
+ TypeHelper.TryInvokeMethodAsync(() =>
+ GetProducts(@params), token);
+
+ ///
+ public Task GetStickersKeywordsAsync(StoreGetStickersKeywordsParams @params, CancellationToken token = default) =>
+ TypeHelper.TryInvokeMethodAsync(() =>
+ GetStickersKeywords(@params), token);
+
+ ///
+ public Task RemoveStickersFromFavoriteAsync(StoreRemoveStickersFromFavoriteParams @params, CancellationToken token = default) =>
+ TypeHelper.TryInvokeMethodAsync(() =>
+ RemoveStickersFromFavorite(@params), token);
+}
\ No newline at end of file
diff --git a/VkNet/Categories/StoreCategory.cs b/VkNet/Categories/StoreCategory.cs
new file mode 100644
index 000000000..ca7af41d8
--- /dev/null
+++ b/VkNet/Categories/StoreCategory.cs
@@ -0,0 +1,73 @@
+using VkNet.Abstractions.Category;
+using VkNet.Model;
+using VkNet.Utils;
+
+namespace VkNet.Categories;
+
+///
+public partial class StoreCategory : IStoreCategory
+{
+ ///
+ public bool AddStickersToFavorite(StoreAddStickerToFavoriteParams @params) =>
+ _vk.Call("store.addStickersToFavorite", new()
+ {
+ {
+ "sticker_ids", @params.StickerIds
+ }
+ });
+
+ ///
+ public VkCollection GetFavoriteStickers() =>
+ _vk.Call>("store.getFavoriteStickers", new());
+
+ ///
+ public VkCollection GetProducts(StoreGetProductsParams @params) =>
+ _vk.Call>("store.getProducts", new()
+ {
+ {
+ "type", @params.Type
+ },
+ {
+ "merchant", @params.Merchant
+ },
+ {
+ "product_ids", @params.ProductIds
+ },
+ {
+ "filters", @params.Filters
+ },
+ {
+ "extended", @params.Extended
+ }
+ });
+
+ ///
+ public StickersKeywords GetStickersKeywords(StoreGetStickersKeywordsParams @params) =>
+ _vk.Call("store.getStickersKeywords", new()
+ {
+ {
+ "stickers_ids", @params.StickerIds
+ },
+ {
+ "products_ids", @params.ProductIds
+ },
+ {
+ "aliases", @params.Aliases
+ },
+ {
+ "all_products", @params.AllProducts
+ },
+ {
+ "need_stickers", @params.NeedStickers
+ }
+ });
+
+ ///
+ public bool RemoveStickersFromFavorite(StoreRemoveStickersFromFavoriteParams @params) =>
+ _vk.Call("store.removeStickersFromFavorite", new()
+ {
+ {
+ "sticker_ids", @params.StickerIds
+ }
+ });
+}
\ No newline at end of file
diff --git a/VkNet/Enums/StringEnums/Merchant.cs b/VkNet/Enums/StringEnums/Merchant.cs
new file mode 100644
index 000000000..577c99907
--- /dev/null
+++ b/VkNet/Enums/StringEnums/Merchant.cs
@@ -0,0 +1,27 @@
+using Newtonsoft.Json;
+using VkNet.Utils.JsonConverter;
+
+namespace VkNet.Enums.StringEnums;
+
+///
+/// Магазин
+///
+[StringEnum]
+[JsonConverter(typeof(TolerantStringEnumConverter))]
+public enum Merchant
+{
+ ///
+ /// Google
+ ///
+ Google,
+
+ ///
+ /// Apple
+ ///
+ Apple,
+
+ ///
+ /// Microsoft
+ ///
+ Microsoft
+}
\ No newline at end of file
diff --git a/VkNet/Enums/StringEnums/ProductStatusFilter.cs b/VkNet/Enums/StringEnums/ProductStatusFilter.cs
new file mode 100644
index 000000000..45cc72f57
--- /dev/null
+++ b/VkNet/Enums/StringEnums/ProductStatusFilter.cs
@@ -0,0 +1,27 @@
+using Newtonsoft.Json;
+using VkNet.Utils.JsonConverter;
+
+namespace VkNet.Enums.StringEnums;
+
+///
+/// Фильтр статуса продуктов
+///
+[StringEnum]
+[JsonConverter(typeof(TolerantStringEnumConverter))]
+public enum ProductStatusFilter
+{
+ ///
+ /// Купленные
+ ///
+ Purchased,
+
+ ///
+ /// Активные
+ ///
+ Active,
+
+ ///
+ /// Рекламные
+ ///
+ Promoted
+}
\ No newline at end of file
diff --git a/VkNet/Enums/StringEnums/ProductType.cs b/VkNet/Enums/StringEnums/ProductType.cs
new file mode 100644
index 000000000..cbe4cfc17
--- /dev/null
+++ b/VkNet/Enums/StringEnums/ProductType.cs
@@ -0,0 +1,24 @@
+
+
+using Newtonsoft.Json;
+using VkNet.Utils.JsonConverter;
+
+namespace VkNet.Enums.StringEnums;
+
+///
+/// Тип продуктов
+///
+[StringEnum]
+[JsonConverter(typeof(TolerantStringEnumConverter))]
+public enum ProductType
+{
+ ///
+ /// Стикеры
+ ///
+ Stickers,
+
+ ///
+ /// Голоса
+ ///
+ Votes
+}
\ No newline at end of file
diff --git a/VkNet/Model/Attachments/Sticker.cs b/VkNet/Model/Attachments/Sticker.cs
index 362ac5de6..40c9db6ed 100644
--- a/VkNet/Model/Attachments/Sticker.cs
+++ b/VkNet/Model/Attachments/Sticker.cs
@@ -37,4 +37,23 @@ private long? StickerId
get => Id;
set => Id = value;
}
+
+ ///
+ /// URL анимации стикера (для анимированных стикеров)
+ ///
+ [JsonProperty("animation_url")]
+ public bool AnimationUrl { get; set; }
+
+ ///
+ /// Тип, который описывает вариант формата ответа.
+ ///
+ /// По умолчанию: "base_sticker_new"
+ [JsonProperty("inner_type")]
+ public string InnerType { get; set; }
+
+ ///
+ /// Информация о том, доступен ли стикер
+ ///
+ [JsonProperty("is_allowed")]
+ public bool IsAllowed { get; set; }
}
\ No newline at end of file
diff --git a/VkNet/Model/Hint.cs b/VkNet/Model/Hint.cs
new file mode 100644
index 000000000..c0811d897
--- /dev/null
+++ b/VkNet/Model/Hint.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using Newtonsoft.Json;
+
+namespace VkNet.Model;
+
+///
+/// Подсказки
+///
+[Serializable]
+public class Hint
+{
+ ///
+ /// Коллекция строк, содержащих слова и (или) Emoji соответствующие стикерам из поля UserStickers
+ ///
+ [JsonProperty("words")]
+ public List Words { get; set; }
+
+ ///
+ /// Стикеры, которые установлены у пользователя
+ ///
+ [JsonProperty("user_stickers")]
+ public List UserStickers { get; set; }
+
+ ///
+ /// Cтикеры, которым соответствуют ключевые слова words, но наборы с ними у пользователя не установлены
+ ///
+ [JsonProperty("promoted_stickers")]
+ public List PromotedStickers { get; set; }
+}
\ No newline at end of file
diff --git a/VkNet/Model/Icon.cs b/VkNet/Model/Icon.cs
new file mode 100644
index 000000000..6d992b83b
--- /dev/null
+++ b/VkNet/Model/Icon.cs
@@ -0,0 +1,17 @@
+using System;
+using Newtonsoft.Json;
+
+namespace VkNet.Model;
+
+///
+/// Иконка
+///
+[Serializable]
+public class Icon
+{
+ ///
+ /// URL иконки
+ ///
+ [JsonProperty("base_url")]
+ public string BaseUrl { get; set; }
+}
\ No newline at end of file
diff --git a/VkNet/Model/Product.cs b/VkNet/Model/Product.cs
new file mode 100644
index 000000000..9bab02506
--- /dev/null
+++ b/VkNet/Model/Product.cs
@@ -0,0 +1,89 @@
+using System;
+using System.Collections.Generic;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Converters;
+using VkNet.Enums.StringEnums;
+using VkNet.Utils.JsonConverter;
+
+namespace VkNet.Model;
+
+///
+/// Продукт
+///
+[Serializable]
+public class Product
+{
+ ///
+ /// Идентификатор продукта
+ ///
+ [JsonProperty("id")]
+ public long Id { get; set; }
+
+ ///
+ /// Тип продукта
+ ///
+ [JsonProperty("type")]
+ [JsonConverter(typeof(TolerantStringEnumConverter))]
+ public ProductType Type { get; set; }
+
+ ///
+ /// Является ли продукт новым
+ ///
+ [JsonProperty("is_new")]
+ public bool IsNew { get; set; }
+
+ ///
+ /// Копирайт
+ ///
+ [JsonProperty("copyright")]
+ public string Copyright { get; set; }
+
+ ///
+ /// Куплен ли продукт
+ ///
+ [JsonProperty("purchased")]
+ public bool Purchased { get; set; }
+
+ ///
+ /// Активен ли продукт
+ ///
+ [JsonProperty("active")]
+ public bool Active { get; set; }
+
+ ///
+ /// Является ли продукт рекламным
+ ///
+ [JsonProperty("promoted ")]
+ public bool Promoted { get; set; }
+
+ ///
+ /// Дата покупки
+ ///
+ [JsonProperty("purchase_date")]
+ [JsonConverter(converterType: typeof(UnixDateTimeConverter))]
+ public DateTime? PurchaseDate { get; set; }
+
+ ///
+ /// Название продукта
+ ///
+ [JsonProperty("title")]
+ public string Title { get; set; }
+
+ ///
+ /// Стикеры
+ ///
+ [JsonProperty("stickers")]
+ public List Stickers { get; set; }
+
+ ///
+ /// Иконка продукта
+ ///
+ [JsonProperty("icon")]
+ public Icon Icon { get; set; }
+
+ ///
+ /// Превью
+ ///
+ [JsonProperty("previews")]
+ public List Previews { get; set; }
+}
\ No newline at end of file
diff --git a/VkNet/Model/RequestParams/Store/StoreAddStickerToFavoriteParams.cs b/VkNet/Model/RequestParams/Store/StoreAddStickerToFavoriteParams.cs
new file mode 100644
index 000000000..b39b0fc4b
--- /dev/null
+++ b/VkNet/Model/RequestParams/Store/StoreAddStickerToFavoriteParams.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+
+namespace VkNet.Model;
+
+///
+/// Список параметров для метода store.addStickersToFavorite
+///
+[Serializable]
+public class StoreAddStickerToFavoriteParams
+{
+ ///
+ /// Идентификаторы стикеров
+ ///
+ public List StickerIds { get; set; }
+}
\ No newline at end of file
diff --git a/VkNet/Model/RequestParams/Store/StoreGetProductsParams.cs b/VkNet/Model/RequestParams/Store/StoreGetProductsParams.cs
new file mode 100644
index 000000000..5dd1ebb64
--- /dev/null
+++ b/VkNet/Model/RequestParams/Store/StoreGetProductsParams.cs
@@ -0,0 +1,38 @@
+using System.Collections.Generic;
+using VkNet.Enums.StringEnums;
+
+namespace VkNet.Model;
+
+///
+/// Параметры получения списка продуктов
+///
+public class StoreGetProductsParams
+{
+ ///
+ /// Тип продуктов
+ ///
+ /// Обязательный параметр, если не используется параметр ProductIds.
+ public ProductType Type { get; set; }
+
+ ///
+ /// Магазин
+ ///
+ public Merchant? Merchant { get; set; }
+
+ ///
+ /// Идентификаторы продуктов, информацию о которых необходимо получить.
+ ///
+ /// Если используется этот параметр, параметр Type является обязательным.
+ public List ProductIds { get; set; }
+
+ ///
+ /// Определяет статусы, по которым необходимо отфильтровать продукты
+ ///
+ /// Является обязательным, если не используется параметр ProductIds.
+ public List Filters { get; set; }
+
+ ///
+ /// Нужна ли расширенная информация о продуктах
+ ///
+ public bool Extended { get; set; }
+}
\ No newline at end of file
diff --git a/VkNet/Model/RequestParams/Store/StoreGetStickersKeywordsParams.cs b/VkNet/Model/RequestParams/Store/StoreGetStickersKeywordsParams.cs
new file mode 100644
index 000000000..755fbf3de
--- /dev/null
+++ b/VkNet/Model/RequestParams/Store/StoreGetStickersKeywordsParams.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+
+namespace VkNet.Model;
+
+///
+/// Список параметров для метода store.getStickersKeywords
+///
+[Serializable]
+public class StoreGetStickersKeywordsParams
+{
+ ///
+ /// Идентификаторы стикеров
+ ///
+ public List StickerIds { get; set; }
+
+ ///
+ /// Идентификаторы продуктов
+ ///
+ public List ProductIds { get; set; }
+
+ ///
+ /// Если true, то будет возвращены синонимы для каждого из ключевых слов
+ ///
+ public bool Aliases { get; set; }
+
+ ///
+ /// Если true, то будет возвращена информация о всех активных продуктах на сайтах с учётом страны
+ ///
+ public bool AllProducts { get; set; }
+
+ ///
+ /// Если true, то будут возвращены стикеры вместе с подсказками.
+ ///
+ public bool NeedStickers { get; set; }
+}
\ No newline at end of file
diff --git a/VkNet/Model/RequestParams/Store/StoreRemoveStickersFromFavoriteParams.cs b/VkNet/Model/RequestParams/Store/StoreRemoveStickersFromFavoriteParams.cs
new file mode 100644
index 000000000..46b084fbc
--- /dev/null
+++ b/VkNet/Model/RequestParams/Store/StoreRemoveStickersFromFavoriteParams.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+
+namespace VkNet.Model;
+
+///
+/// Список параметров для метода store.removeStickersFromFavorite
+///
+[Serializable]
+public class StoreRemoveStickersFromFavoriteParams
+{
+ ///
+ /// Идентификаторы стикеров
+ ///
+ public List StickerIds { get; set; }
+}
\ No newline at end of file
diff --git a/VkNet/Model/StickersKeywords.cs b/VkNet/Model/StickersKeywords.cs
new file mode 100644
index 000000000..a32c729dc
--- /dev/null
+++ b/VkNet/Model/StickersKeywords.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using Newtonsoft.Json;
+
+namespace VkNet.Model;
+
+///
+/// Ключевые слова
+///
+[Serializable]
+public class StickersKeywords
+{
+ ///
+ /// базовый URL для стикеров
+ ///
+ [JsonProperty("base_url")]
+ public string BaseUrl { get; set; }
+
+ ///
+ /// Количество объектов
+ ///
+ [JsonProperty("count")]
+ public int Count { get; set; }
+
+ ///
+ /// Коллекция объектов, описывающих подсказки
+ ///
+ [JsonProperty("dictionary")]
+ public List Dictionary { get; set; }
+}
\ No newline at end of file
diff --git a/VkNet/VkApi.cs b/VkNet/VkApi.cs
index 5c441b5aa..fc3195f3b 100644
--- a/VkNet/VkApi.cs
+++ b/VkNet/VkApi.cs
@@ -791,6 +791,9 @@ public int MaxCaptchaRecognitionCount
///
public IShortVideoCategory ShortVideo { get; set; }
+ ///
+ public IStoreCategory Store { get; set; }
+
///
public ICallsCategory Calls { get; set; }
@@ -1087,6 +1090,7 @@ private void Initialization(IServiceProvider serviceProvider)
DownloadedGames = new DownloadedGamesCategory(this);
Asr = new AsrCategory(this);
ShortVideo = new ShortVideoCategory(this);
+ Store = new StoreCategory(this);
Calls = new CallsCategory(this);
RequestsPerSecond = 3;