Home / Blog

Полное руководство по разработке плагинов для nopCommerce

Carlos Casalicchio · June 23, 2026 ·7 мин чтения

Почему плагины nopCommerce важны

На nopCommerce работает более 60 000 интернет-магазинов по всему миру. Это ведущая e-commerce-платформа с открытым исходным кодом на .NET, и её архитектура плагинов — движок, стоящий за всей этой экосистемой. Каждая интеграция платёжного шлюза, каждый перевозчик, каждый виджет и каждая пользовательская функция существуют в виде плагина.

Если вы понимаете, как создавать плагины для nopCommerce, вы можете расширять одну из самых мощных e-commerce-платформ на рынке — и построить на этом бизнес. Это руководство охватывает всё: от вашего первого каркаса плагина до промышленных паттернов развёртывания.

Мы создаём плагины для nopCommerce с 2009 года, и в нашем каталоге более 38 плагинов — включая 12 интеграций бразильских платёжных шлюзов и единственное на платформе полноценное решение для платежей PIX. Это руководство отражает всё, что мы усвоили, создавая плагины, обрабатывающие миллионы транзакций.

Архитектура плагина: фундамент

Иерархия интерфейсов плагина

Каждый плагин nopCommerce начинается с интерфейса IPlugin в Nop.Services.Plugins. Вместо того чтобы заставлять вас реализовывать всё с нуля, nopCommerce предоставляет BasePlugin — абстрактный класс, который берёт на себя шаблонный код, — и набор специализированных интерфейсов для распространённых типов плагинов:

Интерфейс Назначение Пример
IPaymentMethod Обработка платежей (авторизация, списание, возврат, отмена) PayPal, Stripe, PIX, MercadoPago
IShippingRateComputationMethod Расчёт стоимости доставки от перевозчиков UPS, FedEx, Correios (Бразилия)
ITaxProvider Расчёт налоговых ставок по юрисдикциям Avalara, TaxJar
IWidgetPlugin Отрисовка UI-виджетов в определённых зонах Онлайн-чат, всплывающее окно подписки, карточки Trello
IExchangeRateProvider Получение курсов валют ЕЦБ, Центральный банк Бразилии
IDiscountRequirementRule Пользовательская логика скидок «Клиент из Бразилии получает скидку 10%»
IExternalAuthenticationMethod Вход через соцсети и SSO Google, Facebook, Azure AD
IMultiFactorAuthenticationMethod Плагины MFA (начиная с 4.40) Google Authenticator, SMS OTP
IPickupPointProvider Пункты самовывоза в магазинах Сеть локальных магазинов, системы постаматов
IMiscPlugin Расширения общего назначения Управление DNS, аналитика, интеграции

Выбирайте наиболее конкретный интерфейс под ваш сценарий. IPaymentMethod даёт вам полный жизненный цикл платежа — ProcessPaymentAsync, PostProcessPaymentAsync, RefundAsync, VoidAsync, CaptureAsync — тогда как IMiscPlugin служит запасным вариантом для всего, что не вписывается в стандартную категорию.

Структура проекта: шаг за шагом

1. Создайте проект библиотеки классов

Создайте новый проект Class Library, нацеленный на .NET 9. Рекомендуемое соглашение об именовании — Nop.Plugin.{Group}.{Name}:

Nop.Plugin.Payments.PayPalCommerce
Nop.Plugin.Shipping.FedEx
Nop.Plugin.Widgets.WhatsApp
Nop.Plugin.Misc.GoDaddy

Разместите проект в каталоге \Plugins в корне решения (а не внутри \Nop.Web\Plugins, который является целевым каталогом развёртывания). Задайте в .csproj путь вывода $(SolutionDir)\Presentation\Nop.Web\Plugins\{PluginOutputDirectory} и включите CopyLocalLockFileAssemblies, чтобы зависимости NuGet копировались в выходной каталог.

2. Создайте plugin.json

Каждому плагину требуется файл plugin.json с метаданными:

{
  "Group": "Payment methods",
  "FriendlyName": "My Payment Gateway",
  "SystemName": "Payments.MyGateway",
  "Version": "1.00",
  "SupportedVersions": [ "4.90" ],
  "Author": "SplatDev",
  "DisplayOrder": 1,
  "FileName": "Nop.Plugin.Payments.MyGateway.dll",
  "Description": "Process payments via My Gateway"
}

