Email Delivery
Email delivery in Self-Managed Commerce is now handled as part of the Notification Events extension point. By default, the VelocitySMTPEmailSender extension will implement this extension point, which renders emails using Apache Velocity and uses SMTP to send out the emails. The details included in this page are specific to the VelocitySMTPEmailSender extension.
All emails have plain text versions, and some also have HTML versions. Each email event uses a different template and includes event-specific properties (such as order details or customer details). The details of these properties are documented within the Notification Events extension point.
Technical Details
The VelocitySMTPEmailSender extension uses Apache Velocity to render the email templates. The general administration (non-store) email templates are located in <assets>/cmassets/templates/velocity/email. Store specific email templates are located in <assets>/themes/<theme_name>/default/templates/velocity/email.
Emails are sent as multi-part MIME (Multipurpose Internet Mail Extensions) messages. If the email client cannot accept an HTML version, most email clients will fallback to the text version.
Adding a new notification type
To support a new notification type, first decide on a unique key for the custom notification type. Then follow the steps below.
Create an email handler module and the Velocity templates
Follow these steps to create a new email handler module:
Open the
extensions/integrationmodule and copy theext-example-email-handlerfolder to a new folder namedext-{notificationType}-email-handler.Optionally copy the
ext-example-email-uatfolder to a new folder namedext-{notificationType}-email-uatif you want to create a new cucumber test for the new notification type.Declare the new module to the
extensions/integration/pom.xmlfile.Rename the
com.elasticpath.extensions.email.handler.example.converterpackage within the new module tocom.elasticpath.extensions.email.handler.{notificationType}.converter.Rename the
ExampleNotificationContextConverterclass within the new module to{notificationType}NotificationContextConverter.Modify the
{notificationType}NotificationContextConverterclass to read the properties from the event message and return aXPFNotificationDeliveryContextobject with the required notification type name, recipients, and placeholder values.Open the
src/main/resources/META-INF/elasticpath/conf/spring/plugin.xmlSpring configuration file and follow these steps:Rename the
camelContextbean ID toext-{notificationType}-email-handler.Rename the beans IDs so that they start with
{notificationType}instead ofexample.Within the
{notificationType}NotificationEventRouteBuilderbean, replace theincomingEndpointproperty with the following, replacing the{notificationType}placeholders in the XML, and thepathwith the setting definition path that defines where the event messages should be retrieved from.<property name="incomingEndpoint"> <bean class="com.elasticpath.messaging.camel.impl.SettingValueBackedCamelEndpointFactoryBean"> <property name="path" value="COMMERCE/SYSTEM/MESSAGING/CMUSERS/channelUri" /> <property name="context" value="{notificationType}NotificationHandler"/> <property name="settingsReader" ref="settingsReader"/> <property name="camelContextId" value="ext-{notificationType}-email-handler" /> </bean> </property>
Find the
{notificationType}EventTypePredicatebean definition and update the compatible event types to match the type of messages that your module will handle.Add a dependency on the new module within
extensions/integration/ext-integration-webapp/pom.xml.Open
extensions/core/ext-core/src/main/resources/META-INF/conf/ep-core-plugin.xmland override thecustomEmailTypePropertiesbean as follows:
<bean id="customEmailTypeProperties" class="java.util.HashMap">
<constructor-arg>
<map>
<entry key="EXAMPLE_EMAIL">
<bean class="com.elasticpath.email.domain.impl.EmailTypePropertiesImpl">
<property name="defaultSubject" value="Example email for testing"/>
<property name="localeDependentSubjectKey" value="example.emailSubject"/>
<property name="htmlTemplate" value="example.html"/>
<property name="textTemplate" value="example.txt"/>
</bean>
</entry>
</map>
</constructor-arg>
</bean>
Replace EXAMPLE_EMAIL with your custom notification type name, and update the defaultSubject, localeDependentSubjectKey, htmlTemplate, and textTemplate properties as required. The htmlTemplate property can be omitted if your notification type does not require an HTML version of the email.
- Create new Velocity templates for your custom notification type in the
extensions/assets/ext-assetsmodule. The names of the templates should match thehtmlTemplateandtextTemplateproperties in thecustomEmailTypePropertiesbean, with a.vmextension added. Your Velocity template can reference any placeholders defined in your{notificationType}NotificationContextConverterclass.
Liquibase changes
You will need to define a new Liquibase changeset to create the new setting value that the {notificationType}NotificationEventRouteBuilder bean will use.
Example:
<changeSet id="2025-06-{notificationType}-notification-event-handler-setting" author="elasticpath">
<customChange class="liquibase.ext.elasticpath.CreateSettingValue">
<param name="path" value="COMMERCE/SYSTEM/MESSAGING/CMUSERS/channelUri"/>
<param name="context" value="{notificationType}NotificationHandler"/>
<param name="contextValue"
value="jms:queue:Consumer.{notificationType}NotificationHandler${extensionQueueName}.VirtualTopic.ep.dataimport"/>
</customChange>
</changeSet>
note
Make sure to replace the path value and the {notificationType} placeholders in the example above, but leave the ${extensionQueueName} placeholder, which is replaced automatically by the {notificationType}NotificationEventRouteBuilderFactory for each extension that implements the NotificationEvent extension point..