Skip to Content
Technical Articles
Author's profile photo Gang Li

Use Emarsys to Distribute Coupon Codes for SAP Commerce


As enterprise e-commerce platform, SAP Commerce Cloud provides solid support for marketing, such as coupon management, promotion rule, personalization etc. Unfortunately, although SAP commerce has implemented a demo in B2C/B2B accelerator to distribute coupon by using free coupon action in promotion rule, it’s far from enough to meet the complex scenarios in real projects, such as:

  • Coupon can be distributed across multiple channels
  • Personalization can be supported in coupon distribution related content
  • Statistics is required to help customers understand how much these related marketing targets are reached

On the other hand, Emarsys is the omni-channel marketing platform, which just cover all these requirements:

  • Coupon can be distributed across multi channels, such as email, mobile, web, etc.
  • All kinds of personalization features (such as token, conditional text, ESL, etc.) can be used in coupon distribution related email or message.
  • Different dashboards are provided to give an overall insight about coupon distribution program from different aspects

Apparently, we can use Emarsys to distribute coupon for SAP Commerce Cloud. In this post, I will implement a simplified prototype to demo it


The basic thinking is simple:

  1. Whenever a coupon is created in SAP Commerce by using any way (Backoffice, ImpEx, coding), an outer event is created in Emarsys.
  2. Create an interactive coupon distribution program in Emarsys, which will use the outer event as the trigger event
  3. When coupon codes for this coupon are generated in SAP Commerce, they need to be uploaded in Emarsys
  4. Any related components in SAP Commerce Cloud can trigger this outer event to activate coupon distribution

The following diagram is the conceptual architecture of this prototype,

Figure 1: The Conceptual Architecture for This Prototype

Two major components are introduced in SAP Commerce Cloud:

  • CouponEventListener: responsible for create outer event in Emarsys whenever a new coupon is created in SAP Commerce Cloud
  • EmarsysCouponService: responsible for activating the coupon distribution program in Emarsys

In Emarsys, we need to create an interaction program with outer event as the trigger event, this interaction program can distribute coupon across multiple channels

Prototype Implementation


We have the following assumptions for simplicity:

  • Only implement email-based coupon distribution, if you want to support other channels,  please refer to Emarsys online help documents
  • User is identified using email
  • Only happy path is covered for interaction between Sap Commerce and Emarsys, in other words, we don’t process exceptional conditions in code

SAP Commerce Cloud Side

Define New Type EmarsysCoupon

First, create an new extension, define a new type EmarsysCoupon in this new extension:

<itemtype code="EMarsysCoupon" jaloclass="de.hybris.platform.couponservices.jalo.EmarsysCoupon"
extends="MultiCodeCoupon" generate="true" autocreate="true">
		<attribute qualifier="outerEventId" type="java.lang.String">
			<persistence type="property"/>				
			<description>used to indicate outer event generated by Emarsys.</description>

EmarsysCoupon is a subtype of MultiCodeCoupon with a new attribute ‘outerEventId’, this attribute is used to uniquely identify related outer event created by Emarsys.

Define EmarsysConnector Interface and Implementation

public interface EmarsysConnector
	 * Send data to Emarsys.
	 * @param method
	 *           the http method, such as get, post, etc.
	 * @param urlText
	 *           url path
	 * @param data
	 *           the data in JSON format, which will be send to Emarsys as request body
	String send(String method, String urlText, String data);
public class DefaultEmarsysConnector implements EmarsysConnector

EmarsysConnector is used to communicate with Emarsys based on Emarsys API, for simplicity, i don’t paste the details for DefaultEmarsysConnector, you can refer to

Define EmarsysCouponService Interface and Implementation

EmarsysCouponService interface is a sub interface of CouponService, which introduces two method:

public interface EmarsysCouponService extends CouponService
	 * Create an outer event in Emarsys, by which coupon distribution can be triggered.
	 * @param couponDistribEventName
	 *           the outer event to be created in Emarsys in order to distribute coupon
	 * @return the coupon distribution event id returned by Emarsys
	String createCouponDistribEvent(String couponDistribEventName);

	 * Delegate Emarsys to distribute coupon.
	 * @param couponDistribEventId
	 *           the outer event id in Emarsys
	 * @param userEmail
	 *           the email used to identify current user
	 * @return the outer event id returned by Emarsys
	void distributeCoupon(String couponDistribEventId, String userEmail);

The default implementation is DefaultEmarsysCouponService, which is a sub class of Default CouponService.

public class DefaultEmarsysCouponService extends DefaultCouponService implements EmarsysCouponService
	private EmarsysConnector emarsysConnector;


	public String createCouponDistribEvent(final String couponDistribEventName)
		final String response = emarsysConnector.send("POST", "/event", "{\"name\":\"" + couponDistribEventName + "\"}");
		final Gson gson = new Gson();
		final EventResponse eventResponse = gson.fromJson(response, EventResponse.class);
		if (eventResponse.getData() != null)
			return eventResponse.getData().getId();
		return null;

	public void distributeCoupon(final String couponDistribEventId, final String userEmail)
		final String response = emarsysConnector.send("POST", "/event/" + couponDistribEventId + "/trigger",
				"{\"key_id\":\"3\", \"external_id\":\"" + userEmail + "\", \"data\":null, \"contacts\":null}");



