I found the idea on this forum post

Using Debut theme v16.5.5 and free metafieds editor app , I figured out a way to do the same.

I have created two demo products. 1. Abbey Road (Album) and 2. Here comes the sun (Song) . So if product 2 is in the cart, the cart should prompt an upgrade option to the user.

The following metafield {{ product.metafields.parent.bundle }} will connect both products using product handle . In this case, i’m creating a metafield for product 2 which will be handle of product 1, ie abbey-road-album

Solution

Create a snippet upgrade-to-bundle.liquid and render it with product and line_item as variables inside cart-template.liquid

{% render 'upgrade-to-bundle', product: item.product, line_item: item %}

And below is the code for upgrade-to-bundle.liquid , where it checks the product metafield and assigns the bundle variant to the upgrade link.


{%- liquid
 	if product.metafields.parent.bundle !=  nil
	 assign hasBundle = 'true'
	 assign productBundle = all_products[product.metafields.parent.bundle]
	endif
-%}
{% if hasBundle == 'true' and productBundle.title!= nil %}

<a href="#" id="upgrade-action" 
   data-variant-id="{{ line_item.variant_id  }}" 
   data-bundle-id="{{productBundle.selected_or_first_available_variant.id}}">

  <small> Would you like a upgrade to {{productBundle.title}} - {{ productBundle.price | money}} ? </small>
  
</a>

{%endif%}

And using AJAX API update the cart with javascript as in Creating an Upsell feature without using an app


$(document).on('click','#upgrade-action', function(){
  $(this).attr('disabled','disabled')
  var bundle = $(this).attr('data-bundle-id')
  var variant = $(this).attr('data-variant-id')
 
  jQuery.ajax({
    type: 'POST',
    url: '/cart/update.js', 
    data: 'updates['+bundle+']=1&updates['+variant+']=0', 
    dataType: 'json',
    success: function() { location.href = '/cart/'; },
    error: function(err) { console.log(err.responseText)}
  });

})


working demo