npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

medusa-plugin-ecomail

v1.1.0

Published

Ecomail integration plugin for Medusa v2 - email marketing and transaction tracking

Readme

medusa-plugin-ecomail

Ecomail integration plugin for Medusa v2 - email marketing and transaction tracking.

Features

  • 📧 Subscriber Management - Add, update, and manage Ecomail subscribers
  • 🛒 E-commerce Tracking - Automatically track order transactions in Ecomail
  • 🎯 Smart Subscription - Intelligent handling of new subscribers, updates, and resubscriptions
  • 🎨 Admin UI - Built-in admin panel for testing and managing subscribers
  • 🔄 Auto-sync - Automatic synchronization of customer data with Ecomail lists

Compatibility

This plugin is compatible with Medusa v2 (>= 2.11.2).

Installation

npm install medusa-plugin-ecomail
# or
yarn add medusa-plugin-ecomail

Configuration

Basic Configuration (Default Mode)

Add the plugin to your medusa-config.ts:

import { defineConfig } from '@medusajs/framework/utils'

export default defineConfig({
  plugins: [
    {
      resolve: 'medusa-plugin-ecomail',
      options: {
        ecomailListId: process.env.ECOMAIL_LIST_ID,
        ecomailToken: process.env.ECOMAIL_TOKEN,
        shopDomain: process.env.SHOP_DOMAIN, // optional
      },
    },
  ],
})

Default Behavior: All customers are automatically synced to Ecomail when they place an order.

GDPR-Compliant Configuration

For GDPR compliance, enable explicit consent requirement:

import { defineConfig } from '@medusajs/framework/utils'

export default defineConfig({
  plugins: [
    {
      resolve: 'medusa-plugin-ecomail',
      options: {
        ecomailListId: process.env.ECOMAIL_LIST_ID,
        ecomailToken: process.env.ECOMAIL_TOKEN,
        shopDomain: process.env.SHOP_DOMAIN, // optional
        requireExplicitConsent: true, // Only sync with explicit consent
        consentMetadataKey: 'ecomail_consent', // optional, this is the default
      },
    },
  ],
})

GDPR Behavior: Only customers who explicitly consent are synced to Ecomail.

Environment Variables

Add these to your .env file:

ECOMAIL_LIST_ID=your_list_id
ECOMAIL_TOKEN=your_api_token
SHOP_DOMAIN=your-shop.com # optional

Configuration Options

| Option | Type | Required | Default | Description | |--------|------|----------|---------|-------------| | ecomailListId | string | Yes | - | Your Ecomail list ID | | ecomailToken | string | Yes | - | Your Ecomail API token | | shopDomain | string | No | '' | Your shop domain for transaction tracking | | requireExplicitConsent | boolean | No | false | Require explicit consent before syncing customers | | consentMetadataKey | string | No | 'ecomail_consent' | Metadata key to check for consent |

Automatic Syncing

The plugin automatically syncs customers to Ecomail when orders are placed. No additional code is required!

How It Works

  1. Customer places an orderorder.placed event fires
  2. Plugin checks consent (if requireExplicitConsent is enabled)
  3. Syncs customer data to Ecomail list
  4. Tracks transaction for e-commerce analytics

Consent Handling

Default Mode (requireExplicitConsent: false)

All customers are automatically synced to Ecomail when they place an order. No consent checking is performed.

GDPR Mode (requireExplicitConsent: true)

Only customers who explicitly consent are synced. The plugin checks for consent in order or customer metadata.

How to pass consent from your storefront:

When completing checkout, include the consent flag in the order metadata:

// Example: Next.js/React storefront
const completeCheckout = async () => {
  await sdk.store.cart.complete(cartId, {
    metadata: {
      ecomail_consent: userAcceptedNewsletter, // true or false
    },
  })
}
// Example: In a custom checkout flow
await fetch('/store/checkout/complete', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    cart_id: cartId,
    metadata: {
      ecomail_consent: true, // User checked the newsletter box
    },
  }),
})

The plugin checks for consent in this order:

  1. Order metadata (order.metadata.ecomail_consent)
  2. Customer metadata (customer.metadata.ecomail_consent)

If consent is true, the customer is synced. If false or missing (in GDPR mode), the sync is skipped.

Customizing the Consent Key

You can use a different metadata key for consent:

{
  resolve: 'medusa-plugin-ecomail',
  options: {
    // ... other options
    requireExplicitConsent: true,
    consentMetadataKey: 'marketing_consent', // Use your own key
  }
}

Then pass it from your storefront:

metadata: {
  marketing_consent: true
}

Usage

In Your Code

Import and use the Ecomail service in your custom modules, subscribers, or workflows:

import { ECOMAIL_MODULE } from 'medusa-plugin-ecomail'
import type EcomailService from 'medusa-plugin-ecomail'

