Membership Cart Drawer Upsell with Dynamically Calculated Cashback: Implementation Guide
This is an advanced theme customization meant for developers that not is supported by the Inveterate team. You should ensure you have the appropriate development resources to implement before proceeding.
Functionality can vary theme-by-theme and some small adjustments may be required.
File Structure
snippets/membership-upsell.liquid
Renders the upsell block inside the cart drawer
assets/membership-upsell.js
Handles AJAX add-to-cart and drawer refresh
Step 1: Create the Snippet
In the Snippets folder of your theme, create a new file called membership-upsell.liquid
Then, paste the following code:
{%- comment -%}
Adjust this percentage to reflect your actual cashback offer.
{%- endcomment -%}
{% assign cashback_percentage = 20 %}
{% assign cashback_amount = cart.total_price | times: cashback_percentage | divided_by: 100 %}
<div class="drawer-membership-upsell">
<h3 class="drawer-upsell-heading">Become a Member</h3>
<p class="drawer-upsell-subheading">Join now to unlock your benefits</p>
<ul class="drawer-benefits">
{%- comment -%}
Customize the list of membership benefits below to reflect your actual offering.
These items are placeholder examples — replace them with your own benefits.
{%- endcomment -%}
<li>
<strong>{{ cashback_percentage }}% Cashback</strong>
{% if cart.item_count > 0 %}
<span class="drawer-cashback-amount">
({{ cashback_amount | money }} on today's order!)
</span>
{% endif %}
</li>
<li>Free Shipping</li>
<li>Exclusive Product Access</li>
<li>Member-Only Discounts</li>
<li>$10 Birthday Credit</li>
<li>Priority Support</li>
</ul>
<button
class="drawer-upsell-button"
data-membership-variant="REPLACE_WITH_VARIANT_ID" <!-- Replace with your membership product's variant ID -->
data-membership-selling-plan="REPLACE_WITH_SELLING_PLAN_ID"> <!-- Replace with your selling plan ID -->
Join Now for $10 Annually! <!-- Replace with your price & CTA -->
</button>
</div>
{%- comment -%}
Ensure this script is included so the JS functionality is loaded when the snippet renders.
{%- endcomment -%}
<script type="module" src="{{ 'membership-upsell.js' | asset_url }}"></script>
Ensure that you replace all of the placeholder content in the code snippet (Cashback %, Benefits, Variant ID, Selling Plan ID, Price and CTA) with those that are relevant & specific to your program.
Step 2: Create the JavaScript File
In the assets folder of your theme, create a new file called membership-upsell.js
Then, paste the following code:
document.addEventListener('click', async (event) => {
const btn = event.target.closest('.drawer-upsell-button');
if (!btn || btn.disabled) return;
const variantId = parseInt(btn.dataset.membershipVariant);
const sellingPlanId = parseInt(btn.dataset.membershipSellingPlan);
const payload = {
items: [{
id: variantId,
quantity: 1
}]
};
if (!isNaN(sellingPlanId)) {
payload.items[0].selling_plan = sellingPlanId;
}
btn.disabled = true;
const originalText = btn.textContent;
btn.textContent = 'Adding...';
try {
const res = await fetch('/cart/add.js', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify(payload)
});
if (!res.ok) throw new Error('Cart add failed');
const cart = await fetch('/cart.js').then(r => r.json());
const exists = cart.items.find(item => item.variant_id === variantId);
if (!exists) throw new Error('Membership not found in cart');
btn.textContent = 'Added!';
const upsell = btn.closest('.drawer-membership-upsell');
if (upsell) setTimeout(() => upsell.remove(), 400);
const drawerRes = await fetch(window.location.pathname + '?sections=cart-drawer');
const html = await drawerRes.text();
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
const newDrawer = doc.querySelector('.cart-drawer');
const currentDrawer = document.querySelector('.cart-drawer');
if (newDrawer && currentDrawer) {
currentDrawer.innerHTML = newDrawer.innerHTML;
}
} catch (err) {
console.error('[Membership Upsell Error]', err);
btn.textContent = 'Error';
alert('Could not add membership.');
}
setTimeout(() => {
btn.textContent = originalText;
btn.disabled = false;
}, 2000);
});
Step 3: Add the Snippet to the Cart Drawer
In your theme’s code editor open the file: snippets/cart-drawer.liquid
Find this section of the code:
<scroll-hint class="cart-drawer__items">
{% render 'cart-products' %}
</scroll-hint>
<div class="cart-drawer__summary">
{% render 'cart-summary' %}
</div>
The exact location of the cart summary block can vary slightly theme by theme.
Insert the upsell snippet above the cart summary block, like so:
<scroll-hint class="cart-drawer__items">
{% render 'cart-products' %}
</scroll-hint>
<div class="cart-drawer__summary">
{% render 'cart-summary' %}
</div>
Step 4: Style with CSS
Add this to your main stylesheet (theme.css, base.css, or equivalent), or inline within the snippet, and customize to your branding needs. All current values are placeholders and should be replaced to match your branding needs:
.drawer-membership-upsell {
background: #f5f0ff;
padding: 16px;
margin: 16px 0;
border-radius: 6px;
font-size: 14px;
}
.drawer-upsell-heading {
font-size: 16px;
font-weight: 600;
}
.drawer-upsell-subheading {
font-size: 13px;
margin-bottom: 10px;
color: #666;
}
.drawer-benefits {
list-style: none;
padding: 0;
margin: 0 0 12px;
}
.drawer-upsell-button {
width: 100%;
background: #7b3fdb;
color: white;
padding: 10px 0;
border-radius: 4px;
font-weight: 600;
border: none;
cursor: pointer;
}
.drawer-upsell-button:hover {
background: #5f2bbb;
}
.drawer-cashback-amount {
font-weight: 600;
color: #7b3fdb;
margin-left: 4px;
}
Once all of the above is implemented & styled, your cart upsell will appear in the cart drawer - visually looking similar to this - but matching the CSS styling that you have adjusted to match your needs:

Functionally, the cart upsell will automatically calculate the cashback amount based on your cart total & the percentage you have defined in the snippet (note: this implementation assumes that you provide credits for orders/cashback on all products). The cart upsell will be present if a membership product has not been added to cart. If the membership product has been added to cart, the upsell will no longer be visible.
Last updated
Was this helpful?