Значение SystemName должно совпадать с именем вашей сборки. Поле SupportedVersions определяет, в каких версиях nopCommerce можно установить плагин. Если вы обновляете nopCommerce и плагин перестаёт работать, проверьте это поле в первую очередь — многим плагинам достаточно лишь обновить список поддерживаемых версий.

3. Реализуйте класс плагина

Создайте класс, который реализует подходящий интерфейс плагина и наследуется от BasePlugin:

public class MyPaymentProcessor : BasePlugin, IPaymentMethod
{
    public override Task InstallAsync()
    {
        // Insert settings, locale resources, or database tables
        return base.InstallAsync();
    }

    public override Task UninstallAsync()
    {
        // Clean up settings, locale resources, or database tables
        return base.UninstallAsync();
    }

    public override Task UpdateAsync(string currentVersion, string targetVersion)
    {
        // Handle version migrations
        return base.UpdateAsync(currentVersion, targetVersion);
    }

    public Task<ProcessPaymentResult> ProcessPaymentAsync(ProcessPaymentRequest request)
    {
        // Your payment logic here
    }

    public override string GetConfigurationPageUrl()
    {
        return _nopUrlHelper.RouteUrl(MyDefaults.Route.Configuration);
    }
}

Переопределения InstallAsync, UninstallAsync и UpdateAsync — это ваши хуки жизненного цикла. Всегда вызывайте базовую реализацию — base.InstallAsync() отвечает за регистрацию в системе плагинов.

4. Добавьте конфигурацию (админ-интерфейс)

Для плагинов с настройками создайте MVC-контроллер, модель и представление Razor:

  1. Controllers/{Name}Controller.cs — снабжённый атрибутами [AuthorizeAdmin] и [Area(AreaNames.ADMIN)]. Наследуйте от BasePluginController.
  2. Models/ConfigurationModel.cs — обычный класс со свойствами ваших настроек и атрибутами [NopResourceDisplayName] для локализации.
  3. Views/Configure.cshtml — использует макет _ConfigurePlugin. Также включите _ViewImports.cshtml (скопируйте из существующего плагина).

Зарегистрируйте маршрут конфигурации в RouteProvider.cs, реализующем IRouteProvider:

public class RouteProvider : IRouteProvider
{
    public void RegisterRoutes(IEndpointRouteBuilder endpointRouteBuilder)
    {
        endpointRouteBuilder.MapControllerRoute(
            name: MyDefaults.Route.Configuration,
            pattern: "Admin/MyGateway/Configure",
            defaults: new { controller = "MyGateway", action = "Configure", area = AreaNames.ADMIN });
    }

    public int Priority => 0;
}

Создание платёжного плагина: паттерн из реальной практики

Платёжные плагины — самый распространённый и самый сложный тип плагинов. Вот промышленный паттерн, который мы используем в SplatDev:

Основные компоненты

  1. Класс настроек: класс, реализующий ISettings, со свойствами для API-ключей, URL, режимов (песочница/боевой) и переключателей функций. Храните секреты в ISettingService — никогда не зашивайте учётные данные в код.
  2. Класс Defaults: статический класс с константами — именами маршрутов, системным именем, URL конфигурации, эндпоинтами API. Убирает «магические строки» из вашей логики.
  3. Класс сервиса: собственно логика интеграции — HTTP-вызовы к платёжному шлюзу, разбор ответов, обработка вебхуков. Внедряйте через DI и делайте тестируемым (интерфейс + реализация).
  4. Потребители событий: реализуйте IConsumer<OrderPlacedEvent> и аналогичные интерфейсы, чтобы реагировать на события магазина — отправлять подтверждения транзакций, запускать процессы после оплаты.

Поток платежа: методы, которые вы обязаны реализовать

