Set Up Promotions
Why promotions matter
Section titled “Why promotions matter”Promotions drive conversion. Whether you are running a seasonal sale, rewarding loyal customers, or clearing excess inventory, the promotion engine in Commerce lets you define precise discount rules without changing your base prices. Campaigns group promotions under a schedule, and stacking rules control how multiple discounts interact.
This guide covers creating promotions, scheduling campaigns, generating coupon codes, and configuring stacking behavior.
What you will do
Section titled “What you will do”- Create discount rules (percentage, fixed amount, buy-X-get-Y)
- Schedule promotions within campaigns
- Generate and manage coupon codes
- Configure promotion stacking rules
Create discount rules
Section titled “Create discount rules”Commerce supports several promotion types. Each type targets a specific scope: entry-level (individual items), order-level (entire cart), or shipping-level.
In the Commerce UI:
- Navigate to Commerce > Marketing > Promotions
- Click Create Promotion
- Select a promotion type (entry discount, order discount, or shipping discount)
- Define the conditions and reward
using EPiServer.Commerce.Marketing;
using EPiServer.Commerce.Order;
using EPiServer;
public class PromotionService
{
private readonly IContentRepository _contentRepo;
public PromotionService(IContentRepository contentRepo)
{
_contentRepo = contentRepo;
}
public void CreatePercentageDiscount(
ContentReference campaignLink)
{
var promotion = _contentRepo
.GetDefault<SpendAmountGetPercentageDiscount>(
campaignLink);
promotion.Name = "Summer Sale 20% Off";
promotion.IsActive = true;
promotion.Banner = null;
// Condition: minimum order $50
promotion.Condition.Amounts =
new List<MoneyAndMarket>
{
new MoneyAndMarket
{
Amount = 50m,
MarketId = "US"
}
};
// Reward: 20% off order
promotion.Percentage = 20m;
_contentRepo.Save(promotion,
EPiServer.DataAccess.SaveAction.Publish,
EPiServer.Security.AccessLevel.NoAccess);
}
} Common promotion types:
| Type | Use case | Example |
|---|---|---|
| Percentage off entry | Discount on specific items | 15% off all running shoes |
| Fixed amount off order | Cart-wide discount | $10 off orders over $75 |
| Buy X get Y | Bundle incentives | Buy 2 shirts, get 1 free |
| Free shipping | Reduce cart abandonment | Free shipping on orders over $50 |
Schedule promotions within campaigns
Section titled “Schedule promotions within campaigns”Campaigns group related promotions under a date range. When the campaign period ends, all promotions within it stop applying automatically.
In the Commerce UI:
- Navigate to Commerce > Marketing > Campaigns
- Click New Campaign
- Enter a name and set the start and end dates
- Create promotions inside the campaign
using EPiServer.Commerce.Marketing;
public void CreateCampaign(
IContentRepository contentRepo,
ContentReference marketingRoot)
{
var campaign = contentRepo
.GetDefault<SalesCampaign>(marketingRoot);
campaign.Name = "Summer Sale 2026";
campaign.ValidFrom = new DateTime(2026, 6, 1);
campaign.ValidUntil = new DateTime(2026, 8, 31);
campaign.IsActive = true;
contentRepo.Save(campaign,
EPiServer.DataAccess.SaveAction.Publish,
EPiServer.Security.AccessLevel.NoAccess);
} Generate coupon codes
Section titled “Generate coupon codes”Coupons require customers to enter a code at checkout to activate a promotion. You can create single-use codes, multi-use codes, or unique codes for each customer.
using EPiServer.Commerce.Marketing;
public class CouponService
{
private readonly ICouponService _couponService;
public CouponService(ICouponService couponService)
{
_couponService = couponService;
}
public void GenerateCoupons(long promotionId,
int count)
{
for (int i = 0; i < count; i++)
{
var code = $"SUMMER26-{Guid.NewGuid()
.ToString("N")[..8].ToUpper()}";
var couponData = new UniqueCoupon
{
Code = code,
PromotionId = promotionId,
Expiration = new DateTime(2026, 8, 31),
MaxRedemptions = 1,
UsedRedemptions = 0,
ValidFrom = DateTime.UtcNow
};
_couponService.SaveCoupons(
new[] { couponData });
}
}
} Configure stacking rules
Section titled “Configure stacking rules”Stacking rules determine whether multiple promotions can apply to the same order. By default, Commerce applies the best single promotion. You can change this to allow stacking or define exclusion groups.
Stacking options:
| Mode | Behavior |
|---|---|
| Exclusive | Only the highest-value promotion applies |
| Stackable | Multiple promotions can combine |
| Exclusion group | Promotions in the same group are mutually exclusive; promotions in different groups can stack |
Set the ExclusionLevel property on each promotion to control its stacking behavior.
Common issues
Section titled “Common issues”| Issue | Cause | Fix |
|---|---|---|
| Promotion not applying at checkout | Campaign date range has not started or has ended | Verify campaign ValidFrom and ValidUntil dates |
| Coupon code rejected | Code expired or max redemptions reached | Check expiration date and MaxRedemptions count |
| Multiple discounts not combining | Promotions set to exclusive mode | Change promotion stacking to stackable or use different exclusion groups |
| Discount amount incorrect | Condition thresholds not met | Verify the customer’s cart meets the minimum spend or quantity requirements |