Ecomail
Automate Ecomail email marketing
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
123npm install medusa-plugin-ecomail# oryarn add medusa-plugin-ecomail
Configuration
Basic Configuration (Default Mode)
Add the plugin to your Copy to clipboardmedusa-config.ts:
1234567891011121314import { 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:
12345678910111213141516import { 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, // optionalrequireExplicitConsent: true, // Only sync with explicit consentconsentMetadataKey: 'ecomail_consent', // optional, this is the default},},],})
GDPR Behavior: Only customers who explicitly consent are synced to Ecomail.
Environment Variables
Add these to your Copy to clipboard.env file:
123ECOMAIL_LIST_ID=your_list_idECOMAIL_TOKEN=your_api_tokenSHOP_DOMAIN=your-shop.com # optional
Configuration Options
Option Type Required Default Description Copy to clipboardecomailListId string Yes - Your Ecomail list ID Copy to clipboardecomailToken string Yes - Your Ecomail API token Copy to clipboardshopDomain string No Copy to clipboard'' Your shop domain for transaction tracking Copy to clipboardrequireExplicitConsent boolean No Copy to clipboardfalse Require explicit consent before syncing customers Copy to clipboardconsentMetadataKey string No Copy to clipboard'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
- Customer places an order β Copy to clipboard
order.placedevent fires - Plugin checks consent (if Copy to clipboard
requireExplicitConsentis enabled) - Syncs customer data to Ecomail list
- Tracks transaction for e-commerce analytics
Consent Handling
Default Mode (Copy to clipboardrequireExplicitConsent: false)
All customers are automatically synced to Ecomail when they place an order. No consent checking is performed.
GDPR Mode (Copy to clipboardrequireExplicitConsent: 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:
12345678// Example: Next.js/React storefrontconst completeCheckout = async () => {await sdk.store.cart.complete(cartId, {metadata: {ecomail_consent: userAcceptedNewsletter, // true or false},})}
1234567891011// Example: In a custom checkout flowawait 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:
- Order metadata (Copy to clipboard
order.metadata.ecomail_consent) - Customer metadata (Copy to clipboard
customer.metadata.ecomail_consent)
If consent is Copy to clipboardtrue, the customer is synced. If Copy to clipboardfalse or missing (in GDPR mode), the sync is skipped.
Customizing the Consent Key
You can use a different metadata key for consent:
12345678{resolve: 'medusa-plugin-ecomail',options: {// ... other optionsrequireExplicitConsent: true,consentMetadataKey: 'marketing_consent', // Use your own key}}
Then pass it from your storefront:
123metadata: {marketing_consent: true}
Usage
In Your Code
Import and use the Ecomail service in your custom modules, subscribers, or workflows:
1234567891011121314151617181920import { ECOMAIL_MODULE } from 'medusa-plugin-ecomail'import type EcomailService from 'medusa-plugin-ecomail'// In a subscriber or workflowconst ecomailService = container.resolve<EcomailService>(ECOMAIL_MODULE)// Add a subscriberawait ecomailService.addSubscriber({email: 'customer@example.com',name: 'John',surname: 'Doe',city: 'Prague',country: 'CZ',})// Smart add/update (checks if exists, handles resubscriptions)await ecomailService.addSubscriberToListIfNotAdded({email: 'customer@example.com',name: 'John',surname: 'Doe',
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
Copy to clipboardaddSubscriber(data: SubscriberDataT)
Adds a new subscriber to the Ecomail list.
Parameters:
- Copy to clipboard
data.email(required) - Subscriber email - Copy to clipboard
data.name- First name - Copy to clipboard
data.surname- Last name - Copy to clipboard
data.city- City - Copy to clipboard
data.country- Country code - Copy to clipboard
data.zip- Postal code - Copy to clipboard
data.company- Company name - Copy to clipboard
data.street- Street address - Copy to clipboard
data.phone- Phone number
Copy to clipboardgetExistingSubscriber(email: string)
Retrieves an existing subscriber from the list.
Copy to clipboardupdateSubscriber(data: SubscriberDataT)
Updates an existing subscriber's data.
Copy to clipboardaddSubscriberToListIfNotAdded(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
Copy to clipboardaddTransaction(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:
1234567891011121314151617181920// Example: Add subscriber on customer registrationimport { 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,})}
Manual Sync from API Route
1234567891011121314151617// Example: Custom API route for newsletter subscriptionimport { 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.bodyawait ecomailService.addSubscriberToListIfNotAdded({email,name,surname,})res.json({ success: true })}
TypeScript Types
1234567891011121314151617181920type EcomailModuleOptions = {ecomailListId: stringecomailToken: stringshopDomain?: stringrequireExplicitConsent?: booleanconsentMetadataKey?: string}type SubscriberDataT = {email: stringname?: stringsurname?: stringcity?: stringcountry?: stringzip?: stringcompany?: stringstreet?: stringphone?: string[key: string]: string | undefined}
Testing
Testing Consent Modes
Default Mode (sync everyone):
- Configure plugin without Copy to clipboard
requireExplicitConsentor set it to Copy to clipboardfalse - Place a test order
- Verify customer appears in Ecomail list
- Verify transaction is tracked
GDPR Mode (require consent):
- Configure plugin with Copy to clipboard
requireExplicitConsent: true - Place order WITH consent (Copy to clipboard
metadata.ecomail_consent: true)- Customer should be synced β
- Place order WITHOUT consent (Copy to clipboard
metadata.ecomail_consent: false)- Customer should NOT be synced β
- 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
12345# Build the pluginyarn build# Development mode with watchyarn dev
Resources
License
MIT
Author
Gramino
Made with β€οΈ for the Medusa community


