Search code examples
phpwordpresswoocommerceordersfee

Apply discount for every 10th order in WooCommerce


I need to give the customer a 10% discount after 10 orders are made, and next 10 and next 10.

I've found some code and modified it. So based on Apply a coupon programmatically in Woocommerce answer code, this is my code attempt:

///* 10% Discount for10 subsequent order and repeating for every 10th purchase

add_action('woocommerce_before_calculate_totals', 'discount_based_on_10 orders');
function discount_based_on_10_orders( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
        return;

    // Your settings
    $coupon_code      = '10 Or More Discount'; // Coupon code
    $total_orders = 10; // 10th order discount

    // Initializing variables
    $applied_coupons  = $cart->get_applied_coupons();
    $coupon_code      = sanitize_text_field( $coupon_code );

    // Applying coupon
    if( ! in_array($coupon_code, $applied_coupons) && $total_orders >= $10 ){
        $cart->add_discount( $coupon_code );
        wc_clear_notices();
        wc_add_notice( sprintf(
            __("Your have a surprise %s A discount has been Applied! $ You have reached your 10th order discount %s.", "woocommerce"),
            wc_format_order( $order_number ), '10%', '<strong>' . wc_format_order({
$total_orders ) . '</strong>'
        ), "notice");
    }
    // Removing coupon
    elseif( in_array($coupon_code, $applied_coupons) && $total_orders < $order_number ){
        $cart->remove_coupon( $coupon_code );
    }
}

However, this does not give the desired result. I have a coupon code 10 Or More Discount. I'm not sure how to test it and it's not my site so I'm reaching out for a quick learning curve.


Solution

  • Some comments/suggestions regarding your code attempt:

    • Do not use coupons, but a negative fee. The advantage of this is you don't have to provide security for when the coupon is used by users who already know the discount code and therefore enter it themselves
    • $total_orders is not defined, to count the orders you can use the wc_get_customer_order_count() function
    • The above function immediately ensures that this will only work for users with an account
    • The discount is applied/message is displayed when the user already has 9, 19, 29, etc.. orders, since the current order is then the 10th, 20th, 30th, etc..

    So you get:

    function action_woocommerce_cart_calculate_fees( $cart ) {
        if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
    
        // Gets the current user’s ID.
        $user_id = get_current_user_id();
    
        // 10%
        $percent = 10;
    
        // User ID exists
        if ( $user_id >= 1 ) {
            // Get the total orders by a customer.
            $order_count = wc_get_customer_order_count( $user_id );
    
            // Every 10th order
            if ( $order_count % 10 == 9 ) {
                // Discount calculation
                $discount = $cart->cart_contents_total * $percent / 100;
    
                // Only on cart page
                if ( is_cart() ) {
                    // Message
                    $message = sprintf( __( 'Your have a surprise, A discount has been applied! This is your %sth order', 'woocommerce' ), $order_count + 1 );
    
                    // Check if a notice has already been added
                    if ( ! wc_has_notice( $message ) ) {
                        wc_clear_notices();
    
                        wc_add_notice( $message, 'notice' );
                    }
                }
    
                // Set the discount (For discounts (negative fee) the taxes as always included)
                $cart->add_fee( __( 'Discount', 'woocommerce' ) . " (" . $percent . "%)", -$discount );
            }
        }
    }
    add_action( 'woocommerce_cart_calculate_fees', 'action_woocommerce_cart_calculate_fees', 10, 1 );