Метод Когда вызывается Что должен делать
ProcessPaymentAsync Клиент нажимает «Оплатить» Авторизовать или списать платёж. Вернуть успех/неудачу и идентификатор транзакции.
PostProcessPaymentAsync После завершения обработки платежа Перенаправить на внешний шлюз (PayPal, PagSeguro) или показать страницу подтверждения.
RefundAsync Администратор инициирует возврат Провести возврат через шлюз. Вернуть успех/неудачу.
VoidAsync Администратор отменяет авторизацию Отменить ожидающую авторизацию. Применимо, только если платёж ещё не был списан.
CaptureAsync Администратор списывает авторизованный платёж Списать ранее авторизованную сумму. Обычно применяется в схемах «авторизация, затем списание».
GetPaymentMethodDescriptionAsync Отрисовка страницы оформления заказа Вернуть отображаемое имя, описание и логотип метода оплаты.
GetAdditionalHandlingFeeAsync Расчёт итоговой суммы заказа Вернуть любую дополнительную комиссию метода оплаты либо ноль.

Пример бразильского платёжного плагина: PIX

Бразильская система мгновенных платежей PIX требует особого потока: сгенерировать QR-код с полезной нагрузкой (строкой EMV), показать его клиенту и ожидать подтверждения через вебхук при получении платежа. Вот паттерн:

  1. ProcessPaymentAsync: вызовите PSP (PagSeguro, MercadoPago и т. д.), чтобы создать платёж PIX. Сохраните идентификатор транзакции (txid) и полезную нагрузку EMV.
  2. PostProcessPaymentAsync: отрисуйте QR-код (сгенерированный из полезной нагрузки EMV) и код для копирования-вставки. Установите статус платежа Pending.
  3. Обработчик вебхука: PSP отправляет вебхук, когда PIX подтверждает платёж. Обновите статус заказа и запустите OrderPaidEvent.

Именно этот паттерн лежит в основе всех 12 бразильских платёжных плагинов SplatDev — обрабатывающих PIX, boleto и платежи по кредитным картам в рассрочку через PagSeguro, MercadoPago, Cielo, Banco Inter, Pagar.me, Rede, GetNet, PicPay, NuPay, Braspag и InfinityPay.

Виджеты: добавление UI без вмешательства в темы

Плагины-виджеты реализуют IWidgetPlugin и должны указывать, в каких зонах виджетов они отрисовываются:

public Task<IList<string>> GetWidgetZonesAsync()
{
    return Task.FromResult<IList<string>>(new List<string>
    {
        PublicWidgetZones.HomepageBeforeBestSellers,
        PublicWidgetZones.ProductDetailsAfterPictures
    });
}

Затем реализуйте GetPublicViewComponentAsync, чтобы вернуть HTML виджета. Система виджетов вызывает этот метод для каждой зарегистрированной вами зоны.

Распространённые паттерны виджетов: всплывающие окна подписки на рассылку, кнопки онлайн-чата, значки доверия, баннеры согласия на использование cookie, плавающие кнопки WhatsApp, недавно просмотренные товары и уведомления социального доказательства.

Доступ к базе данных: IRepository<T> и миграции

nopCommerce использует паттерн репозитория через IRepository<T> для доступа к данным. Для плагинов, которым нужны собственные таблицы:

  1. Определите класс сущности (у него должно быть свойство Id).
  2. Создайте ObjectContext, который регистрирует вашу сущность в Entity Framework Core.
  3. В InstallAsync используйте _dbContext.InstallAsync(), чтобы создать таблицы.
  4. В UninstallAsync используйте _dbContext.UninstallAsync(), чтобы удалить их.

Для миграций схемы между версиями плагина рассмотрите добавление MigrationManager в переопределение UpdateAsync, который проверяет текущую версию схемы и применяет необходимые операторы ALTER TABLE. Это проще, чем FluentMigrator для плагинов, и держит логику миграций в одном месте.

Тестирование: относитесь к плагину как к продукту

