1

In WooCommerce I use this code to apply coupon if customer for specific country (Palestine):

add_action( 'woocommerce_cart_calculate_fees','woocommerce_custom_surcharge' );
function woocommerce_custom_surcharge() {
    global $woocommerce;
    $coupon_code= "mohannad";
    $country="FR";
    
    $state = $woocommerce->customer->get_shipping_country();  
    if( $woocommerce->cart->applied_coupons === $coupon_code ) {
        if ( $state == 'PS' ) {
            WC()->cart->apply_coupon( 'MOHANNAD' );
         
        } else {
             if( $woocommerce->cart->applied_coupons === $coupon_code )
                 WC()->cart->remove_coupon( 'MOHANNAD' );
        }
    }
}

How can I cheek if coupon is applied before on country change to avoid errors?

Any help?

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399

1 Answers1

3

Your code is a bit outdated and you are not using the right hook. Also there are some mistakes. Try the following instead:

add_action( 'woocommerce_before_calculate_totals', 'country_based_discount' );
function country_based_discount( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
       return;
           
    $coupon_code        = 'mohannad';
    $allowed_countries  = array('PS');
    
    $is_coupon_applied  = in_array( $coupon_code, $cart->get_applied_coupons() );
    $is_country_allowed = in_array( WC()->customer->get_shipping_country(), $allowed_countries );
    
    if( ! $is_coupon_applied && $is_country_allowed ) {
        $cart->apply_coupon( $coupon_code );
    }
    elseif( $is_coupon_applied && ! $is_country_allowed ) {
        $cart->remove_coupon( $coupon_code );
    } 
}

Code goes in functions.php file of the active child theme (or active theme). It should work.


Addition - Handling a minimal subtotal amount (related to your comment):

add_action( 'woocommerce_before_calculate_totals', 'country_based_discount' );
function country_based_discount( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
       return;
           
    $coupon_code         = 'mohannad';
    $allowed_countries   = array('PS');
    $min_amount          = 120;
    
    $cart_subtotal      = WC()->cart->subtotal;
    $is_coupon_applied  = in_array( $coupon_code, $cart->get_applied_coupons() );
    $is_country_allowed = in_array( WC()->customer->get_shipping_country(), $allowed_countries );
    
    if( ! $is_coupon_applied && $is_country_allowed && $cart_subtotal >= $min_amount ) {
        $cart->apply_coupon( $coupon_code );
    }
    elseif( $is_coupon_applied && ! $is_country_allowed && $cart_subtotal < $min_amount ) {
        $cart->remove_coupon( $coupon_code );
    } 
}

It should work too.

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • 1
    I have changed your code slightly. `WC()->customer->get_shipping_country()` returns a string. So you have to do the equality with the `$allowed_countries` field and not `in_array()`. Also the `$shipping_country` field is not initialized, I believe you wanted to use `$allowed_countries`. I have tested it and it works. – Vincenzo Di Gaetano Jan 30 '21 at 11:09
  • @loictTheAztec Can a precondition be added to implement this code, which is to be $ cart_subtotal> 120 ( if total cart 120 do coupon for specific country (Palestine) – Mohannad Najjar Jan 30 '21 at 19:39
  • @LoicTheAztec Thanks a lot , i vote your answer and love it :) and sorry for ask many questions – Mohannad Najjar Jan 31 '21 at 14:45
  • @LoicTheAztec the code not work correctly – Mohannad Najjar Jan 31 '21 at 17:22