The goal is simple, add a checkbox to the WooCommerce Product Page. If the user checks the checkbox, a 5% discount is applied on cart subtotal.
I have checked and doubled checked the code like ten times, I just cannot figure out why it gives me the "Fatal Error
".
This is the code:
add_action( 'woocommerce_after_add_to_cart_button', 'ls_automatic_discount_checbox', 10 );
function ls_automatic_discount_checbox() {
echo '<p><label><input type="checkbox" name="apply_automatic_discount" value="1"/> Apply 5% discount to your subtotal</label></p>';
}
add_action( 'woocommerce_cart_calculate_fees', 'ls_apply_discount_on_checkbox_check', 10, 7 );
function ls_apply_discount_on_checkbox_check( $cart, $cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data ) {
// makes sure that the checkbox is ticked
if ( isset( $_POST[ 'apply_automatic_discount' ] ) && $_POST[ 'apply_automatic_discount' ] == 1 ) {
// if it is, check what the percentaged discount on the subtotal is
$percent = 5;
// if all checks out - give the discount
if ( isset ( $percent ) && $percent > 0 ) {
// customer gets a discount of 5% of the SUBTOTAL
$discount = $cart->cart_contents_total * $percent / 100;
$cart->add_fee( __('5% OFF', 'woocommerce' ) . " (" . $percent . "%)", -$discount);
}
}
}
There are some missing things and mistakes in your code:
woocommerce_cart_calculate_fees
has only one argument: $cart
(the WC_Cart object). That was the main error issue.woocommerce_after_add_to_cart_button
hook (that displays the checkbox after add to cart button) with woocommerce_before_add_to_cart_button
, to display the checkbox before, which is more logical.The code:
add_action( 'woocommerce_after_add_to_cart_button', 'ls_automatic_discount_checbox', 10 );
function ls_automatic_discount_checbox() {
printf( '<p class="auto-discount"><label><input type="checkbox" name="auto_discount" value="1"/> %s</label></p>',
__('Apply 5% discount to your subtotal', 'woocommerce') );
}
// Add custom cart item data
add_filter('woocommerce_add_cart_item_data', 'add_custom_field_value_to_cart_item_data', 10, 2);
function add_custom_field_value_to_cart_item_data($cart_item_data, $product_id) {
$cart_item_data['auto_discount'] = isset($_POST['auto_discount']) ? '1' : '0';
return $cart_item_data;
}
Now you can add a discount globally or by product (where the checkbox has been checked):
A/. Globally (on the cart subtotal):
add_action( 'woocommerce_cart_calculate_fees', 'auto_applied_product_discount', 10 );
function auto_applied_product_discount( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$auto_discount = false; // Initializing
// Loop through cart items
foreach ( $cart->get_cart() as $cart_item ) {
if ( isset($cart_item['auto_discount']) && $cart_item['auto_discount'] ) {
$auto_discount = true;
break; // Stop the loop
}
}
if ( $auto_discount ) {
$percent = 5;
$total = $cart->cart_contents_total;
$cart->add_fee( __('5% OFF', 'woocommerce' ) . " (" . $percent . "%)", -($total * $percent / 100));
}
}
B/. By product subtotal (where the checkbox has been checked):
add_action( 'woocommerce_cart_calculate_fees', 'auto_applied_product_discount', 10 );
function auto_applied_product_discount( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$total = 0; // Initializing
// Loop through cart items
foreach ( $cart->get_cart() as $cart_item ) {
if ( isset($cart_item['auto_discount']) && $cart_item['auto_discount'] ) {
$total += $cart_item['line_total'];
}
}
if ( $total > 0 ) {
$percent = 5;
$cart->add_fee( __('5% OFF', 'woocommerce' ) . " (" . $percent . "%)", -($total * $percent / 100));
}
}
Code goes in functions.php file of your child theme (or in a plugin). Tested and works.