Home / Blog

Der komplette Leitfaden zur nopCommerce-Plugin-Entwicklung

Carlos Casalicchio · June 23, 2026 ·7 Min. Lesezeit

Warum nopCommerce-Plugins wichtig sind

nopCommerce betreibt weltweit über 60,000 Online-Shops. Es ist die führende Open-Source-E-Commerce-Plattform auf .NET — und seine Plugin-Architektur ist der Motor hinter diesem Ökosystem. Jede Zahlungs-Gateway-Integration, jeder Versanddienstleister, jedes Widget und jede individuelle Funktion existiert als Plugin.

Wenn Sie verstehen, wie man nopCommerce-Plugins erstellt, können Sie eine der leistungsfähigsten E-Commerce-Plattformen auf dem Markt erweitern — und daraus ein Geschäft machen. Dieser Leitfaden deckt alles ab, vom ersten Plugin-Grundgerüst bis zu Mustern für das Produktiv-Deployment.

Wir entwickeln nopCommerce-Plugins seit 2009 und haben über 38 Plugins in unserem Katalog — darunter 12 brasilianische Zahlungs-Gateway-Integrationen und die einzige vollständige PIX-Zahlungslösung auf der Plattform. Dieser Leitfaden spiegelt wider, was wir beim Entwickeln von Plugins gelernt haben, die Millionen von Transaktionen verarbeiten.

Plugin-Architektur: Das Fundament

Die Hierarchie der Plugin-Interfaces

Jedes nopCommerce-Plugin beginnt mit dem IPlugin-Interface in Nop.Services.Plugins. Anstatt alles von Grund auf selbst implementieren zu müssen, stellt nopCommerce BasePlugin bereit — eine abstrakte Klasse, die den Boilerplate-Code übernimmt — sowie eine Reihe spezialisierter Interfaces für gängige Plugin-Typen:

Interface Zweck Beispiel
IPaymentMethod Zahlungsabwicklung (Autorisierung, Erfassung, Rückerstattung, Stornierung) PayPal, Stripe, PIX, MercadoPago
IShippingRateComputationMethod Versandkosten von Zustellern berechnen UPS, FedEx, Correios (Brasilien)
ITaxProvider Steuersätze nach Rechtsraum berechnen Avalara, TaxJar
IWidgetPlugin UI-Widgets in bestimmten Zonen rendern Live-Chat, Newsletter-Popup, Trello-Karten
IExchangeRateProvider Währungswechselkurse abrufen EZB, Zentralbank von Brasilien
IDiscountRequirementRule Individuelle Rabattlogik «Kunde aus Brasilien erhält 10% Rabatt»
IExternalAuthenticationMethod Social Login und SSO Google, Facebook, Azure AD
IMultiFactorAuthenticationMethod MFA-Plugins (seit 4.40) Google Authenticator, SMS OTP
IPickupPointProvider Abholstandorte im Geschäft Lokales Filialnetz, Schliessfachsysteme
IMiscPlugin Universelle Erweiterungen DNS-Verwaltung, Analytics, Integrationen

Wählen Sie das spezifischste Interface für Ihren Anwendungsfall. IPaymentMethod gibt Ihnen den vollständigen Zahlungs-Lebenszyklus — ProcessPaymentAsync, PostProcessPaymentAsync, RefundAsync, VoidAsync, CaptureAsync — während IMiscPlugin die Notlösung für alles ist, was nicht in eine Standardkategorie passt.

Projektstruktur: Schritt für Schritt

1. Das Klassenbibliothek-Projekt erstellen

Erstellen Sie ein neues Class Library-Projekt für .NET 9. Die empfohlene Namenskonvention lautet Nop.Plugin.{Group}.{Name}:

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

Platzieren Sie das Projekt im Verzeichnis \Plugins im Solution-Root (nicht in \Nop.Web\Plugins, das das Deployment-Ziel ist). Setzen Sie den Ausgabepfad der .csproj auf $(SolutionDir)\Presentation\Nop.Web\Plugins\{PluginOutputDirectory} und aktivieren Sie CopyLocalLockFileAssemblies, damit die NuGet-Abhängigkeiten in die Ausgabe kopiert werden.

2. plugin.json erstellen

Jedes Plugin benötigt eine plugin.json-Datei mit Metadaten:

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

