Home / Blog

O Guia Completo de Desenvolvimento de Plugins para nopCommerce

Carlos Casalicchio · June 23, 2026 ·7 min de leitura

Por que os plugins do nopCommerce importam

O nopCommerce alimenta mais de 60.000 lojas online no mundo todo. É a principal plataforma de e-commerce open-source em .NET — e sua arquitetura de plugins é o motor por trás desse ecossistema. Toda integração de gateway de pagamento, toda transportadora, todo widget e toda funcionalidade personalizada vive como um plugin.

Se você entende como construir plugins para o nopCommerce, pode estender uma das plataformas de e-commerce mais capazes do mercado — e construir um negócio a partir disso. Este guia cobre tudo, desde o seu primeiro esqueleto de plugin até padrões de implantação em produção.

Construímos plugins para o nopCommerce desde 2009, com mais de 38 plugins em nosso catálogo — incluindo 12 integrações de gateways de pagamento brasileiros e a única solução completa de pagamento PIX na plataforma. Este guia reflete o que aprendemos construindo plugins que processam milhões de transações.

Arquitetura de plugins: a fundação

A hierarquia de interfaces de plugin

Todo plugin do nopCommerce começa com a interface IPlugin em Nop.Services.Plugins. Em vez de fazer você implementar tudo do zero, o nopCommerce fornece a BasePlugin — uma classe abstrata que cuida do código repetitivo — e um conjunto de interfaces especializadas para tipos comuns de plugin:

Interface Finalidade Exemplo
IPaymentMethod Processamento de pagamentos (autorizar, capturar, estornar, cancelar) PayPal, Stripe, PIX, MercadoPago
IShippingRateComputationMethod Calcular fretes a partir das transportadoras UPS, FedEx, Correios (Brasil)
ITaxProvider Calcular alíquotas de imposto por jurisdição Avalara, TaxJar
IWidgetPlugin Renderizar widgets de UI em zonas específicas Chat ao vivo, popup de newsletter, cards do Trello
IExchangeRateProvider Obter taxas de câmbio de moedas BCE, Banco Central do Brasil
IDiscountRequirementRule Lógica de desconto personalizada "Cliente do Brasil ganha 10% de desconto"
IExternalAuthenticationMethod Login social e SSO Google, Facebook, Azure AD
IMultiFactorAuthenticationMethod Plugins de MFA (desde a 4.40) Google Authenticator, SMS OTP
IPickupPointProvider Locais de retirada na loja Rede de lojas locais, sistemas de armários
IMiscPlugin Extensões de propósito geral Gestão de DNS, analytics, integrações

Escolha a interface mais específica para o seu caso de uso. A IPaymentMethod dá a você o ciclo de vida completo do pagamento — ProcessPaymentAsync, PostProcessPaymentAsync, RefundAsync, VoidAsync, CaptureAsync — enquanto a IMiscPlugin é a saída de emergência para qualquer coisa que não se encaixe em uma categoria padrão.

Estrutura do projeto: passo a passo

1. Crie o projeto de biblioteca de classes

Crie um novo projeto Class Library tendo como alvo o .NET 9. A convenção de nomenclatura recomendada é Nop.Plugin.{Group}.{Name}:

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

Coloque o projeto no diretório \Plugins na raiz da solução (não dentro de \Nop.Web\Plugins, que é o destino de implantação). Defina o caminho de saída do .csproj como $(SolutionDir)\Presentation\Nop.Web\Plugins\{PluginOutputDirectory} e habilite CopyLocalLockFileAssemblies para garantir que as dependências NuGet sejam copiadas para a saída.

2. Crie o plugin.json

Todo plugin requer um arquivo plugin.json com metadados:

{
  "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"
}

O SystemName deve coincidir com o nome do seu assembly. SupportedVersions determina quais versões do nopCommerce podem instalar o plugin. Se você atualizar o nopCommerce e um plugin quebrar, verifique este campo primeiro — muitos plugins só precisam ter suas versões suportadas atualizadas.

3. Implemente a classe do plugin

Crie uma classe que implemente a interface de plugin apropriada e derive de 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);
    }
}

As sobrescritas de InstallAsync, UninstallAsync e UpdateAsync são seus ganchos de ciclo de vida. Sempre chame a implementação base — base.InstallAsync() cuida do registro no sistema de plugins.

4. Adicione a configuração (UI do admin)

Para plugins com configurações, crie um controller MVC, um model e uma view Razor:

  1. Controllers/{Name}Controller.cs — decorado com [AuthorizeAdmin] e [Area(AreaNames.ADMIN)]. Herde de BasePluginController.
  2. Models/ConfigurationModel.cs — uma classe simples com as propriedades das suas configurações e atributos [NopResourceDisplayName] para localização.
  3. Views/Configure.cshtml — usa o layout _ConfigurePlugin. Inclua também o _ViewImports.cshtml (copie de um plugin existente).

