alegjos alegjos - 2 months ago 36
PHP Question

Check if a customer has purchased a specific product earlier in WooCommerce

I need to check if a customer has purchased a specific product earlier in WooCommerce.

The case is this: The customer shall not be able to purchase product "c", "d", "e" unless they have purchased product "a" or "b" at an earlier time.

If the customer has purchased product "a" or "b" earlier, then the purchase button of product "c", "d" and "e" is activated and they are allowed to buy them.

If they haven´t purchased "a" or "b" earlier, they will not be allowed to purchase "c", "d", "e" and the purchase button is deactivated.

How can I achieve this?



Yes it's possible, writing a conditional function that returns "true" if current customer has already bought specifics defined products IDs. This code goes on function.php file of your active child theme or theme.

Here is the conditional function:

function is_bought_items() {

    $bought = false;

    // setting the IDs of specific products that are needed to be bought by the customer
    // => Replace the example numbers by your specific product IDs
    $prod_arr = array( '21', '67' );

    // Get all customer orders
    $customer_orders = get_posts( array(
        'numberposts' => -1,
        'meta_key'    => '_customer_user',
        'meta_value'  => get_current_user_id(),
        'post_type'   => 'shop_order', // WC orders post type
        'post_status' => 'wc-completed' // Only orders with status "completed"
    ) );

    // Going through each current customer orders
    foreach ( $customer_orders as $customer_order ) {
        $order = wc_get_order( $customer_order );
        // $order_id = $order->id;

        // Going through each current customer products bought in the order
        foreach ($items as $item) {

            // Your condition related to your 2 specific products Ids
            if ( in_array( $item['product_id'], $prod_arr ) ) {

                $bought = true; // Corrected mistake in variable name

    // return "true" if one the specifics products have been bought before by customer
    if ( $bought ) {
        return true;

This code is tested and works.

For example, you can use it in some WooCommerce templates that you will have previously copied to your active child theme or theme:

Here is an example that you could use in those templates (above):

// Replace the numbers by your special restricted products IDs
$restricted_products = array( '20', '32', '75' );

// customer has NOT already bought a specific product for this restricted products
if ( !is_bought_items() && in_array( $product->id, $restricted_products ) ) { 

    // Displaying an INACTIVE add-to-cart button (With a custom text, style and without the link).
    // (AND optionally) an explicit message for example.

} else { 

    // place for normal Add-To-Cart button code here

And here the complete applied example to add-to-cart button template on Shop page:

 * Loop Add to Cart
 * This template can be overridden by copying it to yourtheme/woocommerce/loop/add-to-cart.php.
 * HOWEVER, on occasion WooCommerce will need to update template files and you
 * (the theme developer) will need to copy the new files to your theme to
 * maintain compatibility. We try to do this as little as possible, but it does
 * happen. When this occurs the version of the template file will be bumped and
 * the readme will list any important changes.
 * @see
 * @author      WooThemes
 * @package     WooCommerce/Templates
 * @version     2.5.0

if ( ! defined( 'ABSPATH' ) ) {

global $product;

// Replace the numbers by your special restricted products IDs
$restricted_products = array( '37', '53', '70' );

if ( !is_bought_items() && in_array( $product->id, $restricted_products ) ) {

    echo '<a class="button greyed_button">' . __("Disabled", "your_theme_slug") . '</a>';
    echo '<br><span class="greyed_button-message">' . __("Your message goes here…", "your_theme_slug") . '</span>';

} else {

echo apply_filters( 'woocommerce_loop_add_to_cart_link',
    sprintf( '<a rel="nofollow" href="%s" data-quantity="%s" data-product_id="%s" data-product_sku="%s" class="%s">%s</a>',
        esc_url( $product->add_to_cart_url() ),
        esc_attr( isset( $quantity ) ? $quantity : 1 ),
        esc_attr( $product->id ),
        esc_attr( $product->get_sku() ),
        esc_attr( isset( $class ) ? $class : 'button' ),
        esc_html( $product->add_to_cart_text() )
$product );


You will style the inactive button with greyed_button class in the style.css file of your active child theme or theme. Same thing for the message with greyed_button-message class.