Der SystemName muss mit Ihrem Assembly-Namen übereinstimmen. SupportedVersions bestimmt, welche nopCommerce-Versionen das Plugin installieren können. Wenn Sie nopCommerce aktualisieren und ein Plugin nicht mehr funktioniert, prüfen Sie zuerst dieses Feld — bei vielen Plugins müssen lediglich die unterstützten Versionen aktualisiert werden.

3. Die Plugin-Klasse implementieren

Erstellen Sie eine Klasse, die das passende Plugin-Interface implementiert und von BasePlugin ableitet:

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);
    }
}

Die Overrides InstallAsync, UninstallAsync und UpdateAsync sind Ihre Lifecycle-Hooks. Rufen Sie immer die Basis-Implementierung auf — base.InstallAsync() übernimmt die Registrierung im Plugin-System.

4. Konfiguration hinzufügen (Admin-UI)

Erstellen Sie für Plugins mit Einstellungen einen MVC-Controller, ein Model und eine Razor-View:

  1. Controllers/{Name}Controller.cs — dekoriert mit [AuthorizeAdmin] und [Area(AreaNames.ADMIN)]. Von BasePluginController ableiten.
  2. Models/ConfigurationModel.cs — eine einfache Klasse mit Ihren Einstellungs-Properties und [NopResourceDisplayName]-Attributen für die Lokalisierung.
  3. Views/Configure.cshtml — verwendet das Layout _ConfigurePlugin. Fügen Sie ausserdem _ViewImports.cshtml hinzu (von einem bestehenden Plugin kopieren).

Registrieren Sie die Konfigurations-Route in einer RouteProvider.cs, die IRouteProvider implementiert:

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;
}

Ein Zahlungs-Plugin erstellen: Das Praxismuster

Zahlungs-Plugins sind der häufigste — und komplexeste — Plugin-Typ. Hier ist das Produktivmuster, das wir bei SplatDev verwenden:

Kernkomponenten

  1. Settings-Klasse: Eine Klasse, die ISettings implementiert, mit Properties für API-Schlüssel, URLs, Modi (Sandbox/Produktion) und Feature-Toggles. Speichern Sie Geheimnisse in ISettingService — codieren Sie Zugangsdaten niemals fest ein.
  2. Defaults-Klasse: Eine statische Klasse mit Konstanten — Routennamen, Systemname, Konfigurations-URLs, API-Endpunkte. Hält Magic Strings aus Ihrer Logik heraus.
  3. Service-Klasse: Ihre eigentliche Integrationslogik — HTTP-Aufrufe an das Payment-Gateway, Parsen von Antworten, Webhook-Verarbeitung. Per DI injizieren und testbar halten (Interface + Implementierung).
  4. Event-Consumer: Implementieren Sie IConsumer<OrderPlacedEvent> und ähnliche Interfaces, um auf Shop-Ereignisse zu reagieren — Transaktionsbestätigungen versenden, Workflows nach der Zahlung auslösen.

Zahlungsablauf: Die Methoden, die Sie implementieren müssen

Methode Wann aufgerufen Was sie tun soll
ProcessPaymentAsync Kunde klickt auf «Bezahlen» Zahlung autorisieren oder erfassen. Erfolg/Fehler und Transaktions-ID zurückgeben.
PostProcessPaymentAsync Nach Abschluss der Zahlungsabwicklung Zum externen Gateway (PayPal, PagSeguro) weiterleiten oder eine Bestätigungsseite anzeigen.
RefundAsync Admin leitet Rückerstattung ein Die Rückerstattung über das Gateway abwickeln. Erfolg/Fehler zurückgeben.
VoidAsync Admin storniert eine Autorisierung Die ausstehende Autorisierung stornieren. Nur zutreffend, wenn die Zahlung noch nicht erfasst wurde.
CaptureAsync Admin erfasst eine autorisierte Zahlung Einen zuvor autorisierten Betrag erfassen. Üblich bei Abläufen mit Autorisierung und anschliessender Erfassung.
GetPaymentMethodDescriptionAsync Checkout-Seite wird gerendert Anzeigenamen, Beschreibung und Logo für die Zahlungsmethode zurückgeben.
GetAdditionalHandlingFeeAsync Berechnung der Bestellsumme Eine allfällige zusätzliche Gebühr der Zahlungsmethode zurückgeben oder null.

Beispiel für ein brasilianisches Zahlungs-Plugin: PIX