Registre a rota de configuração em um RouteProvider.cs implementando 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;
}

Construindo um plugin de pagamento: o padrão do mundo real

Plugins de pagamento são o tipo mais comum — e mais complexo. Aqui está o padrão de produção que usamos na SplatDev:

Componentes centrais

  1. Classe de configurações (Settings): Uma classe implementando ISettings com propriedades para chaves de API, URLs, modos (sandbox/produção) e alternadores de funcionalidades. Armazene segredos no ISettingService — nunca embuta credenciais no código.
  2. Classe de defaults: Uma classe estática com constantes — nomes de rotas, system name, URLs de configuração, endpoints de API. Mantém strings mágicas fora da sua lógica.
  3. Classe de serviço: Sua lógica de integração propriamente dita — chamadas HTTP ao gateway de pagamento, parsing de respostas, tratamento de webhooks. Injete via DI e mantenha testável (interface + implementação).
  4. Consumidores de eventos (event consumers): Implemente IConsumer<OrderPlacedEvent> e interfaces similares para reagir a eventos da loja — enviar confirmações de transação, disparar fluxos pós-pagamento.

Fluxo de pagamento: os métodos que você deve implementar

Método Quando é chamado O que deve fazer
ProcessPaymentAsync Cliente clica em "Pagar" Autorizar ou capturar o pagamento. Retornar sucesso/falha e o ID da transação.
PostProcessPaymentAsync Após a conclusão do processamento do pagamento Redirecionar para o gateway externo (PayPal, PagSeguro) ou mostrar uma página de confirmação.
RefundAsync Admin inicia um estorno Processar o estorno através do gateway. Retornar sucesso/falha.
VoidAsync Admin cancela uma autorização Cancelar a autorização pendente. Aplicável apenas se o pagamento ainda não foi capturado.
CaptureAsync Admin captura um pagamento autorizado Capturar um valor previamente autorizado. Comum em fluxos de autorização-e-captura.
GetPaymentMethodDescriptionAsync Renderização da página de checkout Retornar o nome de exibição, a descrição e o logo do método de pagamento.
GetAdditionalHandlingFeeAsync Cálculo do total do pedido Retornar qualquer taxa adicional cobrada pelo método de pagamento, ou zero.

Exemplo de plugin de pagamento brasileiro: PIX

O sistema de pagamento instantâneo PIX do Brasil requer um fluxo específico: gerar um QR code com um payload (string EMV), exibi-lo ao cliente e aguardar uma confirmação via webhook quando o pagamento for recebido. Aqui está o padrão:

  1. ProcessPaymentAsync: Chame o PSP (PagSeguro, MercadoPago, etc.) para criar uma cobrança PIX. Armazene o ID da transação (txid) e o payload EMV.
  2. PostProcessPaymentAsync: Renderize o QR code (gerado a partir do payload EMV) e o código "copia e cola". Defina o status do pagamento como Pending.
  3. Tratador de webhook: O PSP envia um webhook quando o PIX confirma o pagamento. Atualize o status do pedido e dispare o OrderPaidEvent.

Este é o padrão por trás de todos os 12 plugins de pagamento brasileiros da SplatDev — processando PIX, boleto e pagamentos parcelados com cartão de crédito através de PagSeguro, MercadoPago, Cielo, Banco Inter, Pagar.me, Rede, GetNet, PicPay, NuPay, Braspag e InfinityPay.

Widgets: adicionando UI sem tocar nos temas

Plugins de widget implementam IWidgetPlugin e devem especificar em quais zonas de widget eles são renderizados:

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

Em seguida, implemente GetPublicViewComponentAsync para retornar o HTML do widget. O sistema de widgets chama esse método para cada zona que você registrou.

Padrões comuns de widget: popups de cadastro em newsletter, botões de chat ao vivo, selos de confiança, banners de consentimento de cookies, botões flutuantes de WhatsApp, produtos vistos recentemente e notificações de prova social.

Acesso ao banco de dados: IRepository<T> e migrations

O nopCommerce usa um padrão de repositório via IRepository<T> para acesso a dados. Para plugins que precisam de tabelas personalizadas:

  1. Defina sua classe de entidade (deve ter uma propriedade Id).
  2. Crie um ObjectContext que registre sua entidade no Entity Framework Core.
  3. No InstallAsync, use _dbContext.InstallAsync() para criar as tabelas.
  4. No UninstallAsync, use _dbContext.UninstallAsync() para removê-las.

Para migrations de schema entre versões do plugin, considere adicionar um MigrationManager à sua sobrescrita de UpdateAsync que verifica a versão atual do schema e aplica as instruções ALTER TABLE necessárias. Isso é mais simples que o FluentMigrator para plugins e mantém sua lógica de migração em um só lugar.