// In a subscriber or workflow
const ecomailService = container.resolve<EcomailService>(ECOMAIL_MODULE)

// Add a subscriber
await ecomailService.addSubscriber({
  email: '[email protected]',
  name: 'John',
  surname: 'Doe',
  city: 'Prague',
  country: 'CZ',
})

// Smart add/update (checks if exists, handles resubscriptions)
await ecomailService.addSubscriberToListIfNotAdded({
  email: '[email protected]',
  name: 'John',
  surname: 'Doe',
})

// Track an order transaction
await ecomailService.addTransaction(order, customer)

Admin Panel

The plugin adds an Ecomail settings page to your Medusa admin panel where you can:

  • Test subscriber operations (Check, Add, Update, Smart Add)
  • View subscriber details
  • Verify plugin configuration

Access it at: Settings → Ecomail

API Reference

EcomailService Methods

addSubscriber(data: SubscriberDataT)

Adds a new subscriber to the Ecomail list.

Parameters:

  • data.email (required) - Subscriber email
  • data.name - First name
  • data.surname - Last name
  • data.city - City
  • data.country - Country code
  • data.zip - Postal code
  • data.company - Company name
  • data.street - Street address
  • data.phone - Phone number

getExistingSubscriber(email: string)

Retrieves an existing subscriber from the list.

updateSubscriber(data: SubscriberDataT)

Updates an existing subscriber's data.

addSubscriberToListIfNotAdded(data: SubscriberDataT)

Smart method that:

  • Adds subscriber if they don't exist
  • Updates subscriber if they exist and are subscribed
  • Resubscribes if they exist but are unsubscribed

addTransaction(order: OrderDTO, customer: CustomerDTO)

Tracks an e-commerce transaction in Ecomail with order details and items.

Custom Integration Examples

Using the Service Directly

While the plugin automatically syncs on order placement, you can also use the service directly for custom scenarios:

// Example: Add subscriber on customer registration
import { SubscriberArgs } from '@medusajs/framework'
import { ECOMAIL_MODULE } from 'medusa-plugin-ecomail'
import type EcomailService from 'medusa-plugin-ecomail'

export default async function customerCreatedHandler({
  event: { data },
  container,
}: SubscriberArgs<{ id: string }>) {
  const ecomailService = container.resolve<EcomailService>(ECOMAIL_MODULE)
  const customerService = container.resolve('customerService')
  
  const customer = await customerService.retrieve(data.id)

  await ecomailService.addSubscriberToListIfNotAdded({
    email: customer.email,
    name: customer.first_name,
    surname: customer.last_name,
  })
}

export const config = {
  event: 'customer.created',
}

Manual Sync from API Route

// Example: Custom API route for newsletter subscription
import { MedusaRequest, MedusaResponse } from '@medusajs/framework'
import { ECOMAIL_MODULE } from 'medusa-plugin-ecomail'
import type EcomailService from 'medusa-plugin-ecomail'

export async function POST(req: MedusaRequest, res: MedusaResponse) {
  const ecomailService = req.scope.resolve<EcomailService>(ECOMAIL_MODULE)
  const { email, name, surname } = req.body

  await ecomailService.addSubscriberToListIfNotAdded({
    email,
    name,
    surname,
  })

  res.json({ success: true })
}

TypeScript Types

type EcomailModuleOptions = {
  ecomailListId: string
  ecomailToken: string
  shopDomain?: string
  requireExplicitConsent?: boolean
  consentMetadataKey?: string
}

type SubscriberDataT = {
  email: string
  name?: string
  surname?: string
  city?: string
  country?: string
  zip?: string
  company?: string
  street?: string
  phone?: string
  [key: string]: string | undefined
}

Testing

Testing Consent Modes

Default Mode (sync everyone):

  1. Configure plugin without requireExplicitConsent or set it to false
  2. Place a test order
  3. Verify customer appears in Ecomail list
  4. Verify transaction is tracked

GDPR Mode (require consent):

  1. Configure plugin with requireExplicitConsent: true
  2. Place order WITH consent (metadata.ecomail_consent: true)
    • Customer should be synced ✓
  3. Place order WITHOUT consent (metadata.ecomail_consent: false)
    • Customer should NOT be synced ✓
  4. Place order with NO metadata
    • Customer should NOT be synced ✓

Testing via Admin Panel

The plugin includes an admin panel (Settings → Ecomail) where you can:

  • Test adding subscribers manually
  • Check if a subscriber exists
  • Update subscriber information
  • Verify your Ecomail connection

Error Handling

The plugin is designed to be resilient:

  • Ecomail sync failures do not break the order flow
  • All errors are logged for debugging
  • Orders complete successfully even if Ecomail is unavailable

Development

# Build the plugin
yarn build

# Development mode with watch
yarn dev

Resources

License

MIT

Author

Gramino


Made with ❤️ for the Medusa community