skip to Main Content

In my WooCommerce store I want to restrict and show payment gateway(cheque) only if the product has particular product category with the category ID "266". Now I have this snippet but it does the opposite – it disabled the gateway on the checkout for particular product category:

add_filter( 'woocommerce_available_payment_gateways', 'bbloomer_unset_gateway_by_category' );
  
function bbloomer_unset_gateway_by_category( $available_gateways ) {
    if ( is_admin() ) return $available_gateways;
    if ( ! is_checkout() ) return $available_gateways;
    $unset = false;
    $category_ids = array( 8, 37 );
    foreach ( WC()->cart->get_cart_contents() as $key => $values ) {
        $terms = get_the_terms( $values['product_id'], 'product_cat' );    
        foreach ( $terms as $term ) {        
            if ( in_array( $term->term_id, $category_ids ) ) {
                $unset = true;
                break;
            }
        }
    }
    if ( $unset == true ) unset( $available_gateways['cheque'] );
    return $available_gateways;
}

2

Answers


  1. can you change your condition in your code

    if ( $unset == true ){
         $index = 0;
        foreach($available_gateways as $single){
            if($single != "cheque"){
                unset($available_gateways[$index]);
            }   
            $index++;
        }
     }
    
    Login or Signup to reply.
  2. Using has_term() WordPress conditional function that will simplify the code making it more effective, this way:

    add_filter( 'woocommerce_available_payment_gateways', 'filter_available_payment_gateways' );
    function filter_available_payment_gateways( $available_gateways ) {
        // Only on checkout page
        if ( is_checkout() && ! is_wc_endpoint_url() ) {
            // Here define your product categories
            $product_categories = array( 't-shirts', 'posters' ); // Can be term names, term slugs or term ids
            $taxonomy = 'product_cat'; // For WooCommerce product category terms (or 'product_tag' for WooCommerce product tag terms)
    
            $payment_method     = 'cheque'; // Here define your payment method id to be removed
            $hide_payment       = false;
    
            // Loop through cart items
            foreach ( WC()->cart->get_cart_contents() as $item ) {
                if ( ! has_term( $product_categories, $taxonomy, $item['product_id'] ) ) {
                    $hide_payment = true;
                }
            }
            
            if ( $hide_payment ) {
                unset( $available_gateways[$payment_method] );
            }
        }
        return $available_gateways;
    }
    

    Code goes in functions.php file of your active child theme (or active theme). Tested and works.


    Handling product tags instead

    Simply replace in the code the taxonomy 'product_cat' by 'product_tag'.


    Targeting parent product category too

    If you need to target the parent product categories too, you will have to use this instead:

    // Custom conditional function that handle parent product categories too
    function has_product_categories( $categories, $product_id = 0 ) {
        $parent_term_ids = $categories_ids = array(); // Initializing
        $taxonomy        = 'product_cat';
        $product_id      = $product_id == 0 ? get_the_id() : $product_id;
    
        if( is_string( $categories ) ) {
            $categories = (array) $categories; // Convert string to array
        }
    
        // Convert categories term names and slugs to categories term ids
        foreach ( $categories as $category ){
            $result = (array) term_exists( $category, $taxonomy );
            if ( ! empty( $result ) ) {
                $categories_ids[] = reset($result);
            }
        }
    
        // Loop through the current product category terms to get only parent main category term
        foreach( get_the_terms( $product_id, $taxonomy ) as $term ){
            if( $term->parent > 0 ){
                $parent_term_ids[] = $term->parent; // Set the parent product category
                $parent_term_ids[] = $term->term_id; // (and the child)
            } else {
                $parent_term_ids[] = $term->term_id; // It is the Main category term and we set it.
            }
        }
        return array_intersect( $categories_ids, array_unique($parent_term_ids) ) ? true : false;
    }
    
    add_filter( 'woocommerce_available_payment_gateways', 'filter_available_payment_gateways' );
    function filter_available_payment_gateways( $available_gateways ) {
        // Only on checkout page
        if ( is_checkout() && ! is_wc_endpoint_url() ) {
            // Here define your product categories
            $product_categories = array( 't-shirts', 'posters' ); // Can be term names, term slugs or term ids
            $taxonomy = 'product_cat'; // For WooCommerce product category terms (or 'product_tag' for WooCommerce product tag terms)
    
            $payment_method     = 'cheque'; // Here define your payment method id to be removed
            $hide_payment       = false;
    
            // Loop through cart items
            foreach ( WC()->cart->get_cart_contents() as $item ) {
                if ( ! has_product_categories( $product_categories, $item['product_id'] ) ) {
                    $hide_payment = true;
                }
            }
            
            if ( $hide_payment ) {
                unset( $available_gateways[$payment_method] );
            }
        }
        return $available_gateways;
    }
    

    Code goes in functions.php file of your active child theme (or active theme). Tested and works.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search