Testes: trate seu plugin como um produto

Na SplatDev, tratamos cada plugin como um produto com sua própria suíte de testes:

  • Testes unitários (xUnit): Teste sua camada de serviço de forma isolada. Faça mock de ISettingService, IRepository<T> e de quaisquer clientes HTTP. Sua lógica de pagamento, cálculos de impostos e cálculos de frete devem ter 100% de cobertura de testes unitários na lógica de negócio.
  • Testes de integração: Suba uma instância de teste do nopCommerce e verifique se o seu plugin instala, configura e processa ao longo de todo o ciclo de vida. Use credenciais de sandbox/teste para os gateways de pagamento.
  • Testes de localização: Verifique se todos os recursos de idioma existem para cada idioma que você afirma suportar. Strings de recurso ausentes são o bug de plugin mais comum.
  • Conformidade com StyleCop: O nopCommerce espera conformidade com o StyleCop. Execute-o no seu pipeline de CI — ele captura problemas sutis antes do code review.

Armadilhas comuns (e como evitá-las)

1. Não chamar base.InstallAsync()

Se você sobrescrever InstallAsync sem chamar a base, seu plugin não se registrará no sistema de plugins e não aparecerá no admin. Sempre inclua await base.InstallAsync() ao final da sua sobrescrita.

2. Embutir credenciais no código

Armazene chaves de API, tokens e segredos no ISettingService — nunca os embuta no plugin.json ou como constantes de classe. A página de configurações deve permitir que os administradores configurem esses valores, e eles devem ser persistidos de forma criptografada quando apropriado.

3. Ignorar a compatibilidade de versão

As versões do nopCommerce quebram plugins. O campo SupportedVersions no plugin.json não é decorativo — o nopCommerce o verifica antes de carregar seu plugin. Ao atualizar o nopCommerce, teste seu plugin contra a nova versão e atualize esse campo. Não apenas incremente o número sem testar.

4. Bloquear a thread da requisição

Todos os métodos de plugin são assíncronos por um motivo. Se o seu processador de pagamento chama uma API externa, essa chamada deve ser assíncrona. Bloquear a thread com .Result ou .Wait() vai degradar o desempenho sob carga e pode causar deadlocks.

5. Nenhum consumidor de eventos

Plugins que só fornecem uma página de configuração estão perdendo o ponto. O verdadeiro poder dos plugins do nopCommerce vem dos consumidores de eventos — reagindo a eventos da loja como OrderPlacedEvent, CustomerRegisteredEvent ou ShipmentDeliveredEvent. Conecte seu plugin aos eventos de negócio da loja, não apenas à UI do admin.

nopCommerce 4.90: o que há de novo para desenvolvedores de plugins

O nopCommerce 4.90 tem como alvo o .NET 9 e traz várias melhorias para desenvolvedores de plugins:

  • Runtime do .NET 9: Seus plugins rodam no .NET mais rápido até hoje — beneficiando-se automaticamente de melhorias no JIT, adaptação dinâmica do GC e otimizações de laços.
  • Suporte a C# 13: Use coleções params, interfaces ref struct e propriedades parciais no código do seu plugin.
  • Dependências NuGet atualizadas: Pacotes subjacentes (Autofac, FluentValidation, etc.) foram atualizados. Teste a árvore de dependências do seu plugin.
  • IMultiFactorAuthenticationMethod: Plugins de MFA agora são um conceito de primeira classe, com sua própria interface.
  • Template de plugin aprimorado: O template oficial de plugin do nopCommerce para o Visual Studio foi atualizado para a 4.90 — use-o como seu ponto de partida.

Para onde ir a partir daqui

O desenvolvimento de plugins para o nopCommerce é uma habilidade que constrói carreira. O marketplace do nopCommerce é ativo e crescente, e plugins bem construídos geram receita recorrente através de atualizações e suporte. Na SplatDev, plugins são nosso negócio principal — nossa Loja em store.splatdev.com tem mais de 38 plugins, e somos Gold Solutions Partner há anos.

Se você está construindo um projeto de e-commerce em nopCommerce, não precisa construir tudo do zero. Nosso catálogo cobre pagamentos brasileiros, frete (Correios, JadLog, Braspress), integrações com ERP e funcionalidades personalizadas. Se você precisa de algo que não temos, também construímos plugins sob medida.

Pronto para construir ou estender sua loja nopCommerce? Nossa equipe faz isso desde 2009 — há mais tempo que quase todo mundo no ecossistema.

Trabalhe com nossa equipe nopCommerce

Ou navegue pelo nosso catálogo de plugins: store.splatdev.com

Want more articles like this?

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

Get in touch →