There is no recommended way to do this customization, but I can give you some suggestions.
You will need a way of tracking how many samples did the customer get already. The easiest solution to do that is to add a custom field to the Customer record, which will tell how many free samples do they have left, and save the remaining amount when the order has been submitted. This is to ensure that the customer does not lose free sample eligibility if their shopping cart expires. An alternative solution would be to retrieve all past orders, based on the customer ID and search for how many items were already provided as a sample.
Afterwards, you will have to track which items in shopping cart are samples. The best solution for this is to use the item.CartItemCustomData xml to save a custom flag with number of discounted units. You can then cycle through shopping cart items, and see how many items are already considered a free sample.
The final step will be the discount itself. You can add any custom discount by overriding this method ShoppingCartItemInfoProvider.GetDiscountsInternal(ShoppingCartItemInfo item), which is called to evaluate shopping cart item discounts:
/// Returns the list of all discounts which should be applied to the specified shopping cart item.
/// <param name="item">Shopping cart item</param>
protected override List<IItemDiscount> GetDiscountsInternal(ShoppingCartItemInfo item)
List<IItemDiscount> discounts = base.GetDiscountsInternal(item);
if (discounts != null && item != null && item.ShoppingCart != null)
item.CartItemCustomData["Sample"] = "";
// Add myDiscount
ItemDiscount myDiscount = new ItemDiscount
ItemDiscountType = DiscountTypeEnum.CustomDiscount,
ItemDiscountValue = 100,
ItemDiscountIsFlat = false,
ItemDiscountedUnits = item.CartItemUnits,
ItemDiscountCustomData = null,
ItemDiscountDisplayName = "MyDiscount",
ItemDiscountIsGlobal = false,
ItemDiscountID = "MyDiscountID"
item.CartItemCustomData["Sample"] = item.CartItemUnits;
In this code, you will need to determine a condition based on which you will be making the item free for the customer. I suggest that you run a foreach over item.ShoppingCart.CartItems list, and verify how many items (and their units) are marked as “Sample” in the item custom data. If this number + number of units of the current item is lower than the remaining free samples for the customer, mark the item as Sample and add 100% discount.