---
title: ICartOrderProvider
slug: configured-commerce/docs/icartorderprovider
docTags: 
createdAt: 2026-08-13T10:46:18.000Z
---

This provider is used in several places on the Storefront, including on the Cart page and during the checkout process.

## Methods

### CustomerOrder GetCartOrder();

Retrieves the cart for the current user.

### CustomerOrder GetOrCreateCartOrder();

Retrieves the cart for the current session. If a cart does not exist for the current session, a cart will be created and associated with the session.

### void SetCartOrder(CustomerOrder customerOrder);

Associates the cart (customer order) with the current session. This method is called by the `GetOrCreateCartOrder` if and after a cart is created.

- `customerOrder` – The cart to associate with the current session.

### void ClearCache();

If the cart provider stores the current cart in a cache (like using the `PerRequestCacheManager`), this will clear the current cart from that cache.

## Remarks

Configured Commerce provides three standard implementations: `CartOrderProviderByCustomer`, `CartOrderProviderByShipTo`, and `CartOrderProviderByUser`. The `CartOrderProviderByCustomer` associates a cart with the user that created the cart (added products) and the Bill To customer being used at the time the cart was created. The `CartOrderProviderByShipTo` associates a cart with the user that created the cart and the Ship To customer being used at the time the cart was created. The `CartOrderProviderByUserassociates` a cart with the user that created the cart.  Depending on the implementation being used, the current session could include the user who created the cart or the bill-to or ship-to customer being used when the cart was created. Usually these customers are selected immediately after logging into the Storefront.

Only one provider is used at a time. The cart order provider can be configured in the Admin Console using the **Site Configurations** > **Providers** > **Cart Provider** setting.

![](https://api.archbee.com/api/optimize/BrbvVORKJ5iIeSMZye5kI/osqgLXZ4sFvWil9U-jKGf_108d0cc-icart.png)

Implementations of the `ICartOrderProvider` must be decorated with the **ependencyName]** attribute. The `DependencyName` attribute takes a name as an argument. The name will be used to register the implementation in the IOC container. In the Admin Console, the name will appear in the dropdown when selecting a cart provider. This is how the application will know which cart provider to use during runtime.

## Example: Associate the cart with the current user

ependencyName("ByUser")]

