---
title: Coupons
slug: commerce-connect-14/docs/coupons
docTags: 
createdAt: 2026-07-23T10:25:34.690Z
---

The default coupon system supports setting a single coupon code for any promotion. If set, a matching coupon code must be supplied for the order, or the promotion is not applied.

## Interfaces

To change the default implementation, implement the interfaces below, and register them as the default services in the service locator. See [Dependency injection in Optimizely Content Management System (CMS)](docId\:H_OSCPGONtwggHCyTNtFq) for more information.

### Add coupons to an order

An order's coupons can be accessed via `EPiServer.Commerce.Order.IOrderForm.CouponCodes`. This is an `ICollection<string>`, which supports adding and removing coupon codes.

### ICouponFilter

Components mentioned here are available in the `EPiServer.Commerce.Marketing` namespace.

This interface has one method that has to be implemented. The method filters out promotions that do not meet the requirements for coupons. The method should return a `PromotionFilterContext`, where the `IncludedPromotions` property contains all promotions that are still valid after coupons are evaluated. It should also populate the `PromotionCouponCodeMap` property with information about applied coupon codes, and add descriptions to `ExcludedPromotionDescriptions` for any promotions that were excluded.

```csharp
PromotionFilterContext Filter(PromotionFilterContext filterContext, IEnumerable`<string>` couponCodes);
```

- `filterContext` – Its IncludedPromotions property contains the list of promotions that the engine will evaluate against the current order.
- `couponCodes` – The list of coupon codes supplied for the order.
- `PromotionFilterContext.IncludedItems` – It should include all promotions that meet the coupon requirements. Two types of promotions are included: those that require a coupon and provide a valid one, and those that do not require a coupon. Eliminate promotions that require a coupon, but no valid one is supplied.

Here is an example of a filter that verifies against a single coupon code.

```csharp
public virtual PromotionFilterContext Filter(PromotionFilterContext filterContext, IEnumerable<string> couponCodes)
{
  foreach (var promotion in filterContext.IncludedPromotions)
  {
    var couponCode = promotion.Coupon.Code;
    if (String.IsNullOrEmpty(couponCode))
    {
      continue;
    }

    if (couponCodes.Contains(couponCode, StringComparer.OrdinalIgnoreCase))
    {
      filterContext.AddCouponCode(promotion.ContentGuid, couponCode);
    }
    else
    {
      filterContext.ExcludePromotion(
        promotion, 
        FulfillmentStatus.CouponCodeRequired,
        filterContext.RequestedStatuses.HasFlag(RequestFulfillmentStatus.NotFulfilled));
    }
  }
  return filterContext;
}
```

### ICouponUsage

Implementing this is optional, but you must do so if you want to track coupon codes that were used. Only one method has to be implemented.

```csharp
void Report(IEnumerable<PromotionInformation> appliedPromotions);
```

This method is called when a cart is saved as a purchase order. It is supplied with one parameter: a list of any promotions (both with and without coupon codes) that were applied to the purchase order. Here is an example of implementing it.

```csharp
public class CustomCouponUsage : ICouponUsage
{
  public void Report(IEnumerable<PromotionInformation> appliedPromotions)
  {
    // Store any information needed about the coupon codes that were used.
  }
}
```