Define CouponEventListener

CouponEventListener will invoke Emarsys API to create an outer event whenever an EmarsysCoupon is created in SAP Commerce.

public class CouponEventListener extends AbstractEventListener<AfterItemCreationEvent>
	private ModelService modelService;
	private EmarsysCouponService emarsysCouponService;


	protected void onEvent(final AfterItemCreationEvent event)
		if (event.getTypeCode().equals(EMarsysCouponModel._TYPECODE))
			if ((event.getSource() != null))
				final EMarsysCouponModel coupon = (EMarsysCouponModel) modelService.get(event.getSource());
				final String couponDistribEventName = coupon.getCouponId() + "CouponDistribEvent";
				final String eventId = emarsysCouponService.createCouponDistribEvent(couponDistribEventName);

Please note

  • There is a contract between EmarsysCoupon ID and outer event name, if the coupon id is ‘tmp’, then outer event name is ‘tmpCouponDistribEvent’.
  • As CouponEventListener successfully invoke Emarsys API to create an outer event, it will keep the outer event ID in the new created EmarsysCoupon, so other Commerce modules can use this ID to trigger the distribution of EmarsysCoupon codes

Configure Spring

    <bean id="couponEventListener" class="de.hybris.emarsysintegrate.listener.CouponEventListener"
                           parent="abstractEventListener" >
    	<property name="modelService" ref="modelService" />
    	<property name="emarsysCouponService" ref="emarsysCouponService" />
    <bean id="emarsysConnector" class="de.hybris.emarsysintegrate.service.impl.DefaultEmarsysConnector" lazy-init="true">
   		<constructor-arg name="environment" value="${environment}" />
   		<constructor-arg name="apiUsername" value="${apiUsername}" />
   		<constructor-arg name="apiSecretKey" value="${apiSecretKey}" />
    <alias name="emarsysCouponService" alias="couponService" />
    <bean id="emarsysCouponService" class="de.hybris.emarsysintegrate.service.impl.DefaultEmarsysCouponService" >
   		<property name="emarsysConnector" ref="emarsysConnector" />

Create an EmarsysCoupon in Backoffice

Navigate to System -> Marketing ->Coupon Management -> Coupons, create a new EmarsysCoupon

  • Id: tmp
  • Name: tmp emarsys coupon

After this step is finished, you can visit Emarsys to make sure an outer event ‘tmpCouponDistribEvent’ has been created, it indicates CouponEventListener has used EmarsysCouponService to create related outer event in Emarsys.

Figure 2: New Created Outer Event in Emarsys

Furthermore, Refresh new created EmarsysCoupon in Backoffice, you will find outer event ID has been filled.

Figure 3: Outer Event ID Set in Backoffice

Generate Coupon Codes

Open new created EmarsysCoupon ‘tmp’

Generate 100 coupon codes for EmarsysCoupon ‘tmp’, download this generated csv file into local file system.

Emarsys Side

Create Voucher Pool

Navigate to Add-ons -> Omnichannel Voucher, create a voucher pool ‘demo_voucher_pool’, upload coupons csv file generated by previous step.

Figure 4: New Created Voucher Pool in Emarsys

Create Voucher-Based Personalization Token

Navigate to Content->Personalization, create a voucher-based token ‘demo_voucher_token’, choose ‘demo_voucher_pool’ as the value of Field.

Create Coupon Distribution Email Campaign

Navigate to Channels -> Tiggered Email, create a block based coupon distribution email ‘Demo Coupon Distribution Email’, email content will contain token ‘demo_voucher_token’ created by previous step. Finally, don’t forget to activate this email campaign

Figure 5: The Content for The Demo Email Campaign

Create Interaction Program

Navigate to Automation -> Automation Programs, create an interactions program ‘Demo Coupon Distribution’.

Figure 6: The Demo Interaction Program for Distributing Email

Configure like this:

  • Choose tmpCouponDistribEvent as the outer event
  • Choose ‘Demo Coupon Distribution Email’ in the Send email node
  • Enable ‘Only once ever’ in the Participation check node to make sure each customer will just receive one email

Finally, activate this program.


Write a test code to invoke EmarsysCouponService.distributeCoupon(String couponDistribEventId, String userEmail) with the following parameters

  • couponDistribEventId: 12460, this value is gotten from the new created Emarsys coupon, which is returned from Emarsys (don’t foreget we extend Multi code coupon with new attribute ‘outerEventId’
  • userEmail: use your personal email

After running the test code, wait several minutes, you will get a new email containing assigned coupon code similar like this:

Figure 7: Received Coupon in Email


Since Emarsys doesn’t provide API to programmatically create vouch pool, upload related coupon code, and create related personalization token, we’ll have to manually do it, but we can use workflow in SAP Commerce to make sure related users will be assigned task to do these work in Emarsys whenever a new EmarsysCoupon is created,

Another possible enhancement is to support batch coupon distribution, so a list of users will be assigned coupon code with just one invocation.


This post just shed some light on how to use Emarsys to support multi-channel coupon distribution for SAP Commerce Cloud, in future, i will share more example to utilize Emarsys features to extend SAP Commerce Cloud functionalities.

If you have any questions and feedback, please use comment box below, 🙂

Assigned Tags

      Be the first to leave a comment
      You must be Logged on to comment or reply to a post.