I use this code to programmatically apply a coupon in WooCommerce, for first order made by customers. I am needing a function that sees if the customer is new, and if so applies the coupon code.
I am trying to use this within my functions.php of my child theme to no avail.
add_action('woocommerce_after_checkout_validation','check_new_customer_coupon', 0);
function check_new_customer_coupon(){
global $woocommerce;
// you might change the name of your coupon
$new_cust_coupon_code = 'new2022';
$has_apply_coupon = false;
foreach ( WC()->cart->get_coupons() as $code => $coupon ) {
if($code == $new_cust_coupon_code) {
$has_apply_coupon = true;
}
}
if($has_apply_coupon) {
if(is_user_logged_in()) {
$user_id = get_current_user_id();
// retrieve all orders
$customer_orders = get_posts( array(
'meta_key' => '_customer_user',
'meta_value' => $user_id,
'post_type' => 'shop_order',
'numberposts'=> -1
) );
if(count($customer_orders) > 0) {
$has_ordered = false;
$statuses = array('wc-failed', 'wc-cancelled', 'wc-refunded');
// loop thru orders, if the order is not falled into failed, cancelled or refund then it consider valid
foreach($customer_orders as $tmp_order) {
$order = wc_get_order($tmp_order->ID);
if(!in_array($order->get_status(), $statuses)) {
$has_ordered = true;
}
}
// if this customer already ordered, we remove the coupon
if($has_ordered == true) {
WC()->cart->remove_coupon( $new_cust_coupon_code );
wc_add_notice( sprintf( "Coupon code: %s is only applicable for new customer." , $new_cust_coupon_code), 'error' );
return false;
}
} else {
// customer has no order, so valid to use this coupon
return true;
}
} else {
// new user is valid
return true;
}
}
}
Only this no longer appears to work in the current WooCommerce version? What am I doing wrong? My WordPress version is 6.0 and WooCommerce is 6.5.1
The code you are using no longer works in current WooCommere versions because it contains outdated code, shortcomings and some superfluous steps:
get_posts()
with multiple arguments, use wc_get_customer_order_count()
instead$tmp_order->ID
changed to $tmp_order->get_id()
since WooCommerce 3woocommerce_after_checkout_validation
hook contains 2 parametersThis updated version takes into account:
So you get:
function action_woocommerce_after_checkout_validation( $data, $error ) {
// Change the name to your coupon
$new_cust_coupon_code = 'coupon1';
// Initialize
$coupon_been_applied = false;
$remove_coupon = false;
// Get applied coupons
$applied_coupons = WC()->cart->get_applied_coupons();
// Has coupon already been applied by the customer
if ( in_array( $new_cust_coupon_code, $applied_coupons ) ) {
$coupon_been_applied = true;
// Coupon has been applied, but customer is a guest user
if ( ! is_user_logged_in() ) {
$remove_coupon = true;
}
}
// Customer is logged in
if ( is_user_logged_in() ) {
// Check if the customer has bought before
$has_bought_before = wc_get_customer_order_count( get_current_user_id() ) >= 1 ? true : false;
// Coupon been applied, but customer has bought before
if ( $coupon_been_applied && $has_bought_before ) {
$remove_coupon = true;
// NOT been applied AND NOT has bought before
} elseif ( ! $coupon_been_applied && ! $has_bought_before ) {
// Apply coupon
WC()->cart->apply_coupon( $new_cust_coupon_code );
}
}
// When true
if ( $remove_coupon ) {
// Remove coupon
WC()->cart->remove_coupon( $new_cust_coupon_code );
// Show message
$error->add( 'validation', sprintf( __( 'Coupon code: "%s" is only applicable for logged in new customers. So the coupon has been removed', 'woocommerce' ), $new_cust_coupon_code ) );
}
}
add_action( 'woocommerce_after_checkout_validation', 'action_woocommerce_after_checkout_validation', 10, 2 );