Ekom.Mailchimp 1.2.2

dotnet add package Ekom.Mailchimp --version 1.2.2
                    
NuGet\Install-Package Ekom.Mailchimp -Version 1.2.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Ekom.Mailchimp" Version="1.2.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Ekom.Mailchimp" Version="1.2.2" />
                    
Directory.Packages.props
<PackageReference Include="Ekom.Mailchimp" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Ekom.Mailchimp --version 1.2.2
                    
#r "nuget: Ekom.Mailchimp, 1.2.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Ekom.Mailchimp@1.2.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Ekom.Mailchimp&version=1.2.2
                    
Install as a Cake Addin
#tool nuget:?package=Ekom.Mailchimp&version=1.2.2
                    
Install as a Cake Tool

Ekom.Mailchimp

Mailchimp Marketing API integration for Ekom. The first release supports audience subscriptions, unsubscriptions, and completed-purchase conversion tracking.

Ekom.Mailchimp supports Umbraco 17 on .NET 10 and reusable integration services on .NET 8. Use Ekom.Mailchimp.U18 for Umbraco 18.

Configuration

{
  "Ekom": {
    "Mailchimp": {
      "Enabled": true,
      "ApiKey": "your-api-key-us1",
      "AudienceId": "audience-id",
      "EcommerceStoreId": "stable-mailchimp-store-id",
      "SiteBaseUrl": "https://www.example.com",
      "Stores": [
        {
          "Alias": "iceland",
          "ApiKey": "iceland-api-key-us1",
          "AudienceId": "iceland-audience-id",
          "EcommerceStoreId": "iceland-mailchimp-store-id",
          "SiteBaseUrl": "https://www.example.is"
        },
        {
          "Alias": "united-kingdom",
          "ApiKey": "united-kingdom-api-key",
          "ServerPrefix": "us2",
          "AudienceId": "united-kingdom-audience-id",
          "EcommerceStoreId": "united-kingdom-mailchimp-store-id",
          "SiteBaseUrl": "https://www.example.co.uk"
        }
      ],
      "Purchases": {
        "Enabled": true,
        "TrackCompletedCheckouts": true
      }
    }
  }
}

Stores is an array of per-store overrides. Each Alias is matched against the Ekom store alias case-insensitively. A store can override ApiKey, ServerPrefix, AudienceId, EcommerceStoreId, and SiteBaseUrl; omitted values fall back to the corresponding global value. Global credentials can be omitted when every store supplies its complete configuration.

Global and store-level values can be mixed. For example, each store can provide its own API key while sharing global audience and e-commerce store IDs. A root ApiKey is not required when every used store provides one:

{
  "Ekom": {
    "Mailchimp": {
      "Enabled": true,
      "AudienceId": "shared-audience-id",
      "EcommerceStoreId": "shared-mailchimp-store-id",
      "Stores": [
        {
          "Alias": "HVerslun",
          "ApiKey": "store-specific-key-us21"
        }
      ]
    }
  }
}

ServerPrefix is inferred from the suffix of a standard Mailchimp API key, such as us1 in your-api-key-us1. Set it explicitly when the API key does not contain the server prefix.

Use the standard ASP.NET Core configuration key format for environment variables and secrets. Array entries use zero-based indexes; for example, Ekom__Mailchimp__Stores__0__ApiKey sets the API key for the first configured store.

Missing operational values do not prevent the application from starting. Each missing setting is logged once for the affected store, and work for that store is ignored before it reaches the queue. Configured stores are checked during startup; missing global fallback values for an unlisted alias are logged when that alias is first used. Stores are evaluated independently, and a missing EcommerceStoreId disables purchase tracking without disabling subscriptions. Invalid dispatcher settings remain startup errors. Duplicate or blank store aliases are also startup errors when Mailchimp and at least one feature are enabled.

Register the integration during application startup. The options are read from Ekom:Mailchimp.

using Ekom.Mailchimp;

builder.Services.AddMailchimp();

Options can also be configured or overridden in code:

using Ekom.Mailchimp;

builder.Services.AddMailchimp(options =>
{
    options.Enabled = true;
    options.ApiKey = "your-api-key-us1";
    options.AudienceId = "audience-id";
    options.EcommerceStoreId = "stable-mailchimp-store-id";
    options.SiteBaseUrl = new Uri("https://www.example.com");
    options.Purchases.TrackCompletedCheckouts = true;
});

The Umbraco package automatically registers the completed-checkout event component. Calling AddMailchimp is still required.

Usage

Inject the service

IMailchimpService is the public entry point for subscriptions and purchases.

using Ekom.Mailchimp.Services;

public sealed class CustomerMarketingService(IMailchimpService mailchimp)
{
    private readonly IMailchimpService _mailchimp = mailchimp;
}

Subscribe a contact

Subscription calls require an explicit Pending or Subscribed status. Use Pending for double opt-in workflows, and only use Subscribed when the contact has already provided the required consent.

using Ekom.Mailchimp.Models;

