Enable or Disable Payment Methods for Shipping Methods

Sometimes, in your WooCommerce store, you may need to allow specific payment methods depending on the selected shipping method by a customer.

The simplest example is when you want to allow the “Cash on delivery” payment method when “Local pickup” is selected as the shipping method. Or maybe vice versa – when your pickup points don’t accept cash, and you need “Cash on delivery” enabled only for shipping products with a carrier.

Enable payment gateway by shipping method in WooCommerce
In this example, we have three payment methods – Cash on delivery, PayPal, and Credit Card. We deactivate the “Cash on delivery” payment method for local pickups.

How can we achieve that for our WooCommerce store? As usual, there is always a plugin approach and a programmatic approach.

If you’re up for something easy and you don’t want to mess with the code, the plugin approach is your way to go – you will need Simple Conditional Shipping and Payments.

Once you install and activate it in your WooCommerce store, you will need to go to the plugin settings WooCommerce > Settings > Conditions > Payment conditions and create a new one with the following configuration:

Enable cash on delivery for specific WooCommerce shipping methods
The “Cash on delivery” option will be enabled only when the customer selects the “Local pickup” shipping method.

Well, that’s pretty much it for the plugin approach. No more steps are needed.

Now, let’s try to achieve the same with the programmatic approach. Let’s start with the code below. If you don’t know how to use it, you may check this guide.

add_filter( 'woocommerce_available_payment_gateways', 'rudr_payment_method_by_shipping' );

function rudr_payment_method_by_shipping( $gateways ) {
	
	if( is_admin() ) { // do nothing in /wp-admin
		return $gateways;
	}
	
	if( is_wc_endpoint_url( 'order-pay' ) ) { // "Pay for order" page
		
		$order = wc_get_order( wc_get_order_id_by_order_key( $_GET[ 'key' ] ) );
		if( $order->has_shipping_method( 'local_pickup' ) ) {
			if( isset( $gateways[ 'cod' ] ) ) {
				unset( $gateways[ 'cod' ] ); // unset cash on delivery if exists
			}
		}
		
	} else { // Cart/Checkout page
		
		// get a shipping method selected by a customer
		$chosen_shipping_method = WC()->session->get( 'chosen_shipping_methods' )[0];

		// check the shipping method
		if ( 'local_pickup:4' === $chosen_shipping_method ) {
			if( isset( $gateways[ 'cod' ] ) ) {
				unset( $gateways[ 'cod' ] );
			}
		}
		
	}
	
	return $gateways;

}

As you can see, we have two parts of the code.

What is local_pickup:4 here and how to get it?

As you can see, it consists of two parts – shipping method name and index. For example, you could have multiple local pickup shipping methods, and if you would like to apply the condition for all of them, you have to change line 9 to:

if ( 0 === strpos( $chosen_shipping_method, 'local_pickup' ) ) {

Okay, but where to get it? What if you have some custom shipping methods installed?

The easiest way is to inspect the code in your browser:

How to get shipping method in WooCommerce

Have any questions? Let’s discuss them 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