Home > Software design >  How to Display a custom message on woocommerce checkout page if user previously purchased a similar
How to Display a custom message on woocommerce checkout page if user previously purchased a similar

Time:12-16

on my website I will like to display a custom message on the checkout page if a user have previously purchased the product they are about to buy. so I came across this code that actually displays a custom message if a user already bought the product, the code only display on the single product page. please how can I display this message on the checkout page?

add_action( 'woocommerce_before_add_to_cart_form', 'user_logged_in_product_already_bought', 30 );
  
function user_logged_in_product_already_bought() {
   global $product;
   if ( ! is_user_logged_in() ) return;
   if ( wc_customer_bought_product( '', get_current_user_id(), $product->get_id() ) ) {
      echo '<div>You purchased this in the past. Buy again?</div>';
   }
}

CodePudding user response:

As @Dmitry suggested you can use the woocommerce_before_checkout_form action hook. but you can't access global $product; on the checkout page. try the below code.

function user_logged_in_product_already_bought() {

    global $woocommerce;

    if ( ! is_user_logged_in() ) return;

    // check if current user in specific role.
    $user = wp_get_current_user();
    if ( in_array( 'customer', (array) $user->roles ) ) {
        
    }

    $items = $woocommerce->cart->get_cart();

    $has_bought = false;

    foreach($items as $item => $values) { 
        if ( has_bought_items( get_current_user_id(), $values['data']->get_id() ) ) {
            $has_bought = true;
            break;
        }
    } 

    if( $has_bought ){
        wc_print_notice( "You purchased this in the past. Buy again?", 'success' );
    }

}
add_action( 'woocommerce_before_checkout_form', 'user_logged_in_product_already_bought' );

Tested and works

enter image description here

As per @7uc1f3r comment, I will like to prevent the double purchase of product per user. you can use the woocommerce_add_to_cart_validation action hook to prevent adding products from the cart.

function prevent_from_adding_cart_if_user_product_already_bought( $passed, $product_id, $quantity ) { 
    if ( has_bought_items( get_current_user_id(), $product_id ) ) {
        wc_add_notice( __( "You purchased this in the past. Buy again?", 'woocommerce' ), 'error' );
        $passed = false;
    }
    return $passed;
}
add_filter( 'woocommerce_add_to_cart_validation', 'prevent_from_adding_cart_if_user_product_already_bought', 10, 3 );

Tested and works

enter image description here

You can use this awesome function made by LoicTheAztec to check if a user has purchased specific products.

function has_bought_items( $user_var = 0,  $product_ids = 0 ) {
    global $wpdb;
    
    // Based on user ID (registered users)
    if ( is_numeric( $user_var) ) { 
        $meta_key     = '_customer_user';
        $meta_value   = $user_var == 0 ? (int) get_current_user_id() : (int) $user_var;
    } 
    // Based on billing email (Guest users)
    else { 
        $meta_key     = '_billing_email';
        $meta_value   = sanitize_email( $user_var );
    }
    
    $paid_statuses    = array_map( 'esc_sql', wc_get_is_paid_statuses() );
    $product_ids      = is_array( $product_ids ) ? implode(',', $product_ids) : $product_ids;

    $line_meta_value  = $product_ids !=  ( 0 || '' ) ? 'AND woim.meta_value IN ('.$product_ids.')' : 'AND woim.meta_value != 0';

    // Count the number of products
    $count = $wpdb->get_var( "
        SELECT COUNT(p.ID) FROM {$wpdb->prefix}posts AS p
        INNER JOIN {$wpdb->prefix}postmeta AS pm ON p.ID = pm.post_id
        INNER JOIN {$wpdb->prefix}woocommerce_order_items AS woi ON p.ID = woi.order_id
        INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS woim ON woi.order_item_id = woim.order_item_id
        WHERE p.post_status IN ( 'wc-" . implode( "','wc-", $paid_statuses ) . "' )
        AND pm.meta_key = '$meta_key'
        AND pm.meta_value = '$meta_value'
        AND woim.meta_key IN ( '_product_id', '_variation_id' ) $line_meta_value 
    " );

    // Return true if count is higher than 0 (or false)
    return $count > 0 ? true : false;
}

UPDATE as per OP request.

You can use the below code for check if the current user is in a specific role.

$user = wp_get_current_user();
if ( in_array( 'customer', (array) $user->roles ) ) {
    
}

and only products with the status of 'processing in has_bought_items function change the value of the $paid_statuses variable. as per your need.

  • Related