Order bumps are a powerful way to increase your average order value by offering relevant products to customers at the checkout. WooCommerce, one of the most popular eCommerce platforms, allows you to implement custom features like order bumps easily. In this guide, we’ll walk you through building a Dynamic Order Bump for WooCommerce, utilizing both PHP and JavaScript to create a seamless experience that adapts based on dynamic conditions such as cart total and item count.
What is an Order Bump?
An Order Bump is a special offer presented during the checkout process. It typically appears just before the final payment stage and encourages the customer to add an additional product to their cart, often at a discounted price. This is a great way to increase your store’s revenue without disrupting the user experience.
Step 1: Setting Up the Plugin
We will create a plugin that adds a dynamic order bumps for WooCommerce store. To begin, we’ll define the structure and functionality of the plugin in PHP and include necessary JavaScript for dynamic interactions.
1.1 Create the Plugin Files
Create a folder named dynamic-order-bump
inside your wp-content/plugins/
directory. Inside this folder, create the following files:
dynamic-order-bump.php
: Main plugin file.assets/order-bump.js
: JavaScript for handling the dynamic behavior.assets/order-bump.css
: Optional CSS for styling the order bump.
1.2 PHP Code: Building the Core Plugin
The main purpose of the PHP file is to handle the backend logic of the order bump. It will dynamically fetch products based on cart conditions, handle AJAX requests, and insert the necessary hooks into WooCommerce’s checkout page.
Plugin Header
/**
* Plugin Name: Dynamic Order Bump with Conditions
* Description: Display dynamic order bump products on the checkout page with AJAX updates and complex conditions.
* Version: 1.0
* Author: Kishores
*/
This block defines the basic information about your plugin, like its name, description, version, and author.
Product Display Conditions Interface
We need to define the conditions under which an order bump product should be shown. For this, we create an interface and some classes to handle different types of conditions.
interface ProductDisplayCondition {
public function isSatisfied(): bool;
}
This ProductDisplayCondition
interface is the blueprint for all conditions (like cart total, item count, or user login status). Any class implementing this interface should define the isSatisfied()
method, which returns true
or false
based on whether the condition is met.
CartTotalCondition Class
class CartTotalCondition implements ProductDisplayCondition {
private $minimumCartTotal;
public function __construct($minimumCartTotal) {
$this->minimumCartTotal = $minimumCartTotal;
}
public function isSatisfied(): bool {
$cartTotal = WC()->cart->get_cart_contents_total();
return $cartTotal >= $this->minimumCartTotal;
}
}
This class checks if the cart total exceeds a specified threshold (e.g., 500). If the cart total is sufficient, the order bump can be shown.
CartItemCountCondition Class
class CartItemCountCondition implements ProductDisplayCondition {
private $minimumItems;
public function __construct($minimumItems) {
$this->minimumItems = $minimumItems;
}
public function isSatisfied(): bool {
$cartItemCount = WC()->cart->get_cart_contents_count();
return $cartItemCount >= $this->minimumItems;
}
}
Similarly, this condition checks if the cart has a minimum number of items (e.g., 2 items). If so, the order bump will be displayed.
CompositeCondition Class
We also need a way to combine multiple conditions, allowing for more complex logic (e.g., show the order bump if either the cart total is high or the item count is sufficient). The CompositeCondition
class handles this.
class CompositeCondition implements ProductDisplayCondition {
private $conditions = [];
private $logic = 'AND';
public function setLogic($logic) {
$this->logic = $logic;
}
public function addCondition(ProductDisplayCondition $condition) {
$this->conditions[] = $condition;
}
public function isSatisfied(): bool {
if ($this->logic === 'OR') {
foreach ($this->conditions as $condition) {
if ($condition->isSatisfied()) {
return true;
}
}
return false;
} else {
foreach ($this->conditions as $condition) {
if (!$condition->isSatisfied()) {
return false;
}
}
return true;
}
}
}
With this class, you can use an “AND” or “OR” logic to combine different conditions. For example, if you want the order bump to appear only when both the cart total is over 500 and the item count is greater than 2, you can set the logic to AND
. If you want to show it if either condition is met, you can set it to OR
.
ConditionProvider Class
The ConditionProvider
class is used to collect and provide all the conditions for showing the order bump. It dynamically adds conditions and allows for modifications via WordPress filters.
class ConditionProvider {
public function getConditions(): array {
$conditions = apply_filters('dynamic_order_bump_conditions', [
new CartTotalCondition(500),
new CartItemCountCondition(2),
]);
return $conditions;
}
}
By using the apply_filters
function, we allow other developers to hook into this logic and add custom conditions.
1.3 Enqueuing Scripts and AJAX Integration
For the order bump to work dynamically, we’ll need some JavaScript to handle the user interactions and AJAX calls.
class DynamicOrderBump {
public $order_bump_position_hook = 'woocommerce_checkout_before_order_review';
public function __construct() {
add_action('wp_enqueue_scripts', [$this, 'enqueue_scripts']);
add_action($this->order_bump_position_hook, [$this, 'display_order_bump_section'], 20);
add_action('wp_ajax_get_order_bump_products', [$this, 'get_order_bump_products']);
add_action('wp_ajax_nopriv_get_order_bump_products', [$this, 'get_order_bump_products']);
}
public function enqueue_scripts() {
if (is_checkout()) {
wp_enqueue_script('order-bump-script', plugin_dir_url(__FILE__) . 'assets/order-bump.js', ['jquery'], '1.0', true);
wp_localize_script('order-bump-script', 'orderBumpConfig', [
'ajaxUrl' => admin_url('admin-ajax.php'),
'currencySymbol' => get_woocommerce_currency_symbol(),
]);
}
}
public function display_order_bump_section() {
echo '<div id="order-bump-products">Loading order bump products...</div>';
}
public function get_order_bump_products() {
// Fetch order bump products based on dynamic conditions
}
}
new DynamicOrderBump();
In this code:
- We hook into the WooCommerce checkout page to display the order bump.
- We enqueue the necessary JavaScript for the frontend interaction.
- AJAX endpoints are created to fetch the order bump products and handle user actions like adding products to the cart.
Step 2: Adding the JavaScript for Dynamic Behavior
The JavaScript file (order-bump.js
) handles fetching and displaying the order bump products, updating the UI, and adding products to the cart through AJAX.
2.1 Fetching Order Bump Products
document.addEventListener("DOMContentLoaded", () => {
const orderBumpContainer = document.getElementById("order-bump-products");
let excludedProducts = []; // Products already added to cart
const fetchOrderBumpProducts = () => {
showLoadingSpinner();
fetch(`${orderBumpConfig.ajaxUrl}?action=get_order_bump_products`, {
method: "GET",
headers: { "Content-Type": "application/json" },
})
.then((response) => response.json())
.then((data) => {
if (data.success) {
const filteredProducts = data.data.filter(
(product) => !excludedProducts.includes(product.id.toString())
);
renderOrderBumpProducts(filteredProducts);
} else {
showError("No products available for the order bump.");
}
})
.catch(() => {
console.error("Error fetching order bump products.");
showError();
});
};
});
This JavaScript function fetches available order bump products from the server and filters out products that have already been added to the cart.
2.2 Displaying Products
const renderOrderBumpProducts = (products) => {
orderBumpContainer.innerHTML = "";
products.forEach((product) => {
const productElement = document.createElement("div");
productElement.className = "order-bump-product";
productElement.innerHTML = `
<p>${product.name} - ${orderBumpConfig.currencySymbol}${product.price}</p>
<button data-product-id="${product.id}">Add to Cart</button>
`;
orderBumpContainer.appendChild(productElement);
productElement.querySelector("button").addEventListener("click", (event) => {
addProductToCart(event.target.dataset.productId);
});
});
};
This function dynamically generates HTML for each product and attaches an event listener to the “Add to Cart” button.
2.3 Adding Product to Cart
const addProductToCart = (productId) => {
fetch(`${orderBumpConfig.ajaxUrl}?action=add_product_to_cart&product_id=${productId}`, {
method: "POST",
body: JSON.stringify({ productId }),
headers: {
"Content-Type": "application/json",
},
})
.then((response) => response.json())
.then((data) => {
if (data.success) {
alert("Product added to cart successfully.");
} else {
alert("Failed to add product to cart.");
}
});
};
This function handles adding a product to the cart when the user clicks the “Add to Cart” button.
You can find the complete code here.
Conclusion
By following these steps, you can implement a Dynamic Order Bump for your WooCommerce store. This solution allows you to present relevant products to customers based on conditions like cart total or item count, all while providing a smooth and seamless experience using AJAX and dynamic updates.
This approach increases your revenue potential by showing offers to customers when they’re most likely to add extra products to their cart, improving both the user experience and the profitability of your store.
Leave a Reply