В SplatDev мы относимся к каждому плагину как к продукту с собственным набором тестов:

  • Модульные тесты (xUnit): тестируйте слой сервисов в изоляции. Мокайте ISettingService, IRepository<T> и любые HTTP-клиенты. Ваша платёжная логика, расчёты налогов и вычисления стоимости доставки должны иметь 100% покрытие бизнес-логики модульными тестами.
  • Интеграционные тесты: поднимите тестовый экземпляр nopCommerce и убедитесь, что ваш плагин устанавливается, настраивается и проходит весь жизненный цикл. Используйте тестовые учётные данные (песочницу) для платёжных шлюзов.
  • Тесты локализации: проверьте, что все ресурсы локализации существуют для каждого языка, который вы заявляете как поддерживаемый. Отсутствующие строки ресурсов — самая распространённая ошибка плагинов.
  • Соответствие StyleCop: nopCommerce ожидает соответствия StyleCop. Запускайте его в конвейере CI — он ловит тонкие проблемы ещё до код-ревью.

Типичные ошибки (и как их избежать)

1. Не вызван base.InstallAsync()

Если вы переопределяете InstallAsync без вызова базовой реализации, ваш плагин не зарегистрируется в системе плагинов и не появится в админке. Всегда включайте await base.InstallAsync() в конце вашего переопределения.

2. Учётные данные, зашитые в код

Храните API-ключи, токены и секреты в ISettingService — никогда не зашивайте их в plugin.json или в константы класса. Страница настроек должна позволять администраторам задавать эти значения, и при необходимости они должны сохраняться в зашифрованном виде.

3. Игнорирование совместимости версий

Версии nopCommerce ломают плагины. Поле SupportedVersions в plugin.json — не декорация: nopCommerce проверяет его перед загрузкой вашего плагина. При обновлении nopCommerce протестируйте плагин против новой версии и обновите это поле. Не увеличивайте номер просто так, без тестирования.

4. Блокировка потока запроса

Все методы плагина асинхронны неспроста. Если ваш платёжный процессор вызывает внешний API, этот вызов должен быть асинхронным. Блокировка потока через .Result или .Wait() снизит производительность под нагрузкой и может привести к взаимоблокировкам.

5. Отсутствие потребителей событий

Плагины, которые предоставляют только страницу конфигурации, упускают суть. Настоящая сила плагинов nopCommerce — в потребителях событий, реагирующих на события магазина, такие как OrderPlacedEvent, CustomerRegisteredEvent или ShipmentDeliveredEvent. Встраивайте плагин в бизнес-события магазина, а не только в админ-интерфейс.

nopCommerce 4.90: что нового для разработчиков плагинов

nopCommerce 4.90 нацелен на .NET 9 и приносит несколько улучшений для разработчиков плагинов:

  • Среда выполнения .NET 9: ваши плагины работают на самой быстрой на сегодня версии .NET — автоматически выигрывая от улучшений JIT, динамической адаптации GC и оптимизаций циклов.
  • Поддержка C# 13: используйте коллекции params, интерфейсы для ref struct и частичные свойства в коде своих плагинов.
  • Обновлённые зависимости NuGet: базовые пакеты (Autofac, FluentValidation и др.) были обновлены. Протестируйте дерево зависимостей вашего плагина.
  • IMultiFactorAuthenticationMethod: плагины MFA теперь являются полноценной концепцией с собственным интерфейсом.
  • Улучшенный шаблон плагина: официальный шаблон плагина nopCommerce для Visual Studio обновлён под 4.90 — используйте его как отправную точку.

Куда двигаться дальше

Разработка плагинов nopCommerce — это навык, строящий карьеру. Маркетплейс nopCommerce активен и растёт, а качественно сделанные плагины приносят регулярный доход за счёт обновлений и поддержки. В SplatDev плагины — наш основной бизнес: наш магазин на store.splatdev.com насчитывает более 38 плагинов, и мы уже много лет являемся Gold Solutions Partner.

Если вы создаёте e-commerce-проект на nopCommerce, вам не нужно строить всё с нуля. Наш каталог охватывает бразильские платежи, доставку (Correios, JadLog, Braspress), интеграции с ERP и пользовательскую функциональность. Если вам нужно что-то, чего у нас нет, мы создаём и заказные плагины.

Готовы создать или расширить свой магазин на nopCommerce? Наша команда занимается этим с 2009 года — дольше почти кого-либо в экосистеме.

Работать с нашей командой nopCommerce

Или посмотрите наш каталог плагинов: store.splatdev.com

Want more articles like this?

Subscribe for updates on .NET, Umbraco, nopCommerce, and software engineering.

Get in touch →