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.

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:

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.
- In the first part, we process the payment methods on the “Pay for order” page and check if a specific shipping method is set in the order itself using the
has_shipping_method()method of theWC_Orderclass. - In the second part, we do the same for the WooCommerce Checkout page, where we get the selected shipping method from user sessions.
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:

Have any questions? Let’s discuss them in the comments below.
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