Skip to content

Set Up Promotions

⏱ 25 minutes intermediate
📜Corecommerce

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.

  1. Create discount rules (percentage, fixed amount, buy-X-get-Y)
  2. Schedule promotions within campaigns
  3. Generate and manage coupon codes
  4. Configure promotion stacking 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:

  1. Navigate to Commerce > Marketing > Promotions
  2. Click Create Promotion
  3. Select a promotion type (entry discount, order discount, or shipping discount)
  4. Define the conditions and reward
Create a percentage discount promotion
csharp
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:

TypeUse caseExample
Percentage off entryDiscount on specific items15% off all running shoes
Fixed amount off orderCart-wide discount$10 off orders over $75
Buy X get YBundle incentivesBuy 2 shirts, get 1 free
Free shippingReduce cart abandonmentFree shipping on orders over $50

Campaigns group related promotions under a date range. When the campaign period ends, all promotions within it stop applying automatically.

In the Commerce UI:

  1. Navigate to Commerce > Marketing > Campaigns
  2. Click New Campaign
  3. Enter a name and set the start and end dates
  4. Create promotions inside the campaign
Create a campaign with date boundaries
csharp
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);
}

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.

Add coupon codes to a promotion
csharp
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 });
        }
    }
}

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:

ModeBehavior
ExclusiveOnly the highest-value promotion applies
StackableMultiple promotions can combine
Exclusion groupPromotions 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.

IssueCauseFix
Promotion not applying at checkoutCampaign date range has not started or has endedVerify campaign ValidFrom and ValidUntil dates
Coupon code rejectedCode expired or max redemptions reachedCheck expiration date and MaxRedemptions count
Multiple discounts not combiningPromotions set to exclusive modeChange promotion stacking to stackable or use different exclusion groups
Discount amount incorrectCondition thresholds not metVerify the customer’s cart meets the minimum spend or quantity requirements