Das brasilianische PIX-Echtzeitzahlungssystem erfordert einen bestimmten Ablauf: einen QR-Code mit einem Payload (EMV-String) generieren, ihn dem Kunden anzeigen und auf eine Webhook-Bestätigung warten, wenn die Zahlung eingegangen ist. Hier ist das Muster:

  1. ProcessPaymentAsync: Rufen Sie den PSP (PagSeguro, MercadoPago usw.) auf, um eine PIX-Zahlung zu erstellen. Speichern Sie die Transaktions-ID (txid) und den EMV-Payload.
  2. PostProcessPaymentAsync: Rendern Sie den QR-Code (aus dem EMV-Payload generiert) und den «Copy-Paste»-Code. Setzen Sie den Zahlungsstatus auf Pending.
  3. Webhook-Handler: Der PSP sendet einen Webhook, wenn PIX die Zahlung bestätigt. Aktualisieren Sie den Bestellstatus und lösen Sie OrderPaidEvent aus.

Das ist das Muster hinter allen 12 brasilianischen Zahlungs-Plugins von SplatDev — sie verarbeiten PIX, boleto und Kreditkartenzahlungen in Raten über PagSeguro, MercadoPago, Cielo, Banco Inter, Pagar.me, Rede, GetNet, PicPay, NuPay, Braspag und InfinityPay.

Widgets: UI hinzufügen, ohne Themes anzufassen

Widget-Plugins implementieren IWidgetPlugin und müssen angeben, in welchen Widget-Zonen sie gerendert werden:

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

Implementieren Sie anschliessend GetPublicViewComponentAsync, um das HTML des Widgets zurückzugeben. Das Widget-System ruft diese Methode für jede von Ihnen registrierte Zone auf.

Gängige Widget-Muster: Newsletter-Anmelde-Popups, Live-Chat-Buttons, Trust-Badges, Cookie-Consent-Banner, schwebende WhatsApp-Buttons, zuletzt angesehene Produkte und Social-Proof-Benachrichtigungen.

Datenbankzugriff: IRepository<T> und Migrationen

nopCommerce verwendet für den Datenzugriff ein Repository-Muster über IRepository<T>. Für Plugins, die eigene Tabellen benötigen:

  1. Definieren Sie Ihre Entity-Klasse (muss eine Id-Property haben).
  2. Erstellen Sie einen ObjectContext, der Ihre Entity bei Entity Framework Core registriert.
  3. Verwenden Sie in InstallAsync die Methode _dbContext.InstallAsync(), um die Tabellen zu erstellen.
  4. Verwenden Sie in UninstallAsync die Methode _dbContext.UninstallAsync(), um sie zu löschen.

Für Schema-Migrationen zwischen Plugin-Versionen sollten Sie in Ihrem UpdateAsync-Override einen MigrationManager hinzufügen, der die aktuelle Schema-Version prüft und die notwendigen ALTER-TABLE-Anweisungen anwendet. Das ist für Plugins einfacher als FluentMigrator und hält Ihre Migrationslogik an einem Ort.

Testing: Behandeln Sie Ihr Plugin wie ein Produkt

Bei SplatDev behandeln wir jedes Plugin als Produkt mit eigener Test-Suite:

  • Unit-Tests (xUnit): Testen Sie Ihre Service-Schicht isoliert. Mocken Sie ISettingService, IRepository<T> und sämtliche HTTP-Clients. Ihre Zahlungslogik, Steuerberechnungen und Versandkostenberechnungen sollten für die Geschäftslogik eine Unit-Test-Abdeckung von 100% haben.
  • Integrationstests: Starten Sie eine Test-nopCommerce-Instanz und überprüfen Sie, dass sich Ihr Plugin über den gesamten Lebenszyklus hinweg installiert, konfiguriert und verarbeitet. Verwenden Sie Sandbox-/Test-Zugangsdaten für Payment-Gateways.
  • Lokalisierungstests: Überprüfen Sie, dass alle Locale-Ressourcen für jede Sprache vorhanden sind, die Sie zu unterstützen angeben. Fehlende Ressourcen-Strings sind der häufigste Plugin-Fehler.
  • StyleCop-Konformität: nopCommerce erwartet StyleCop-Konformität. Führen Sie es in Ihrer CI-Pipeline aus — es findet subtile Probleme vor dem Code-Review.

Häufige Fallstricke (und wie man sie vermeidet)

1. base.InstallAsync() nicht aufrufen

