Co-Purchases (Frequently Bought Together)

Overview

The Co-Purchases feature analyses your customers' purchasing behaviours to automatically recommend products that are frequently bought together. This powerful cross-selling tool increases average order value by suggesting relevant products at key points in the customer journey.

How It Works

Aurora Commerce tracks which products customers purchase together and uses this data to generate intelligent recommendations. These recommendations can appear anywhere you present a product to the customer, but typically includes:

  • The product detail pages (PDP) - showing items frequently bought with the current product
  • The shopping basket - suggesting complementary items based on basket contents
  • The order complete page - to encourage follow-up orders
📘

Note: Co-purchase data is cached and typically takes up to one hour to reflect the latest purchase patterns. But you can always expedite this in a pinch using the Flush Cache feature under Store > Tools > Caching section in the Aurora Back-end.

Configuration

Enabling Co-Purchases

  1. Navigate to Settings > Aurora > Products in the Aurora Back-end
  2. Locate or create a product list with type "Co-Purchases"
  3. Enable the "Enable Co-Purchasing Data" check-box
📘

Please be aware that doing this for the first time can then results in a considerable delay before your recommendations are ready. The first time you activate this service, Aurora will begin back-filling the purchase statistics for the last 6 months. While you need do nothing to ensure this occurs, it can take a few hours on the first activation.

Once the backlog has been processed, the data is kept up to date as orders are placed throughout the day.

Algorithm Settings

The co-purchase algorithm considers:

  • Purchase frequency - how often items are bought together
  • Recency - only the last (rolling) 6 months of purchases are ever considered
  • Recommendation Threshold - how often a product must have been bought with another in order to be considered worthy of recommendation
  • Product availability - excludes out-of-stock items automatically

Implementation

Adding to Product Detail Pages

📘

The following examples are provided for illustration purposes only. You may need to adjust them to better suit your own Store's look and feel.

To display co-purchase recommendations on your product pages, you may add the following to your product template:

{product_list type_list=generated product_id=$product.id product_list_type=copurchases recommendations="copurchases"}
    {if $copurchases}
    <div id="details_upsells" class="details_productlist_container">
    <h2>{site_text page="Product Details" part="Title: Also Bought" default="Others also bought"}</h2>
        <div class="details_productlist">
        {foreach from = $copurchases item=related}
            <div class="details_productlist_item quicklook_container">
            <div class="details_productlist_image">
                <a href="{if $locale_code}/{$locale_code}{/if}{$related.product_filename}">
                    <img src="{product_image_uri product=$related width=320 height=320}" width="160" height="160" alt="{$related.product_name}" />
                        </a>
                    </div>
                <div class="details_productlist_quicklookbutton quicklook_button">
                <p><a href="#" class="template_button quicklook" rel="{$related.id}">{site_text page="Global" part="Link: Quick Look" }</a></p>
                    </div>
                <div class="clear"></div>
                <h2><a href="{if $locale_code}/{$locale_code}{/if}{$related.product_filename}">{$related.product_name}</a></h2>

{if $related.my_price_rrp > $related.my_price}
                <p><span class="details_productlist_rrp"><span class="strikethrough">{$related.my_price_rrp|displayPrice}</span></span>&nbsp;<span class="details_productlist_price_now"> {$related.my_price|displayPrice}</span></p>
                {else}
                <p>
                <span class="details_productlist_price">{$related.my_price|displayPrice}</span>
                    </p>
                {/if}
                    <div class="clear"></div>
                </div>
            {/foreach}
            <div style="min-width: 1px;"></div>
            </ul>
            <div class="clear"></div>
            </div>
        </div>
    {/if}

Adding to Shopping Basket

For basket recommendations, implement a more detailed template that includes quick-add functionality:

{product_list type_list=generated product_id=$basket_item.product.id product_list_type=copurchases recommendations="copurchases"}
{if $copurchases}
<div class="basket_recommendations_container">
    <div class="basket_recommendations_title">
        {site_text page="Basket" part="Title: Line Item - Have you considered" 
            default="Have you considered..."}
    </div>
    <div class="basket_recommendations_products">
        {foreach from=$copurchases item=related name=copurchase}
        {if $smarty.foreach.copurchase.index < 3}
        <div class="basket_recommendation_item">
            <!-- Product image -->
            <a href="{if $locale_code}/{$locale_code}{/if}{$related.product_filename}" 
               class="basket_recommendation_link">
                <div class="basket_recommendation_image">
                    <img src="{product_image_uri product=$related width=60 height=60}" 
                         alt="{$related.product_name}" />
                </div>
            </a>
            
            <!-- Product details and add to basket form -->
            <div class="basket_recommendation_details">
                <form action="{if $locale_code}/{$locale_code}{/if}/basket" 
                      method="post" class="basket_rec_form">
                    <h4 class="basket_recommendation_name">
                        {$related.product_name|truncate:50:"..."}
                    </h4>
                    
                    <!-- Pricing -->
                    <p class="basket_recommendation_price">
                        {if $related.my_price_rrp > $related.my_price}
                        <span class="price_was">{$related.my_price_rrp|displayPrice}</span>
                        <span class="price_now">{$related.my_price|displayPrice}</span>
                        {else}
                        <span class="price_now">{$related.my_price|displayPrice}</span>
                        {/if}
                    </p>
                    
                    <!-- Variations if applicable -->
                    {if $related.attributes}
                    <div class="basket_recommendation_variations">
                        {include file="products/attributes.tpl.html" 
                            attributes=$related.attributes 
                            type="basket_rec" 
                            product_id=$related.id}
                    </div>
                    {/if}
                    
                    <!-- Quantity and Add button -->
                    <div class="basket_recommendation_actions">
                        <div class="basket_rec_quantity_row">
                            <label class="basket_rec_qty_label">Qty:</label>
                            <select name="product_quantity" class="basket_rec_quantity">
                                {section loop=10 name="qty"}
                                <option value="{$smarty.section.qty.iteration}">
                                    {$smarty.section.qty.iteration}
                                </option>
                                {/section}
                            </select>
                        </div>
                        <input type="submit" value="Add to Basket" 
                               class="basket_rec_add_button" />
                        <input type="hidden" name="product_id" value="{$related.id}" />
                    </div>
                </form>
            </div>
        </div>
        {/if}
        {/foreach}
    </div>
</div>
{/if}