Umbraco Commerce
CMSCloudHeartcoreDXP
15.latest
15.latest
  • Umbraco Commerce Documentation
  • Release Notes
    • v15.1.0-Rc
    • v15.0.0-Rc
  • Commerce Products
    • Commerce Packages
    • Commerce Payment Providers
    • Commerce Shipping Providers
  • Getting Started
    • Requirements
    • Installation
    • Licensing
    • Configuration
    • User Interface
  • Upgrading
    • Upgrading Umbraco Commerce
    • Version Specific Upgrade Notes
    • Migrate from Vendr to Umbraco Commerce
      • Migrate Umbraco Commerce Checkout
      • Migrate custom Payment Providers
  • Tutorials
    • Build a Store in Umbraco using Umbraco Commerce
      • Installation
      • Creating a Store
        • Configuring your Store
      • Creating your first Product
      • Implementing a Shopping Cart
        • Using the Umbraco.Commerce.Cart Drop-in Shopping Cart
        • Creating a Custom Shopping Cart
      • Implementing a Checkout Flow
        • Using the Umbraco.Commerce.Checkout Drop-in Checkout Flow
        • Creating a Custom Checkout Flow
      • Configuring Store Access Permissions
  • How-To Guides
    • Overview
    • Configure SQLite support
    • Use an Alternative Database for Umbraco Commerce Tables
    • Customizing Templates
    • Configuring Cart Cleanup
    • Limit Order Line Quantity
    • Implementing Product Bundles
    • Implementing Member Based Pricing
    • Implementing Dynamically Priced Products
    • Implementing Personalized Products
    • Implementing a Currency Switcher
    • Building a Members Portal
    • Order Number Customization
    • Sending Payment Links to Customers
    • Create an Order via Code
  • Key Concepts
    • Get to know the main features
    • Base Currency
    • Calculators
    • Currency Exchange Rate Service Provider
    • Dependency Injection
    • Discount Rules / Rewards
    • Events
      • List of validation events
      • List of notification events
    • Fluent API
    • Order Calculation State
    • Payment Forms
    • Payment Providers
    • Pipelines
    • Price/Amount Adjustments
    • Price Freezing
    • Product Adapters
    • Product Bundles
    • Product Variants
      • Complex Variants
    • Properties
    • ReadOnly and Writable Entities
    • Sales Tax Providers
    • Search Specifications
    • Settings Objects
    • Shipping Package Factories
    • Shipping Providers
    • Shipping Range/Rate Providers
    • Tax Sources
    • UI Extensions
      • Analytics Widgets
      • Entity Quick Actions
      • Order Line Actions
      • Order Properties
      • Order Collection Properties
      • Order Line Properties
      • Store Menu Items
    • Umbraco Properties
    • Unit of Work
    • Umbraco Commerce Builder
    • Webhooks
  • Reference
    • Stores
    • Shipping
      • Fixed Rate Shipping
      • Dynamic Rate Shipping
      • Realtime Rate Shipping
    • Payments
      • Configure Refunds
      • Issue Refunds
    • Taxes
      • Fixed Tax Rates
      • Calculated Tax Rates
    • Storefront API
      • Endpoints
        • Order
        • Checkout
        • Product
        • Customer
        • Store
        • Currency
        • Country
        • Payment method
        • Shipping method
        • Content
    • Management API
    • Go behind the scenes
    • Telemetry
Powered by GitBook
On this page
  • Product Setup
  • Content Configuration
  • Frontend Configuration
  • Add to Cart Updates
  • Order Editor View

Was this helpful?

Edit on GitHub
Export as PDF
  1. How-To Guides

Implementing Product Bundles

Learn how to implement product bundles in Umbraco Commerce.

PreviousLimit Order Line QuantityNextImplementing Member Based Pricing

Last updated 5 days ago

Was this helpful?

Product bundles are Umbraco Commerces' way of creating composite products. This feature allows you to create a product that consists of multiple sub-products. The sub-products can be optional or mandatory, and you can define the quantity of each sub-product. The final order line will be a composite order line of the selected primary product and its sub-product options.

