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/integration
module and copy theext-example-email-handler
folder to a new folder namedext-{notificationType}-email-handler
.Optionally copy the
ext-example-email-uat
folder to a new folder namedext-{notificationType}-email-uat
if you want to create a new cucumber test for the new notification type.Declare the new module to the
extensions/integration/pom.xml
file.Rename the
com.elasticpath.extensions.email.handler.example.converter
package within the new module tocom.elasticpath.extensions.email.handler.{notificationType}.converter
.Rename the
ExampleNotificationContextConverter
class within the new module to{notificationType}NotificationContextConverter
.Modify the
{notificationType}NotificationContextConverter
class to read the properties from the event message and return aXPFNotificationDeliveryContext
object with the required notification type name, recipients, and placeholder values.Open the
src/main/resources/META-INF/elasticpath/conf/spring/plugin.xml
Spring configuration file and follow these steps:Rename the
camelContext
bean ID toext-{notificationType}-email-handler
.Rename the beans IDs so that they start with
{notificationType}
instead ofexample
.Within the
{notificationType}NotificationEventRouteBuilder
bean, replace theincomingEndpoint
property with the following, replacing the{notificationType}
placeholders in the XML, and thepath
with 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}EventTypePredicate
bean 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.xml
and override thecustomEmailTypeProperties
bean 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-assets
module. The names of the templates should match thehtmlTemplate
andtextTemplate
properties in thecustomEmailTypeProperties
bean, with a.vm
extension added. Your Velocity template can reference any placeholders defined in your{notificationType}NotificationContextConverter
class.
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..