Woocommerce: Users able to buy a product only once

What can I add to the functions.php file of my theme that would make it so that users could only buy a product once? As in if they have ever bought any product in the store before, they are prevented from purchasing it again.

I imagine the code would look something like this (pseudo code) and would use the woocommerce_add_cart_item_data filter.

add_filter( 'woocommerce_add_cart_item_data', 'woo_check_not_bought_before' );

function woo_check_not_bought_before( $cart_item_data ) {

    global $woocommerce;

    // Some MYSQL to check if product was bought before

    if ($bought_before == 'true') {       
         $woocommerce->cart->empty_cart();
    }

    // Echo some text to explain why you can only buy the product once

    return $cart_item_data;
}

Related posts

Leave a Reply

3 comments

  1. here’s a simple solution.

    add_filter('woocommerce_add_to_cart_validation','rei_woocommerce_add_to_cart_validation',20, 2);
    function rei_woocommerce_add_to_cart_validation($valid, $product_id){
        $current_user = wp_get_current_user();
        if ( wc_customer_bought_product( $current_user->user_email, $current_user->ID, $product_id)) {
            wc_add_notice( __( 'Purchased', 'woocommerce' ), 'error' );
            $valid = false;
        }
        return $valid;
    }
    

    screenshot
    http://reigelgallarde.me/product/woocommerce-woorei-shop-manager/

    problem with this though is that anyone can create a new user and buy again.

  2. You might use this code to achieve your requirement. Create a folder called woocommerce in your theme. Then create a folder named loop in it. Then create a add-to-cart.php file in it and write the below code:

      if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
    
      global $product;
      $current_user = wp_get_current_user();
    
     if ( wc_customer_bought_product( $current_user->user_email, $current_user->ID, $product->id)) {
        echo 'Purchased';
        }
       else
       {
       echo apply_filters( 'woocommerce_loop_add_to_cart_link',
      sprintf( '<a href="%s" rel="nofollow" data-product_id="%s" data-product_sku="%s" class="button          %s product_type_%s">%s</a>',
        esc_url( $product->add_to_cart_url() ),
        esc_attr( $product->id ),
        esc_attr( $product->get_sku() ),
        $product->is_purchasable() ? 'add_to_cart_button' : '',
        esc_attr( $product->product_type ),
        esc_html( $product->add_to_cart_text() )
    ),
    $product );
      } 
    

    But the user can still make a different account and buy that product again.

  3. Adding onto WisdmLabs’s answer, you will also need to edit the shortcodes and other instances of the add to cart button.

    To do this, create another folder:
    /wp-content/themes/[theme]/woocommerce/single-product/add-to-cart/

    Create a file in that folder: simple.php and add the following code:

    <?php
    /**
     * Simple product add to cart
     *
     * @author      WooThemes
     * @package     WooCommerce/Templates
     * @version     2.1.0
     */
    
    if ( ! defined( 'ABSPATH' ) ) {
        exit; // Exit if accessed directly
    }
    
    global $product;
    
    if ( ! $product->is_purchasable() ) {
        return;
    }
    
    ?>
    
    <?php
        // Availability
        $availability      = $product->get_availability();
        $availability_html = empty( $availability['availability'] ) ? '' : '<p class="stock ' . esc_attr( $availability['class'] ) . '">' . esc_html( $availability['availability'] ) . '</p>';
    
        echo apply_filters( 'woocommerce_stock_html', $availability_html, $availability['availability'], $product );
    ?>
    
    <?php if ( $product->is_in_stock() ) : ?>
    
        <?php do_action( 'woocommerce_before_add_to_cart_form' ); ?>
    
        <form class="cart" method="post" enctype='multipart/form-data'>
            <?php do_action( 'woocommerce_before_add_to_cart_button' ); ?>
    
            <?php
                if ( ! $product->is_sold_individually() ) {
                    woocommerce_quantity_input( array(
                        'min_value'   => apply_filters( 'woocommerce_quantity_input_min', 1, $product ),
                        'max_value'   => apply_filters( 'woocommerce_quantity_input_max', $product->backorders_allowed() ? '' : $product->get_stock_quantity(), $product ),
                        'input_value' => ( isset( $_POST['quantity'] ) ? wc_stock_amount( $_POST['quantity'] ) : 1 )
                    ) );
                }
            ?>
    
            <input type="hidden" name="add-to-cart" value="<?php echo esc_attr( $product->id ); ?>" />
            <?php $current_user = wp_get_current_user();
    
            if ( wc_customer_bought_product( $current_user->user_email, $current_user->ID, $product->id)) { echo '<span class="product-purchased">Purchased</span>';}
            else { ?><button type="submit" class="single_add_to_cart_button button alt"><?php echo esc_html( $product->single_add_to_cart_text() ); ?></button><?php }?>
    
            <?php do_action( 'woocommerce_after_add_to_cart_button' ); ?>
        </form>
    
        <?php do_action( 'woocommerce_after_add_to_cart_form' ); ?>
    
    <?php endif; ?>
    

    You will then also be able to edit the “Purchased” text using css class: product-purchased.

    Separate files needs to be added with different code for external.php, grouped.php, variable.php if you want this functionality to work for those product types as well.