Restrict Payments Gateways for Specific Products / Product Categories

Specific Product IDs

The code below will deactivate PayPal payment gateway if there are products with IDs “123” or “5432” in the Cart.

add_filter( 'woocommerce_available_payment_gateways', 'rudr_payment_methods_by_product_ids' );

function rudr_payment_methods_by_product_ids( $gateways ){

	// do nothing in /wp-admin
	if( is_admin() ) {
		return $gateways;
	}
	
	// Add product IDs you would like to unset payment gateways for
	$product_ids = array( 
		123, 
		5432
	);
	
	// do nothing on "Pay for order" page
	if( is_wc_endpoint_url( 'order-pay' ) ) {
		return $gateways;	
	}

	foreach ( WC()->cart->get_cart_contents() as $key => $cart_item ) {
		// count number of items if needed (optional) 
		if( in_array( $cart_item[ 'data' ]->get_id(), $product_ids ) ) {
			if( isset( $gateways[ 'paypal' ] ) ) {
				unset( $gateways[ 'paypal' ] );
				break; // exit the loop if the specific product is found
			}
		}
	}

	return $gateways; 
	
}

And yes, I think we shouldn’t forget about “Pay for order” page… So let’s add some additional code here as well.

On the “Pay for order” page we can not work with WC()->cart->get_cart_contents(), we should work with order items instead.

if( is_wc_endpoint_url( 'order-pay' ) ) { // Pay for order page

	$order_id = wc_get_order_id_by_order_key( $_GET[ 'key' ] );
	$order = wc_get_order( $order_id );

	foreach( $order->get_items() as $item_id => $order_item ) {
		if( in_array( $order_item->get_product_id(), $product_ids ) ) {
			if( isset( $gateways[ 'paypal' ] ) ) {
				unset( $gateways[ 'paypal' ] );
				break; // exit the loop if a specific product is found
			}
		}
	}

} else {
	  
	foreach ( WC()->cart->get_cart_contents() as $key => $cart_item ) {

Specific Product Categories

The code is very similar to the previous example, so I think there is no reason to copy all the code, I will just show you the condition.

For product categories:

if( array_intersect( $product->get_category_ids(), $category_ids ) ) {

For product tags:

if( array_intersect( $product->get_tag_ids(), $tag_ids ) ) {

Misha Rudrastyh

Misha Rudrastyh

Hey guys and welcome to my website. For more than 10 years I've been doing my best to share with you some superb WordPress guides and tips for free.

Need some developer help? Contact me

Follow me on X