Skip to main content

Feature & Code - Remove Item from Cart after Booking set to Cancelled

Hey all,

I had a real issue with fluenbooking. A student of mine would start the process of booking a lesson, he finished with the fluent booking form but after being redirected to the checkout page he wandered off for an hour. In the meantime - the booking was automatically cancelled after 10 minutes (as it should). But the student came back and completed the transaction! Now the booking cannot be marked as complete (and maybe even someone else took that slot in the meantime).

What's the solution? To remove the booking product from the cart after the X time set when the booking is cancelled. I wrote a code snippet for this and it works great. With regards to UX - we should add a note for the user so he'll know that the item was removed and to offer him to book again.

Shahjahan JewelΒ - I suggest you add this as a feature built-in to FluentBooking.

Here is the code:

(you need to change the booking_products array to match your woocommerce products that are attached to the booking; Also you can modify the time after which the products will be removed - if it's not set to 10 minutes in fluentbooking)

`add_action('woocommerce_add_to_cart', 'set_booking_cart_timestamp');`
`function set_booking_cart_timestamp($cart_item_key) {`
`if (!WC()->cart) return;`
`$cart_item = WC()->cart->get_cart_item($cart_item_key);`
`$product_id = $cart_item['product_id'];`
`$booking_products = [69653, 69646, 62528, 16820];`
`if (in_array($product_id, $booking_products)) {`
`WC()->session->set('booking_cart_timestamp_' . $cart_item_key, time());`
`}`
`}`

`add_action('wp_footer', 'expire_booking_cart_items_script');````function expire_booking_cart_items_script() {````if (!is_checkout()) return;````$booking_products = [69653, 69646, 62528, 16820];````$cart = WC()->cart->get_cart();````$cart_data = [];````foreach ($cart as $cart_item_key => $cart_item) {````if (in_array($cart_item['product_id'], $booking_products)) {````$timestamp = WC()->session->get('booking_cart_timestamp_' . $cart_item_key);````if ($timestamp) {````$cart_data[] = [````'key' => $cart_item_key,````'timestamp' => $timestamp,````'product_id' => $cart_item['product_id'],````];````}````}````}````if (empty($cart_data)) return;````?>````(function(){````const cartData = ` ```;````const expirationTime = 10 * 60 * 1000; // 10 minutes`

    cartData.forEach(item => {
        const timePassed = Date.now() - (item.timestamp * 1000);
        const timeLeft = expirationTime - timePassed;

        if (timeLeft <= 0) {
            removeItem(item.key, item.product_id);
        } else {
            setTimeout(() => {
                removeItem(item.key, item.product_id);
            }, timeLeft);
        }
    });

    function removeItem(cart_item_key, product_id) {
        const formData = new FormData();
        formData.append('action', 'remove_expired_booking_item');
        formData.append('cart_item_key', cart_item_key);
        formData.append('security', '<?php echo wp_create_nonce("remove_booking_item"); ?>');

        fetch('<?php echo admin_url('admin-ajax.php'); ?>', {
            method: 'POST',
            body: formData
        })
        .then(res => res.json())
        .then(response => {
            if (response.success) {
                location.reload();
            }
        })
        .catch(err => {
            location.reload();
        });
    }
})();
</script>
<?php
}

add_action('wp_ajax_remove_expired_booking_item', 'remove_expired_booking_item');
add_action('wp_ajax_nopriv_remove_expired_booking_item', 'remove_expired_booking_item');
function remove_expired_booking_item() {
// Verify nonce for security
if (!wp_verify_nonce($_POST\['security'], 'remove_booking_item')) {
wp_send_json_error('Security check failed');
}
```
if (!WC()->cart || !isset($_POST['cart_item_key'])) {
    wp_send_json_error('Missing cart data');
}

$cart_item_key = sanitize_text_field($_POST['cart_item_key']);
$booking_products = [69653, 69646, 62528, 16820];
$cart = WC()->cart->get_cart();

if (!isset($cart[$cart_item_key])) {
    wp_send_json_error('Cart item not found');
}

$product_id = $cart[$cart_item_key]['product_id'];
if (!in_array($product_id, $booking_products)) {
    wp_send_json_error('Not a booking product');
}

// Check if item has actually expired server-side
$timestamp = WC()->session->get('booking_cart_timestamp_' . $cart_item_key);
if ($timestamp && (time() - $timestamp) < 600) { // 10 minutes = 600 seconds
    wp_send_json_error('Item not yet expired');
}

$removed = WC()->cart->remove_cart_item($cart_item_key);
WC()->session->__unset('booking_cart_timestamp_' . $cart_item_key);

// For logged-in users, we need to update the persistent cart in the database
if (is_user_logged_in()) {
    WC()->cart->persistent_cart_update();

    // Also manually update the user meta to make sure it's saved
    $user_id = get_current_user_id();
    $cart_data = WC()->cart->get_cart_for_session();
    update_user_meta($user_id, '_woocommerce_persistent_cart_' . get_current_blog_id(), array(
        'cart' => $cart_data,
    ));
}

// Force save session data
WC()->session->save_data();

if ($removed) {
    wp_send_json_success('Booking product removed');
} else {
    wp_send_json_error('Failed to remove cart item');
}
```

}