Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Disables Repeat Purchase for any WooCommerce product
<?php
/**
* Disables repeat purchase for products / variations
*
* @param bool $purchasable true if product can be purchased
* @param \WC_Product $product the WooCommerce product
* @return bool $purchasable the updated is_purchasable check
*/
function sv_disable_repeat_purchase( $purchasable, $product ) {
// Don't run on parents of variations,
// function will already check variations separately
if ( $product->is_type( 'variable' ) ) {
return $purchasable;
}
// Get the ID for the current product (passed in)
$product_id = $product->is_type( 'variation' ) ? $product->variation_id : $product->id;
// return false if the customer has bought the product / variation
if ( wc_customer_bought_product( wp_get_current_user()->user_email, get_current_user_id(), $product_id ) ) {
$purchasable = false;
}
// Double-check for variations: if parent is not purchasable, then variation is not
if ( $purchasable && $product->is_type( 'variation' ) ) {
$purchasable = $product->parent->is_purchasable();
}
return $purchasable;
}
add_filter( 'woocommerce_is_purchasable', 'sv_disable_repeat_purchase', 10, 2 );
/**
* Shows a "purchase disabled" message to the customer
*/
function sv_purchase_disabled_message() {
// Get the current product to see if it has been purchased
global $product;
if ( $product->is_type( 'variable' ) ) {
foreach ( $product->get_children() as $variation_id ) {
// Render the purchase restricted message if it has been purchased
if ( wc_customer_bought_product( wp_get_current_user()->user_email, get_current_user_id(), $variation_id ) ) {
sv_render_variation_non_purchasable_message( $product, $variation_id );
}
}
} else {
if ( wc_customer_bought_product( wp_get_current_user()->user_email, get_current_user_id(), $product->id ) ) {
echo '<div class="woocommerce"><div class="woocommerce-info wc-nonpurchasable-message">You\'ve already purchased this product! It can only be purchased once.</div></div>';
}
}
}
add_action( 'woocommerce_single_product_summary', 'sv_purchase_disabled_message', 31 );
/**
* Generates a "purchase disabled" message to the customer for specific variations
*
* @param \WC_Product $product the WooCommerce product
* @param int $no_repeats_id the id of the non-purchasable product
*/
function sv_render_variation_non_purchasable_message( $product, $no_repeats_id ) {
// Double-check we're looking at a variable product
if ( $product->is_type( 'variable' ) && $product->has_child() ) {
$variation_purchasable = true;
foreach ( $product->get_available_variations() as $variation ) {
// only show this message for non-purchasable variations matching our ID
if ( $no_repeats_id === $variation['variation_id'] ) {
$variation_purchasable = false;
echo '<div class="woocommerce"><div class="woocommerce-info wc-nonpurchasable-message js-variation-' . sanitize_html_class( $variation['variation_id'] ) . '">You\'ve already purchased this product! It can only be purchased once.</div></div>';
}
}
}
if ( ! $variation_purchasable ) {
wc_enqueue_js("
jQuery('.variations_form')
.on( 'woocommerce_variation_select_change', function( event ) {
jQuery('.wc-nonpurchasable-message').hide();
})
.on( 'found_variation', function( event, variation ) {
jQuery('.wc-nonpurchasable-message').hide();
if ( ! variation.is_purchasable ) {
jQuery( '.wc-nonpurchasable-message.js-variation-' + variation.variation_id ).show();
}
})
.find( '.variations select' ).change();
");
}
}
@joshrogersdesign

This comment has been minimized.

Copy link

joshrogersdesign commented Jun 28, 2016

Hey Beka!

This code is awesome - thank you for your hard work. My only issue is that I want to allow my client's customers to re-purchase only one product category. In this case it's a category called "gift-cards" (id=470). So far I have tried to just simply isolate a product id to be allowed for repurchase. But even this has its bugs:
if ( $product_id = 43026) {
return $purchasable;
}

Would you be able to help me with the category conditionality?

@pbpraveen1988

This comment has been minimized.

Copy link

pbpraveen1988 commented Jul 21, 2016

Hey Beka,

I am new to woo-commerce can you instruct me where to put the above code to run the site perfectly .

I already purchased the woo-commerce membership plugin and installed it. and I restricted a downloadable product to count according to membership and put amount of product is free because i restricted them with membership so user already paid for membership so he can easily get that product as free and after that he can download but download count is 3 (for example) so he download one so the remaining is 2 now but if he can purchase again then the download count start again from 3 , hope you understand my requirement.

That would be great helpful
Thank You

@Copylefter

This comment has been minimized.

Copy link

Copylefter commented Aug 2, 2016

Wordpress in debug mode give me notice "Notice: Trying to get property of non-object" to line if ( wc_customer_bought_product( get_current_user()->user_email, get_current_user_id(), $product_id ) ) { $purchasable = false; }

@mikeeman2000

This comment has been minimized.

Copy link

mikeeman2000 commented Nov 14, 2016

This is great. Any way to add a time limit? Say limit purchase every 30 days?

@pwallner

This comment has been minimized.

Copy link

pwallner commented Apr 8, 2017

Great code but I have a problem with wpml (multilanguage) which is not detecting the purchase in another language, I solved the problem with small adaption:

/**
 * Disables repeat purchase for products / variations
 * 
 * @param bool $purchasable true if product can be purchased
 * @param \WC_Product $product the WooCommerce product
 * @return bool $purchasable the updated is_purchasable check
 */
function sv_disable_repeat_purchase( $purchasable, $product ) {
	// Don't run on parents of variations,
	// function will already check variations separately
	if ( $product->is_type( 'variable' ) ) {
		return $purchasable;
	}
	
	// Get the ID for the current product (passed in)
	$product_id = $product->is_type( 'variation' ) ? $product->variation_id : $product->id; 
    
    // return false if the customer has bought the product / variation
    // https://wpml.org/forums/topic/get-the-translated-products-id-from-default-id/
	global $sitepress;
	$translated_ids = Array();
	if(!isset($sitepress)) return;
	$post_id = $product->id; // Your original product ID
	$trid = $sitepress->get_element_trid($post_id, 'post_product');
	$translations = $sitepress->get_element_translations($trid, 'product');
	foreach( $translations as $lang=>$translation){
		$translated_ids[] = $translation->element_id;
	}
    //http://stackoverflow.com/questions/27306828/how-to-use-wc-customer-bought-product-function-to-check-if-customer-bought-produ
	foreach($translated_ids as $item):
    	if ( wc_customer_bought_product( wp_get_current_user()->user_email, get_current_user_id(), $item) ) {
    		$purchasable = false;
    		break;
    	}
    endforeach; 
    
    // Double-check for variations: if parent is not purchasable, then variation is not
    if ( $purchasable && $product->is_type( 'variation' ) ) {
        $purchasable = $product->parent->is_purchasable();
    }
    
    return $purchasable;
}
add_filter( 'woocommerce_is_purchasable', 'sv_disable_repeat_purchase', 10, 2 );


/**
 * Shows a "purchase disabled" message to the customer
 */
function sv_purchase_disabled_message() {
	
	// Get the current product to see if it has been purchased
	global $product;
	
	if ( $product->is_type( 'variable' ) ) {
		
		foreach ( $product->get_children() as $variation_id ) {
			// Render the purchase restricted message if it has been purchased
			if ( wc_customer_bought_product( wp_get_current_user()->user_email, get_current_user_id(), $variation_id ) ) {
				sv_render_variation_non_purchasable_message( $product, $variation_id );
			}
		}
		
	} else {
		// https://wpml.org/forums/topic/get-the-translated-products-id-from-default-id/
		global $sitepress;
		$translated_ids = Array();
		if(!isset($sitepress)) return;
		$post_id = $product->id; //34; // Your original product ID
		$trid = $sitepress->get_element_trid($post_id, 'post_product');
		$translations = $sitepress->get_element_translations($trid, 'product');
		foreach( $translations as $lang=>$translation){
			$translated_ids[] = $translation->element_id;
		}
		foreach($translated_ids as $item):
    		if ( wc_customer_bought_product( wp_get_current_user()->user_email, get_current_user_id(), $item) ) {
    			echo '<div class="woocommerce"><div class="woocommerce-info wc-nonpurchasable-message">You\'ve already purchased this product! It can only be purchased once.</div></div>';
    			break;
    		}
    	endforeach; 
	}
}
add_action( 'woocommerce_single_product_summary', 'sv_purchase_disabled_message', 31 );


/**
 * Generates a "purchase disabled" message to the customer for specific variations
 * 
 * @param \WC_Product $product the WooCommerce product
 * @param int $no_repeats_id the id of the non-purchasable product
 */
function sv_render_variation_non_purchasable_message( $product, $no_repeats_id ) {
	
	// Double-check we're looking at a variable product
	if ( $product->is_type( 'variable' ) && $product->has_child() ) {
		
		$variation_purchasable = true;
		
		foreach ( $product->get_available_variations() as $variation ) {
			
			// only show this message for non-purchasable variations matching our ID
			if ( $no_repeats_id === $variation['variation_id'] ) {
				$variation_purchasable = false;	
				echo '<div class="woocommerce"><div class="woocommerce-info wc-nonpurchasable-message js-variation-' . sanitize_html_class( $variation['variation_id'] ) . '">You\'ve already purchased this product! It can only be purchased once.</div></div>';
			}
		}
	}
		
	if ( ! $variation_purchasable ) {
		wc_enqueue_js("
			jQuery('.variations_form')
				.on( 'woocommerce_variation_select_change', function( event ) {
					jQuery('.wc-nonpurchasable-message').hide();
				})
				.on( 'found_variation', function( event, variation ) {
					jQuery('.wc-nonpurchasable-message').hide();
					if ( ! variation.is_purchasable ) {
						jQuery( '.wc-nonpurchasable-message.js-variation-' + variation.variation_id ).show();
					}
				})
			.find( '.variations select' ).change();
		");
	}
}
@mrjikey

This comment has been minimized.

Copy link

mrjikey commented Feb 12, 2018

where should i upload this file?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.