Disable Payment Gateway based on Shipping Method

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

In order to do so you can use the code below in your current or child theme functions.php file:

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;

}

If you need some custom coding help with WooCommerce payment gateways or maybe you need to develop one – please feel free to contact me.

As you can see, we have two parts of the code, in the first part – we process the payment methods on “Pay for order” page and check if a specific shipping method is set in the order itself using has_shipping_method() method of WC_Order class. 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 in 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
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