Ozzy B.
Ozzy B.

Reputation: 23

Disable specific WooCommerce payment method for all subcategories of a given top category

I'm trying to deactivate PayPal for all subcategories by a given category slug for WooCommerce. Currently my following code just deactivates the payment method for one category. Is it possible to deactivate for all subcategories?

<?php
/**
 * Disable payment gateway based on category.
 */
function ace_disable_payment_gateway_category( $gateways ) {
    // Categories that'll disable the payment gateway 
    $category_slugs = array( 'tobacco' );
    $category_ids = get_terms( array( 'taxonomy' => 'product_cat', 'slug' => $category_slugs, 'fields' => 'ids' ) );

    // Check each cart item for given category
    foreach ( WC()->cart->get_cart() as $item ) {
        $product = $item['data'];

        if ( $product && array_intersect( $category_ids, $product->get_category_ids() ) ) {
            unset( $gateways['ppec_paypal'] );
            break;
        }
    }

    return $gateways;
}
add_filter( 'woocommerce_available_payment_gateways', 'ace_disable_payment_gateway_category' );

Upvotes: 0

Views: 855

Answers (2)

Ozzy B.
Ozzy B.

Reputation: 23

For others with the same issue. @LoicTheAztec code was extended by a code part to check if the single product site is a part of the category too:

 * Disable payment gateway based on category.
 */
add_filter( 'woocommerce_available_payment_gateways', 'disable_payment_gateway_subcategory' );
function disable_payment_gateway_subcategory( $payment_gateways ) {
    if ( is_admin() ) return $payment_gateways; // Not on admin

    $taxonomy     = 'product_cat';
    $term_slug    = 'tobacco'; // Main top category
    $term_id      = get_term_by( 'slug', $term_slug, $taxonomy )->term_id; // get term Id
    $children_ids = get_term_children( $term_id, $taxonomy ); // Get all children terms Ids
    array_unshift( $children_ids, $term_id ); // Adding main term Id to the array

    // Check on single product site 
    $cateID = wp_get_post_terms( get_the_ID(), $taxonomy, array('fields' => 'ids') );
    if ( array_intersect( $children_ids, $cateID ) ) {
        unset($payment_gateways['ppec_paypal']);
    }

    // Check each cart item for given subcategories of a top category
    foreach ( WC()->cart->get_cart() as $cart_item ) {
        $term_ids = wp_get_post_terms( $cart_item['product_id'], $taxonomy, array('fields' => 'ids') );

        if ( array_intersect( $children_ids, $term_ids ) ) {
            unset($payment_gateways['ppec_paypal']);
            break; // stop the loop
        }
    }
    return $payment_gateways;
        
}

Upvotes: 0

LoicTheAztec
LoicTheAztec

Reputation: 254438

Update 2

To disable specific payment gateway for a subcategory of a top product category, use the following:

add_filter( 'woocommerce_available_payment_gateways', 'disable_payment_gateway_subcategory' );
function disable_payment_gateway_subcategory( $payment_gateways ) {
    if ( is_admin() ) return $payment_gateways; // Not on admin

    $taxonomy     = 'product_cat';
    $term_slug    = 'tobacco'; // Main top category
    $term_id      = get_term_by( 'slug', $term_slug, $taxonomy )->term_id; // get term Id
    $children_ids = get_term_children( $term_id, $taxonomy ); // Get all children terms Ids
    array_unshift( $children_ids, $term_id ); // Adding main term Id to the array

    // Check each cart item for given subcategories of a top category
    foreach ( WC()->cart->get_cart() as $cart_item ) {
        $term_ids = wp_get_post_terms( $cart_item['product_id'], $taxonomy, array('fields' => 'ids') );

        if ( array_intersect( $children_ids, $term_ids ) ) {
            unset($payment_gateways['ppec_paypal']);
            break; // stop the loop
        }
    }
    return $payment_gateways;
}

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

Upvotes: 1

Related Questions