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.
if one of these “special” products is in the cart, I want to disable “paypal” for example.
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.