Skip to content
Advertisement

Disable all payments gateway if there’s specifics products in the Cart

I would like to disable all payments gateways under special situation:
I’ve 2 special products that I don’t want to be combined at checkout with any other product.

Lets say that my “special” products IDs are 496 and 484. All other are “normal” products.

  1. if one of these “special” products is in the cart, I want to disable “paypal” for example.

  2. if a customer has in his cart, at once, a “special” product and a “normal” product, I want to disable all the payments gateway, so he can’t checkout.

This is my code:

//disable add to cart if
add_filter( 'woocommerce_available_payment_gateways', 'filter_gateways', 1);

function filter_gateways( $gateways )
{   
    global $woocommerce;

    foreach ($woocommerce->cart->cart_contents as $key => $values ) {   
        // store product IDs in array   
        $nonPPproducts = array(496,484);        

        if (in_array( $values['product_id'], $nonPPproducts ) ) {
            unset($gateways['cod'], $gateways['bacs'], $gateways['cheque'], $gateways['stripe']);
        } elseif ( in_array( $values['product_id'], $nonPPproducts ) && in_array( $values['product_id'] ) ) {           
            unset($gateways['under-review'], $gateways['cod'], $gateways['bacs'], $gateways['cheque'], $gateways['stripe']);
        }
    }

    return $gateways;   
}

But I can’t figure out why the only first if statement works… In other words whatever the situation, all payment gateways are disabled except under-review payment gateway.

What I am doing wrong?
How can I achieve this?

Thanks

Advertisement

Answer

Updated for WooCommerce 3+

First I think that in_array( $values['product_id'] ) in your code is not working as a correct condition and so your else statement is never “true”. Then as a customer can have many items in his cart, depending on customer successive choices, with your code there will be many redundant gateway unsets

Here it is your code revisited (you will need to put the desire unset gateways in each statement):

add_filter( 'woocommerce_available_payment_gateways', 'filter_gateways', 1);
function filter_gateways( $gateways ){
    // Not in backend (admin)
    if( is_admin() ) 
        return $gateways;

    // Storing special product IDs in an array
    $non_pp_products = array( 496, 484 );

    // Needed variables
    $is_non_prod = false;
    $is_prod = false;
    $count = 0;

    foreach ( WC()->cart->get_cart() as $cart_item ) {
        // count number of items if needed (optional) 
        $count++;
        $product = $cart_item['data'];
        if( ! empty($product) ){
            $product_id = method_exists( $product, 'get_id' ) ? $product->get_id() : $product->id;
            if ( in_array( $product_id, $non_pp_products ) && ! $is_non_prod ) 
                $is_non_prod = true;

            if ( !in_array( $product_id, $non_pp_products ) && !$is_prod )
                $is_prod = true;

        }
    }
    if ( $is_non_prod && ! $is_prod ) // only special products 
    {
        // unset only paypal;
        unset( $gateways['paypal'] );
    } 
    elseif ( $is_non_prod && $is_prod ) // special and normal products mixed
    {
        // unset ALL GATEWAYS
        unset( $gateways['cod'], 
               $gateways['bacs'], 
               $gateways['cheque'], 
               $gateways['paypal'], 
               $gateways['stripe'], 
               $gateways['under-review'] );
    }
    elseif ( ! $is_non_prod && $is_prod ) // only normal products (optional)
    {
        // (unset something if needed)
    }
    return $gateways; 
}

Naturally this code goes on functions.php file of your active child theme or theme.

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement