In general, there are two kinds of promotions: implicit and explicit promotions.
An implicit promotion applies as soon as its condition is met. In contrast to this, an explicit promotion depends on a code, which must be entered by the consumer. An explicit promotion is also called "code based promotion".
This document explains the concept of promotion code groups and single promotion codes. It covers the creation, management and redemption of codes.
The motivation for introducing promotion code groups is the wish to:
Each promotion is created as an implicit promotion at first. The promotion manager has to enable the promotional code handling in the Commerce Management application. The picture shows a promotion which is assigned to one promotion code group.
A promotion code group is an entity which:
Furthermore, it is possible to restrict the code redemption:
Code reuse per customer
: defines how often a single consumer can use the provided code.Total reuse per code
: defines how often a code can be used in total over all customers.Application
: defines which application supports that code group.The screenshot shows a configuration of a promotion code group:
A promotion code group can also have different target groups. Per default target groups from the corresponding promotions are active.
This setting can be changed in order to limit the number of redemptions per customer segment. See the following picture for an example. In that case codes from the promotion code group can be applied 500 times for customers from the premium customers segment and only 100 times for new customers. When a customer redeems a code and afterwards submits the order, the redemption count is increased for his customer segment. If a customer belongs to multiple customer segments where limitations of redemptions are configured, the redemption count is increased for the customer segment which has the highest number of redemptions left.
Promotion codes are arbitrary strings, inserted manually, or generated randomly. Promotion codes can have the following statuses:
Status | Meaning |
---|---|
0 | The promotion code is active and not redeemed. |
1 | The promotion code is active, but fully redeemed. |
2 | The promotion code is deactivated permanently. |
Note
Promotion codes cannot be redeemed partially.
The API is defined in interface PromotionCode
. It provides functionality to handle codes.
There are different ways to create promotion codes:
Pipelines for code handling are: ViewPromotionCodeList
(sld_ch_base) and ProcessPromotionCode
(bc_marketing).
The promotion code creation is done in pipelet: CreatePromotionCodes
(bc_marketing )
. It creates promotion codes for the given iterator of promotional code strings and commits them into the database. A commit level is set: a step size in order to save a such sized block of codes.
The API for creating promotion codes is available in PromotionCodeRepository
. It offers methods to create a single code instance for the passed code string, and to create a collection of codes for the given code string iterator.
The promotion manager can type codes in the input box or copy them from an external source. Each code must begin in a new line. (See screenshot.)
Manually added promotion codes have to be validated by profanity check functionality. Profanity check allows to configure a set of forbidden words. User entries can be checked against this black list and error messages will be shown when some of the words are used.
It is possible to create randomly generated codes. The following input parameters are required:
Parameter | Meaning |
---|---|
Code prefix | The promotion manager can define a code prefix, e.g., X-MAS. All generated codes will get that prefix. |
Code length | The promotion manager can specify the number of characters in the generated code string. |
No. of codes | The promotion manager can set the number of codes to be generated. |
Note
Since the prefix is part of the code, the specified code length must be larger than the number of characters in the prefix.
It is also possible to import promotion codes from a CSV file. The mapping template is PromotionCodeCSVConvert
(bc _marketing)
.
The first line may contain some header information.
The import is done by the ImpEx framework. It performs a batch job. The processing pipeline is ProcessPromotionCodeImport
(bc_marketing).
Additional pipelines are: ViewPromotionCodeImportUploadFile
(sld_ch_base) to upload the import file and ViewPromotionCodeImport
(sld_ch_base) to configure the import.
The snippet shows an example of a test file.
promotion-code testAI testCG testIS testQF testT8
Furthermore it is possible to export promotion codes into a CSV format. Codes can be exported at once, or classified by their state: redeemed, not redeemed or deactivated. The export is executed by ProcessPromotionCodeExport
(bc_marketing) as a batch job. Pipeline ViewPromotionCodeExport
(sld_ch_base) prepares the export.
Promotion codes can be deactivated. Marketing managers have one or two options to deactivate a code this way:
Note
Promotion codes once deactivated cannot be reactivated again.
As described before, a promotion code group is a container for many promotion codes. Promotion code groups can be used if a marketing manager wants to promote a product by providing individual codes, or trigger more than one promotion by a code. In contrast to that, it is possible to define only one code for a promotion: This is called Single Promotion Code. It is only valid in combination with the promotion it is defined for. The code redemption can be restricted the same ways as for promotion code groups:
Code reuse per customer
: Defines how often a single consumer can use the code.Total reuse per code
: Defines how often the code can be used in total over all customers.A customer can enter one or more codes for the order. As for the appliance of the code to the order the following criteria are checked:
Note
The configuration of the number of code reuses per customer for a single promotion code or promotion code group is limited to Registered Customers. Depending on the promotion target group, e.g., Everyone, anonymous users can also redeem a promotion code. Since it is not possible to distinguish anonymous users from each other, an anonymous user could redeem a promotion code more often as configured.
Nonetheless Intershop recommends to restrict the promotion target groups for such use cases (configured number of code reuses per customer) to Registered Users..
Starting from ICM version 7.9 the logic is implemented in BO Extensions.
To add a promotion code to the basket and further checks and functionality around the basket, use the BasketBOPromotionCodeExtension
.
To redeem a promotion code - count redemptions, remove reservation etc. - after the order has been created, use OrderBOPromotionCodeExtension
.
As mentioned before there are promotion codes that are limited to a certain number of redemptions. In order to ensure that such a promotion code, which is applied to the basket, is still valid when the user submits the order, the concept of promotion code reservation has been newly introduced. Every time a promotion code is applied to the basket, this code is exclusively reserved for the current user and basket for a certain time. During this time the reserved promotion code is not applicable for other users and is treated as it had already been redeemed.
The reservation will automatically expire after the configurable reserving period. If a promotion code is still applied to basket and its reservation expires, the basket validation will automatically extend the reservation if this is possible or otherwise raise an error and remove the code if such adjustments are allowed.
See Concept - Promotion Validation for further details.
The reserving period of promotion codes in minutes can be set in the application settings promotion tab. The default value is 1,440 minutes which represents one day. This period usually covers the time from applying the promotion code until submitting the order in B2C scenarios.
For B2B this might be quite different, when an approval process is configured. In such a case the time frame from applying the promotion code until the order is successfully created may be much longer because multiple persons might have to approve the order first.
To be sure that the reservation of a promotion code will not expire before an order is approved by all required people, the reserving period should be at least as high as the longest response time that is tolerable for approvals, e.g., one week.
When a promotion code is redeemed in the basket, a promotion code reservation entry is stored in the database. Depending on the type of the promotion code - Single Promotion Code or Promotion Code with Code Group - different database tables are used.
For Single Codes, which are stored at the promotion, the reservations will be stored in the table PROMOTIONBASKETRESERVATION. BASKETUUID
together with PROMOTIONUUID
are used as primary key. Additionally, each entry contains the USERID
, the CREATIONDATE
and the EXPIRATIONDATE
.
Promotion codes based on Promotion Code Groups are stored in a separate database table. That is why the reservations will also be stored in a different table called PROMOTIONCODEBASKETRESERVATION. BASKETUUID
together with PROMOTIONCODEUUID
are used as primary key. Additionally, each entry contains the USERID
, the CREATIONDATE
and the EXPIRATIONDATE
.
Every time a promotion code is redeemed for a basket, an entry in the corresponding promotion code reservation table is created. During the time frame from creation date until expiration date the promotion code is reserved/blocked for the current user and basket. If the promotion code has a configured number of reuses in total or per customer (user), then the reservation will lead to a reduced amount of available codes, even if the basket with the code has not been checked out yet. During the promotion code validation the number of available redemptions is validated including the existing promotion code reservations.
When the number of uses plus the number of reservations exceeds the configured number of reuses, then the promotion code cannot be applied anymore or an error occurs during the checkout in case the promotion code is already in the basket.
If a basket contains a promotion code whose reservation expired, the promotion validation will automatically extend the promotion code reservation if possible (creation date and expiration date is updated).
The expiration date is calculated and stored during the creation of the reservation to ensure that a reservation automatically expires without any actions.
Future development
The reserving period of promotion codes will be configurable in the Commerce Management application.
If the reservation of a promotion code is expired, then the code can be redeemed by other customers.
Expired reservations for no more open baskets will be cleaned by a job automatically.
A new interface PromotionCodeGroup
has been introduced. A promotion code group is a container for promotion codes. It holds all attributes to administer promotion codes. Therefore, a huge number of codes can be managed at the same time.
A promotion can be assigned to one or more promotion code groups. On the other hand, a promotion code group can be assigned to different promotions. In other words, a promotion code can trigger more than one promotion at the same time. However, promotion and promotion code group must be in the same domain.
The following interfaces or classes play a vital role in the promotion code (group) context.
Cartridge | Class | Task |
---|---|---|
bc_marketing |
| It holds the information about the code, its state and its redemption. |
bc_marketing |
| Container mapping promotions to codes, it can be assigned to different promotions. |
bc_marketing |
| A promotion can be assigned to different promotion code groups. |
core |
| The group of users that are allowed to apply the code (per default the promotion's target groups are used). |
core |
| The domain where the promotion code groups are valid (promotion and code group must be in the same domain). |
In addition, some business logic to maintain promotion codes and groups exists.
Cartridge | Class | Task |
---|---|---|
bc_marketing |
| Provides business logic to handle promotion code groups, like create, remove and get. |
bc_marketing |
| Provides business logic to handle promotion codes, like create, remove and get. |
bc_marketing |
| Creates an instance of |
Besides the persistent object layer mentioned above there is a business object layer which should be used to programmatically handle promotion code group related tasks.
Here is an overview of available objects and its methods:
Cartridge | Class | Task |
---|---|---|
bc_promotion | com.intershop.component.promotion.capi.PromotionCodeBO | Provides method to check if code can be redeemed, is accessible and active. Also see: |
bc_promotion | com.intershop.component.promotion.capi.PromotionCodeGroupBO | Provides business logic to handle promotion code groups, like create, remove and get. |
bc_promotion | com.intershop.component.promotion.capi.PromotionBO | Provides methods to handle all promotion relevant functionality |
bc_promotion | com.intershop.component.promotion.capi.PromotionCodeBORepository | Provides methods to get a promotion code business object and to create one |
bc_promotion | com.intershop.component.promotion.capi.PromotionCodeGroupBORepository | Provides methods to get a promotion code group business object and to create one |
bc_promotion | com.intershop.component.promotion.capi.PromotionBORepository | Provides methods to handle promotions, like create, remove and get. |
bc_basket | com.intershop.component.basket.capi.extension.BasketBOPromotionCodeExtension | Provides methods to add/remove a promotion code to/from the basket and additional functionality regarding promotion code reservation |
bc_order | com.intershop.component.order.capi.extension.OrderBOPromotionCodeExtension | Provides a method to redeem a promotion code after the order has been created |