```csharp
public class CartOrderProviderByUser : ICartOrderProvider
{
    private int? cartRetentionDays;

    /// <summary>The customer order key.</summary>
    protected const string CustomerOrderKey = "CurrentCustomerOrder";

    /// <summary>The cookie manager.</summary>
    protected readonly ICookieManager CookieManager;

    /// <summary>The customer order utilities.</summary>
    protected readonly ICustomerOrderUtilities CustomerOrderUtilities;

    /// <summary>The per request cache manager.</summary>
    protected readonly IPerRequestCacheManager PerRequestCacheManager;

    /// <summary>The unit of work.</summary>
    protected readonly IUnitOfWork UnitOfWork;

    /// <summary>The cart settings.</summary>
    protected readonly CartSettings CartSettings;

    /// <summary>Gets the cart cookie name.</summary>
    protected virtual string CartCookieName => SiteContext.Current.WebsiteDto.Id + "_Cart";

    /// <summary>Number of days to retain shopping cart.</summary>
    protected virtual int CartRetentionDays => this.cartRetentionDays ?? (this.cartRetentionDays = this.CartSettings.RetentionDays).Value;

    /// <summary>Keep cart from browser session after login.</summary>
    protected virtual bool KeepCartAfterLogin => true;

    /// <summary>Base filter for getting customer order.</summary>
    protected virtual IQueryable<CustomerOrder> ApplyCustomerOrderBaseFilter(IQueryable<CustomerOrder> query)
    {
        var minValidOrderDate = this.CartRetentionDays > 0
            ? DateTimeProvider.Current.Now.AddDays(-this.CartRetentionDays)
            : DateTimeOffset.MinValue;
        var currentUserProfile = SiteContext.Current.UserProfile ?? SiteContext.Current.RememberedUserProfile;

        return query.Where(co => co.WebsiteId == SiteContext.Current.WebsiteDto.Id
            && co.InitiatedByUserProfileId == currentUserProfile.Id
            && (co.Status == CustomerOrder.StatusType.Cart || co.Status == CustomerOrder.StatusType.PunchOut)
            && co.OrderDate > minValidOrderDate);
    }

    /// <summary>Additional filter for getting customer order.</summary>
    protected virtual IQueryable<CustomerOrder> ApplyCustomerOrderAdditionalFilter(IQueryable<CustomerOrder> query)
    {
        return query;
    }

    /// <summary>Initializes a new instance of the <see cref="CartOrderProviderByUser"/> class.</summary>
    /// <param name="cookieManager">The cookie Manager.</param>
    /// <param name="perRequestCacheManager">The per Request Cache Manager.</param>
    /// <param name="unitOfWorkFactory">The unit Of Work Factory.</param>
    /// <param name="customerOrderUtilities">The customer order utilities.</param>
    /// <param name="cartSettings">The cart settings.</param>
    public CartOrderProviderByUser(
        ICookieManager cookieManager,
        IPerRequestCacheManager perRequestCacheManager,
        IUnitOfWorkFactory unitOfWorkFactory,
        ICustomerOrderUtilities customerOrderUtilities,
        CartSettings cartSettings)
    {
        this.CookieManager = cookieManager;
        this.PerRequestCacheManager = perRequestCacheManager;
        this.UnitOfWork = unitOfWorkFactory.GetUnitOfWork();
        this.CustomerOrderUtilities = customerOrderUtilities;
        this.CartSettings = cartSettings;
    }

    /// <summary>The get cart order.</summary>
    /// <returns>The <see cref="CustomerOrder"/>.</returns>
    public virtual CustomerOrder GetCartOrder()
    {
        var customerOrder = this.LookupCustomerOrder();
        if (customerOrder != null && customerOrder.Status == CustomerOrder.StatusType.AwaitingApproval)
        {
            return customerOrder;
        }

        if (customerOrder == null || (customerOrder.Status != CustomerOrder.StatusType.Cart && customerOrder.Status != CustomerOrder.StatusType.PunchOut))
        {
            return null;
        }

        var currentUserProfile = SiteContext.Current.UserProfile ?? SiteContext.Current.RememberedUserProfile;
        if (customerOrder.PlacedByUserProfile != currentUserProfile)
        {
            customerOrder.InitiatedByUserProfileId = currentUserProfile?.Id;
            customerOrder.InitiatedByUserProfile = currentUserProfile;
            customerOrder.PlacedByUserProfileId = currentUserProfile?.Id;
            customerOrder.PlacedByUserProfile = currentUserProfile;
            customerOrder.PlacedByUserName = currentUserProfile?.UserName ?? string.Empty;
        }

        this.SetCartOrder(customerOrder);
        return customerOrder;
    }

    /// <summary>The get or create cart order.</summary>
    /// <returns>The <see cref="CustomerOrder"/>.</returns>
    public virtual CustomerOrder GetOrCreateCartOrder()
    {
        var customerOrder = this.GetCartOrder();
        if (customerOrder != null)
        {
            return customerOrder;
        }

        customerOrder = this.CreateCartOrder();

        this.SetCartOrder(customerOrder);
        return customerOrder;
    }

    /// <summary>The set cart order.</summary>
    /// <param name="customerOrder">The customer order.</param>
    public virtual void SetCartOrder(CustomerOrder customerOrder)
    {
        this.PerRequestCacheManager.Add(CustomerOrderKey, customerOrder);
        var userProfile = SiteContext.Current.UserProfile ?? SiteContext.Current.RememberedUserProfile;
        if (userProfile == null)
        {
            if (customerOrder == null)
            {
                this.CookieManager.Remove(this.CartCookieName);
            }
            else
            {
                var expires = this.CartRetentionDays > 0 ? customerOrder.OrderDate.AddDays(this.CartRetentionDays) : (DateTimeOffset?)null;
                this.CookieManager.Add(this.CartCookieName, customerOrder.Id.ToString(), expires);
            }
        }
    }

    /// <summary>Clears the cache.</summary>
    public virtual void ClearCache()
    {
        this.PerRequestCacheManager.Remove(CustomerOrderKey);
    }

    /// <summary>The create cart order.</summary>
    /// <returns>The <see cref="CustomerOrder"/>.</returns>
    protected virtual CustomerOrder CreateCartOrder()
    {
        var customerOrderRepository = this.UnitOfWork.GetRepository<CustomerOrder>();

        var customerOrder = customerOrderRepository.Create();
        customerOrder.Status = CustomerOrder.StatusType.Cart;
        customerOrder.OrderNumber = Guid.NewGuid().ToString();

        var currentCustomer = SiteContext.Current.BillTo;
        if (currentCustomer == null)
        {
            customerOrder.Customer = this.GetAbandonedCartCustomer();
            this.CustomerOrderUtilities.SetBillTo(customerOrder, customerOrder.Customer);
        }
        else
        {
            customerOrder.Customer = currentCustomer;
            this.CustomerOrderUtilities.SetBillTo(customerOrder, customerOrder.Customer);
            customerOrder.ShipTo = SiteContext.Current.ShipTo;
            this.CustomerOrderUtilities.SetShipTo(customerOrder, customerOrder.ShipTo);
        }

        var currentUserProfile = SiteContext.Current.UserProfile ?? SiteContext.Current.RememberedUserProfile;
        customerOrder.InitiatedByUserProfile = currentUserProfile;
        customerOrder.InitiatedByUserProfileId = currentUserProfile?.Id;
        customerOrder.PlacedByUserProfile = currentUserProfile;
        customerOrder.PlacedByUserProfileId = currentUserProfile?.Id;
        customerOrder.PlacedByUserName = currentUserProfile?.UserName ?? string.Empty;
        customerOrder.Type = CustomerOrder.OrderType.Order;
        customerOrder.Website = this.UnitOfWork.GetRepository<Website>().Get(SiteContext.Current.WebsiteDto.Id);
        customerOrder.WebsiteId = SiteContext.Current.WebsiteDto.Id;

        var currency = SiteContext.Current?.CurrencyDto;
        if (currency != null)
        {
            this.CustomerOrderUtilities.SetCurrency(customerOrder, currency.Id);
        }

        customerOrderRepository.Insert(customerOrder);
        this.UnitOfWork.Save();

        return customerOrder;
    }

    /// <summary>The get abandoned cart customer.</summary>
    /// <returns>The <see cref="Customer"/>.</returns>
    protected virtual Customer GetAbandonedCartCustomer()
    {
        var customerRepository = this.UnitOfWork.GetTypedRepository<ICustomerRepository>();
        var customer = customerRepository.GetBillToByNumber(Customer.AbandonedCartNumber);
        if (customer == null)
        {
            customer = customerRepository.Create();
            customer.CustomerNumber = Customer.AbandonedCartNumber;
            customer.IsBillTo = true;
            customerRepository.Insert(customer);
            this.UnitOfWork.Save();
        }

        return customer;
    }

    /// <summary>The lookup customer order.</summary>
    /// <returns>The <see cref="CustomerOrder"/>.</returns>
    protected virtual CustomerOrder LookupCustomerOrder()
    {
        var customerOrder = this.PerRequestCacheManager.Get<CustomerOrder>(CustomerOrderKey) ?? this.GetCustomerOrder();
        customerOrder = this.ReplaceWithApprovalOrderIfNeeded(customerOrder);
        this.PerRequestCacheManager.Add(CustomerOrderKey, customerOrder);

        return customerOrder;
    }

    /// <summary>The get customer order.</summary>
    /// <returns>The <see cref="CustomerOrder"/>.</returns>
    protected virtual CustomerOrder GetCustomerOrder()
    {
        var currentUserProfile = SiteContext.Current.UserProfile ?? SiteContext.Current.RememberedUserProfile;
        return currentUserProfile == null
            ? this.GetCustomerOrderForNotLoggedUser()
            : this.GetCustomerOrderForLoggedInUser();
    }

    /// <summary>The get customer order for not logged user.</summary>
    /// <returns>The <see cref="CustomerOrder"/>.</returns>
    protected virtual CustomerOrder GetCustomerOrderForNotLoggedUser()
    {
        var customerOrderId = this.CookieManager.Get(this.CartCookieName);
        return customerOrderId.IsBlank()
            ? null
            : this.UnitOfWork.GetRepository<CustomerOrder>().Get(customerOrderId);
    }

    /// <summary>The get customer order for logged in user.</summary>
    /// <returns>The <see cref="CustomerOrder"/>.</returns>
    protected virtual CustomerOrder GetCustomerOrderForLoggedInUser()
    {
        if (this.KeepCartAfterLogin)
        {
            var customerOrderId = this.CookieManager.Get(this.CartCookieName);
            if (!customerOrderId.IsBlank())
            {
                var customerOrder = this.UnitOfWork.GetRepository<CustomerOrder>().Get(customerOrderId);
                if (customerOrder == null)
                {
                    this.CookieManager.Remove(this.CartCookieName);
                }
                else
                {
                    var currentUserProfile = SiteContext.Current.UserProfile ?? SiteContext.Current.RememberedUserProfile;
                    if (customerOrder.InitiatedByUserProfileId == currentUserProfile.Id)
                    {
                        this.CookieManager.Remove(this.CartCookieName);

                        var voidOldCarts = this.ApplyCustomerOrderBaseFilter(this.UnitOfWork.GetRepository<CustomerOrder>().GetTable());

                        this.ApplyCustomerOrderAdditionalFilter(voidOldCarts)
                            .Where(co => co.Id != customerOrder.Id)
                            .Each(co => co.Status = CustomerOrder.StatusType.Void);
                    }

                    return customerOrder;
                }
            }
        }

        var cart = this.ApplyCustomerOrderBaseFilter(this.UnitOfWork.GetRepository<CustomerOrder>().GetTable());
        cart = this.ApplyCustomerOrderAdditionalFilter(cart);
        return cart.OrderByDescending(co => co.CreatedOn).FirstOrDefault();
    }

    /// <summary>The replace with approval order if needed.</summary>
    /// <param name="customerOrder">The customer order.</param>
    /// <returns>The <see cref="CustomerOrder"/>.</returns>
    protected virtual CustomerOrder ReplaceWithApprovalOrderIfNeeded(CustomerOrder customerOrder)
    {
        var cookieKey = SiteContext.Current.WebsiteDto.Id + "_CustomerOrderForApproval";
        var customerOrderForApprovalId = this.CookieManager.Get(cookieKey);
        if (customerOrderForApprovalId.IsBlank() || customerOrderForApprovalId.EqualsIgnoreCase(customerOrder?.Id.ToString()))
        {
            return customerOrder;
        }

        var customerOrderForApproval = this.UnitOfWork.GetRepository<CustomerOrder>().Get(customerOrderForApprovalId);

        var userProfile = SiteContext.Current.UserProfile;
        if (customerOrderForApproval == null || customerOrderForApproval.Status != CustomerOrder.StatusType.AwaitingApproval || userProfile == null)
        {
            this.CookieManager.Remove(cookieKey);
            return customerOrder;
        }

        if (customerOrderForApproval.ApproverUserProfileId == userProfile.Id)
        {
            return customerOrderForApproval;
        }

        // if the user is not an Administrator, then they can only approve orders assigned to themselves
        if (!SiteContext.Current.IsUserInRole(BuiltInRoles.Administrator))
        {
            return customerOrder;
        }

        // if the user is an Administrator, but does not have this billto assigned, return initial order
        if (customerOrderForApproval.Customer.UserProfiles.All(m => m.Id != userProfile.Id))
        {
            return customerOrder;
        }

        // if the shipto is the billto, then the Administrative user has access
        if (customerOrderForApproval.Customer.Id.Equals(customerOrderForApproval.ShipTo.Id))
        {
            return customerOrderForApproval;
        }

        // if the user is an Administrator and has no assigned shiptos, then they can approve any order for their billtos
        var shipTos = this.UnitOfWork.GetTypedRepository<ICustomerRepository>().GetAssignedShipTos(customerOrderForApproval.Customer, userProfile.Id);
        if (!shipTos.Any())
        {
            return customerOrderForApproval;
        }

        // if the user is an Administrator and has assigned shiptos, then they can only approve orders for their assigned shiptos
        if (shipTos.Any(s => s.Id == customerOrderForApproval.ShipTo.Id))
        {
            return customerOrderForApproval;
        }

        return customerOrder;
    }
}
```