This guide is not a direct follow-on from the . It is assumed that your store is set up in a similar structure.

Product Setup

To create a product bundle, you need to create a primary product with multiple sub-products. The most common approach is to create a product page with a structure that allows child nodes of a product variant type.

  1. Navigate to the Settings section in the Umbraco backoffice.

  2. Create a Document Type for your primary product.

  1. Create a Document Type for your sub-products.

  1. Update your primary product Document Type to allow child nodes of the sub-product type.

Content Configuration

The bundle content tree will contain a bundle page with variant elements as children.

  1. Navigate to the Content section.

  2. Create a new product page with the primary product Document Type.

  3. Add variant elements as children.

Frontend Configuration

The base product page will display the product details with a list of variants that can be used as add-ons.

Add the following to your product page template.

ProductPage.cshtml
@using (Html.BeginUmbracoForm("AddToCart", "CartSurface", FormMethod.Post))
{
    @Html.Hidden("bundleProductReference", Model.GetProductReference())
    @Html.Hidden("quantity", 1)
            
    <div>
    
        <h2>@Model.Headline</h2>
        <p>@Model.Description</p>
            
        <div>
            <img src="@Model.Image?.Url()" alt="@Model.Name" />
            <h3>@Model.Title</h3>
            <p>Base Price: @(await Model.GetFormattedPriceAsync())</p>
        </div>
        
        <ul>
            @foreach (var item in Model.Children<ProductVariantDetails>())
            {
                <li>
                    <label>
                        <input id="chk_@item.Id" type="checkbox"
                            value="@item.GetProductReference()" name="bundleItemReferences[]" />
                        <img src="@item.Image.GetCropUrl()" alt="@item.Name" />
                        <h3>@item.Name</h3>
                        <p>+ @(await item.GetFormattedPriceAsync())</p>
                    </label>
                </li>
            }
        </ul>
        
        <button type="submit">Add to Cart</button>
        
    </div>
}

Add to Cart Updates

With the frontend setup, you must update the add-to-cart functionality to handle the bundle product and its sub-products.

  1. Update the AddToCartDto object to include the bundle product reference and an array of variant product references.

AddToCartDto.cs
public class AddToCartDto
{
    ...
    public string? BundleProductReference { get; set; }
    public string[] BundleItemReferences { get; set; }
}
  1. Update the AddToCart method on your CartSurfaceController to handle the bundle product and its sub-products.

CartSurfaceController.cs
[HttpPost]
public async Task<IActionResult> AddToCart(AddToCartDto postModel)
{
    try
    {
        await commerceApi.Uow.ExecuteAsync(async uow =>
        {
            StoreReadOnly store = CurrentPage!.GetStore()!;
            Order? order = await commerceApi.GetOrCreateCurrentOrderAsync(store.Id)!
                .AsWritableAsync(uow);
            
            if (postModel.BundleProductReference is null)
            {
                // Not a bundle so add the product directly
                await order.AddProductAsync(postModel.ProductReference, postModel.Quantity);
            } 
            else // Bundle product so add the bundle and its items
            {
                // Create a unique bundle id
                var bundleId = Guid.NewGuid().ToString();

                // Add the bundle product
                await order.AddProductAsync(postModel.BundleProductReference, 1, bundleId);

                // Add the bundle items to the bundle
                foreach (var itemRef in postModel.BundleItemReferences)
                {
                    await order.AddProductToBundleAsync(bundleId, itemRef, 1);
                }
            }
            
            await commerceApi.SaveOrderAsync(order);
            uow.Complete();
        });
    }
    catch (ValidationException ex)
    {
        ModelState.AddModelError("productReference", "Failed to add product to cart");

        return CurrentUmbracoPage();
    }

    TempData["successMessage"] = "Product added to cart";

    return RedirectToCurrentUmbracoPage();
}

When a user adds a product including variants to the cart, the order is created with the primary product and its sub-products combined.

Order Editor View

When an order includes a bundled product, the order editor will display the primary product and its sub-products as a composite order line.

getting started tutorial
Bundle Document Type
Product Variant Details
Product Variant Children
Product Variant Children
Product with Bundle
Order Editor