await _mailchimp.SubscribeAsync(new MailchimpSubscribeRequest
{
    StoreAlias = "default",
    Email = "person@example.com",
    Status = MailchimpSubscriptionStatus.Pending,
    FirstName = "Example",
    LastName = "Customer",
    Language = "en",
    MergeFields = new Dictionary<string, object?>
    {
        ["COMPANY"] = "Example Ltd.",
    },
    Tags = ["customer", "web-signup"],
}, cancellationToken);

Unsubscribe a contact

using Ekom.Mailchimp.Models;

await _mailchimp.UnsubscribeAsync(new MailchimpUnsubscribeRequest
{
    StoreAlias = "default",
    Email = "person@example.com",
}, cancellationToken);

Track an Ekom order

Pass an IOrderInfo to use the standard Ekom-to-Mailchimp mapping. The mapper includes the customer, addresses, order totals, and product lines.

using Ekom.Models;

public ValueTask TrackOrderAsync(IOrderInfo order, CancellationToken cancellationToken)
    => _mailchimp.TrackPurchaseAsync(order, cancellationToken);

The standard mapping reads marketing consent from customerMailchimpConsentToSubscribe, the Mailchimp campaign ID from mc_cid, and the tracking code from mc_tc. Relative product and image URLs use the configured SiteBaseUrl.

Track a purchase directly

Use MailchimpPurchase when the purchase does not originate from an Ekom order or when the complete payload is already available.

using Ekom.Mailchimp.Models;

await _mailchimp.TrackPurchaseAsync(new MailchimpPurchase
{
    StoreAlias = "default",
    StoreName = "Example Store",
    OrderId = "order-123",
    OrderNumber = "123",
    CurrencyCode = "USD",
    OrderTotal = 49.90m,
    ProcessedAt = DateTimeOffset.UtcNow,
    Customer = new MailchimpPurchaseCustomer
    {
        Id = "customer-123",
        Email = "person@example.com",
        FirstName = "Example",
        LastName = "Customer",
        MarketingOptIn = true,
    },
    Lines =
    [
        new MailchimpPurchaseLine
        {
            Id = "line-123",
            ProductId = "product-123",
            ProductVariantId = "variant-123",
            ProductTitle = "Example product",
            VariantTitle = "Default",
            Sku = "SKU-123",
            Quantity = 1,
            Price = 49.90m,
            ProductUrl = new Uri("https://www.example.com/products/example"),
        },
    ],
}, cancellationToken);

Purchase, customer, line, product, and variant IDs must be non-empty and no longer than 50 characters. Currency codes must be three-letter ISO 4217 codes, such as USD; line quantities must be positive integers, and the only supported tracking code is prec.

Map and customize an Ekom order

ToMailchimpPurchase exposes the standard order mapper when a mapped purchase needs to be inspected or changed before submission.

using Ekom.Mailchimp;
using Ekom.Mailchimp.Mappers;
using Ekom.Mailchimp.Models;
using Ekom.Models;
using Microsoft.Extensions.Options;

public async ValueTask TrackCustomizedOrderAsync(
    IOrderInfo order,
    IOptions<MailchimpOptions> options,
    CancellationToken cancellationToken)
{
    MailchimpPurchase purchase = order.ToMailchimpPurchase(options.Value) with
    {
        FulfillmentStatus = "pending",
    };

    await _mailchimp.TrackPurchaseAsync(purchase, cancellationToken);
}

Enrich every purchase

Implement IMailchimpPurchaseEnricher to apply reusable changes to purchases created through either TrackPurchaseAsync overload.

using Ekom.Mailchimp.Enrichers;
using Ekom.Mailchimp.Models;

public sealed class FulfillmentStatusEnricher : IMailchimpPurchaseEnricher
{
    public ValueTask<MailchimpPurchase> EnrichAsync(
        MailchimpPurchase purchase,
        CancellationToken cancellationToken = default)
    {
        MailchimpPurchase enriched = purchase with
        {
            FulfillmentStatus = purchase.FulfillmentStatus ?? "pending",
        };

        return ValueTask.FromResult(enriched);
    }
}

Register enrichers with dependency injection. Multiple enrichers run sequentially in their registration order before validation and queueing.

using Ekom.Mailchimp;
using Ekom.Mailchimp.Enrichers;

builder.Services.AddMailchimp();
builder.Services.AddScoped<IMailchimpPurchaseEnricher, FulfillmentStatusEnricher>();

Automatic checkout tracking

Automatic tracking requires Enabled, Purchases:Enabled, and Purchases:TrackCompletedCheckouts to be true. Product and variant records referenced by the order are upserted before the order. Replaying an order with the same IDs is safe because purchase tracking uses idempotent Mailchimp commerce upserts.

Queueing and failures

Service calls perform immediate guard and configuration checks before queueing; purchase payloads are also validated before queueing. They do not wait for Mailchimp to process the operation, so remote API failures occur asynchronously. The dispatcher uses a bounded in-memory queue and retries transient HTTP and network failures. When the queue is full, new work is dropped with a warning rather than blocking checkout. Remote failures are logged, including details from MailchimpApiException. Work still queued during process shutdown is not durable; call the relevant service method again to replay the operation safely.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.2.2 0 9/14/2026
1.2.1 35 9/14/2026
1.2.0 32 9/14/2026
1.1.0 34 9/14/2026
1.0.0 32 9/14/2026