Let’s learn about WooCommerce Downsell & how it can boost Conversions with smart product swaps
In eCommerce, upselling often gets all the attention—but downselling is an underrated tactic that can recover lost sales and engage price-sensitive shoppers. With WooCommerce, we can build a simple but powerful downsell mechanism using PHP and AJAX.
Let’s walk through what it is, why it works, and how to build it with code.
What Is Downselling?
Downselling is the practice of offering a cheaper alternative when a customer hesitates or removes a product from their cart.
In WooCommerce, we can display lower-priced alternatives right inside the cart page—and let customers swap with a click.
How to Add a Downsell Swap Feature to Your WooCommerce Cart Page
Let’s build a feature that:
- Shows cheaper product alternatives for each cart item.
- Lets users swap products using AJAX without refreshing the page.
1. PHP: Inject Downsell Options into Cart Items
Place this in your theme’s functions.php
or a custom plugin:
add_action('woocommerce_after_cart_item_name', function($cart_item, $cart_item_key) {
$product_id = $cart_item['product_id'];
$product = wc_get_product($product_id);
$price = $product->get_price();
// Get product categories
$terms = get_the_terms($product_id, 'product_cat');
if (empty($terms) || is_wp_error($terms)) return;
$term_ids = wp_list_pluck($terms, 'term_id');
// Query cheaper products in the same category
$args = [
'post_type' => 'product',
'posts_per_page' => 3,
'post__not_in' => [$product_id],
'meta_query' => [[
'key' => '_price',
'value' => $price,
'compare' => '<',
'type' => 'NUMERIC'
]],
'tax_query' => [[
'taxonomy' => 'product_cat',
'field' => 'term_id',
'terms' => $term_ids
]]
];
$query = new WP_Query($args);
if (!$query->have_posts()) return;
echo '<div class="downsell-products">';
echo '<strong>Cheaper alternatives:</strong>';
foreach ($query->posts as $alt_post) {
$alt_id = $alt_post->ID;
$alt_product = wc_get_product($alt_id);
$alt_price = wc_price($alt_product->get_price());
$savings = wc_price($price - $alt_product->get_price());
echo "<button
class='swap-product-btn'
data-original='{$product_id}'
data-alt='{$alt_id}'
data-key='{$cart_item_key}'>
Swap with <strong>{$alt_post->post_title}</strong> ($alt_price - Save $savings)
</button>";
}
echo '</div>';
}, 10, 2);
2. JS: Handle Product Swaps via AJAX
Enqueue this JavaScript and make sure it runs only on the cart page:
add_action('wp_enqueue_scripts', function() {
if (is_cart()) {
wp_enqueue_script('downsell-swap', plugin_dir_url(__FILE__) . 'swap.js', ['jquery'], null, true);
wp_localize_script('downsell-swap', 'DownsellData', [
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('swap_nonce'),
]);
}
});
Then create swap.js
:
jQuery(document).ready(function($) {
$('.swap-product-btn').on('click', function(e) {
e.preventDefault();
const btn = $(this);
const original_id = btn.data('original');
const alt_id = btn.data('alt');
const cart_item_key = btn.data('key');
btn.prop('disabled', true).text('Swapping...');
$.post(DownsellData.ajax_url, {
action: 'swap_cart_item',
nonce: DownsellData.nonce,
cart_item_key,
original_id,
alt_id,
}, function(response) {
if (response.success) {
location.reload(); // Refresh cart
} else {
alert('Swap failed: ' + response.data);
btn.prop('disabled', false).text('Try again');
}
});
});
});
3. PHP: AJAX Handler for Product Swap
Add this in your plugin or functions file:
add_action('wp_ajax_swap_cart_item', 'handle_cart_item_swap');
add_action('wp_ajax_nopriv_swap_cart_item', 'handle_cart_item_swap');
function handle_cart_item_swap() {
check_ajax_referer('swap_nonce', 'nonce');
$key = sanitize_text_field($_POST['cart_item_key']);
$original = intval($_POST['original_id']);
$alt = intval($_POST['alt_id']);
if (!WC()->cart->remove_cart_item($key)) {
wp_send_json_error('Could not remove original product');
}
$exists = false;
foreach (WC()->cart->get_cart() as $item_key => $item) {
if ($item['product_id'] == $alt) {
WC()->cart->set_quantity($item_key, $item['quantity'] + 1);
$exists = true;
break;
}
}
if (!$exists) {
WC()->cart->add_to_cart($alt);
}
wp_send_json_success('Cart updated');
}
Result: A Dynamic, User-Friendly Downsell Experience
- 🧲 Suggests cheaper products in real-time.
- ⚡ Users swap items without reloading the page.
- 📉 Increases chances of checkout from hesitant buyers.
Final Thoughts
Smart downselling creates value for both you and your customers. It’s not about selling less—it’s about closing more sales.
With this WooCommerce downsell setup, you give your customers a helpful nudge—at the perfect time.
Want This as a Plugin?
We’re packaging this as a ready-to-use plugin. Download it now.
Leave a Reply