Conditional Payment Methods by Product & Country

This time, I will show you two ways of how to set up (enable or disable) payment methods in your WooCommerce store based on two conditions:

My goal is to show you how to combine both these conditions. For example, what if you want to only allow “Payment gateway A” when selling “Product B” to “Country C”?

Method 1. Setting Up Payment Methods by Product and Country Using a Plugin

If you prefer not to use any additional plugins on your WooCommerce store (who knows, maybe you already have hundreds of them), you can feel free to scroll down to the second programmatic method.

However, the plugin I will recommend here will not affect your store’s performance in any way; it also allows you to set up and manage conditions conveniently in a single place.

So, let’s use the Simple Conditional Shipping and Payments plugin to set up payment methods by both product and country conditions.

Once you have the plugin installed and activated, we need to go to WooCommerce settings, then to the “Conditions” tab, then to the “Payment conditions” section. After that, click the “Add payment condition” button.

Example is in the screenshot below:

Creating a payment condition for WooCommerce
WooCommerce > Settings > Conditions > Payment conditions

Ok, I guess, right now it is time to decide what specific condition we are going to add. Our only goal is that it should be a complex one, which checks both the customer’s country and a specific product in the cart. Let’s say that we want to disable the “Cash on delivery” payment method when shipping products with ID = 5 to New Zealand. Sounds good? It is just the first thing that came to my mind 🙂

First of all, in the “Action” select dropdown field, let’s choose “Disable payment methods”, and in another field that will appear, we need to select one or multiple payment methods:

Disable WooCommerce payment methods based on conditions

After that, let’s scroll down to the “Conditions” section and add two of them:

Payment methods by product and country for WooCommerce

As you can see from the screenshot, you can easily select multiple countries; there are no limits to that, however, you can only select one product.

If you want to select multiple products, you have two options:

The Simple Conditional Shipping and Payments plugin allows you to do all this stuff for shipping methods as well.

Method 2. Programmatically

As you can tell from the previous chapter, it only takes 1 minute to create a conditional payment method for a product and a country.

But now, let’s take a look at the programmatic approach.

The goal is the same.

/**
 * @snippet       Payment methods by product & country for WooCommerce
 * @author        Misha Rudrastyh
 * @url           https://rudrastyh.com/woocommerce/payment-methods-by-product-and-country.html
 */
add_filter( 'woocommerce_available_payment_gateways', function( $available_gateways ) {

	// we do not need to apply this function in WooCommerce admin, exit right away
	if( is_admin() ) {
		return $available_gateways;
	}

	// Check billing country
	$country = WC()->customer->get_billing_country();
	// or you can use customer shipping country if you need it instead
	// $country = WC()->customer->get_shipping_country();

	if( 'NZ' !== $country ) { // checking the country first
		return $available_gateways;
	}

	// it is time to loop through the items in the customer's cart and search for a specific product
	foreach( WC()->cart->get_cart_contents() as $cart_item ) {
		if( 5 == $cart_item[ 'product_id' ] ) {
			// disallow using "Cash on delivery" payment method
			if( isset( $available_gateways[ 'cod' ] ) ) {
				unset( $available_gateways[ 'cod'  ] );
			}
			// exit the loop
			break;
		}
	}

	return $available_gateways;

} );

Please keep in mind that the way of obtaining the billing/shipping country is different for the “Pay for order” page. You can check whether you’re on this page with this simple condition: is_wc_endpoint_url( 'order-pay' ).

// Check billing country
$order = wc_get_order( wc_get_order_id_by_order_key( $_GET[ 'key' ] ) );
$country = $order->get_billing_country();
// or you can use customer shipping country if you need it instead
// $country = $order->get_shipping_country();

The same goes for products:

foreach( $order->get_items() as $item_id => $order_item ) {

	if( 5 == $order_item->get_product_id() ) {
		if( isset( $available_gateways[ 'cod' ] ) ) {
			unset( $available_gateways[ 'cod' ] );
		}
		break;
	}

}

Have any questions about the plugin or the code? Feel free to ask in the comments below.

Misha Rudrastyh

Misha Rudrastyh

Hey guys and welcome to my website. For more than 15 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