Wenn Sie InstallAsync überschreiben, ohne die Basis aufzurufen, registriert sich Ihr Plugin nicht im Plugin-System und erscheint nicht im Admin-Bereich. Fügen Sie immer await base.InstallAsync() am Ende Ihres Overrides ein.

2. Zugangsdaten fest einprogrammieren

Speichern Sie API-Schlüssel, Tokens und Geheimnisse in ISettingService — codieren Sie sie niemals fest in plugin.json oder als Klassenkonstanten ein. Die Einstellungsseite sollte es Admins ermöglichen, diese Werte zu konfigurieren, und sie sollten bei Bedarf verschlüsselt gespeichert werden.

3. Versionskompatibilität ignorieren

nopCommerce-Versionen machen Plugins unbrauchbar. Das Feld SupportedVersions in plugin.json ist nicht bloss Dekoration — nopCommerce prüft es, bevor es Ihr Plugin lädt. Testen Sie Ihr Plugin beim Aktualisieren von nopCommerce gegen die neue Version und aktualisieren Sie dieses Feld. Erhöhen Sie die Nummer nicht einfach ohne Test.

4. Den Request-Thread blockieren

Alle Plugin-Methoden sind aus gutem Grund asynchron. Wenn Ihr Payment-Processor eine externe API aufruft, sollte dieser Aufruf asynchron sein. Das Blockieren des Threads mit .Result oder .Wait() verschlechtert die Performance unter Last und kann zu Deadlocks führen.

5. Keine Event-Consumer

Plugins, die nur eine Konfigurationsseite bereitstellen, verfehlen den Kern. Die eigentliche Stärke von nopCommerce-Plugins kommt von Event-Consumern — der Reaktion auf Shop-Ereignisse wie OrderPlacedEvent, CustomerRegisteredEvent oder ShipmentDeliveredEvent. Binden Sie Ihr Plugin in die Geschäftsereignisse des Shops ein, nicht nur in die Admin-UI.

nopCommerce 4.90: Was für Plugin-Entwickler neu ist

nopCommerce 4.90 zielt auf .NET 9 ab und bringt mehrere Verbesserungen für Plugin-Entwickler:

  • .NET 9-Runtime: Ihre Plugins laufen auf dem bislang schnellsten .NET — und profitieren automatisch von JIT-Verbesserungen, dynamischer GC-Anpassung und Schleifenoptimierungen.
  • C# 13-Unterstützung: Verwenden Sie params-Collections, ref struct-Interfaces und partielle Properties in Ihrem Plugin-Code.
  • Aktualisierte NuGet-Abhängigkeiten: Die zugrunde liegenden Pakete (Autofac, FluentValidation usw.) wurden aktualisiert. Testen Sie den Abhängigkeitsbaum Ihres Plugins.
  • IMultiFactorAuthenticationMethod: MFA-Plugins sind nun ein vollwertiges Konzept mit eigenem Interface.
  • Verbessertes Plugin-Template: Das offizielle nopCommerce-Plugin-Template für Visual Studio wurde für 4.90 aktualisiert — verwenden Sie es als Ausgangspunkt.

Wie es weitergeht

Die Entwicklung von nopCommerce-Plugins ist eine karrierefördernde Fähigkeit. Der nopCommerce-Marktplatz ist aktiv und wächst, und gut gebaute Plugins erzeugen über Updates und Support wiederkehrende Einnahmen. Bei SplatDev sind Plugins unser Kerngeschäft — unser Store unter store.splatdev.com umfasst über 38 Plugins, und wir sind seit Jahren Gold Solutions Partner.

Wenn Sie ein E-Commerce-Projekt auf nopCommerce aufbauen, müssen Sie nicht alles von Grund auf entwickeln. Unser Katalog deckt brasilianische Zahlungen, Versand (Correios, JadLog, Braspress), ERP-Integrationen und individuelle Funktionen ab. Wenn Sie etwas benötigen, das wir nicht haben, entwickeln wir auch massgeschneiderte Plugins.

Bereit, Ihren nopCommerce-Shop aufzubauen oder zu erweitern? Unser Team macht das seit 2009 — länger als fast alle anderen im Ökosystem.

Arbeiten Sie mit unserem nopCommerce-Team

Oder durchstöbern Sie unseren Plugin-Katalog: store.splatdev.com

Want more articles like this?

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

Get in touch →