Show Hide Payment Methods Based on Selected Shipping Method in Woocommerce

Show hide payment methods based on selected shipping method in Woocommerce

The following code example will enable / disable payment gateways based on chosen shipping method.

In this example, we have 3 shipping methods and 3 payment gateways. Each selected shipping method will enable only one different payment gateway.

add_filter( 'woocommerce_available_payment_gateways', 'payment_gateways_based_on_chosen_shipping_method' );
function payment_gateways_based_on_chosen_shipping_method( $available_gateways ) {
// Not in backend (admin) and Not in order pay page
if( is_admin() || is_wc_endpoint_url('order-pay') )
return $available_gateways;

// Get chosen shipping methods
$chosen_shipping_methods = (array) WC()->session->get( 'chosen_shipping_methods' );

if ( in_array( 'flat_rate:12', $chosen_shipping_methods ) )
{
unset( $gateways['bacs'] );
unset( $gateways['cod'] );
}
elseif ( in_array( 'flat_rate:14', $chosen_shipping_methods ) )
{
unset( $gateways['bacs'] );
unset( $gateways['paypal'] );
}
elseif ( in_array( 'free_shipping:10', $chosen_shipping_methods ) )
{
unset( $gateways['cod'] );
unset( $gateways['paypal'] );
}

return $gateways;
}

Code goes in functions.php file of your active child theme (or active theme). Tested and works.

To be able to get the correct shipping method ID you can use your browser inspector, this way:

Sample Image

Hide payment methods based on selected shipping method in WooCommerce

Use the following to prevent this error (also removed endif;):

// Filter payment gatways for different shipping methods
add_filter( 'woocommerce_available_payment_gateways', 'my_custom_available_payment_gateways', 10, 1 );
function my_custom_available_payment_gateways( $available_gateways ) {
if( is_admin() ) return $available_gateways; // Only for frontend

$chosen_shipping_rates = (array) WC()->session->get( 'chosen_shipping_methods' );

if ( in_array( 'flat_rate:12', $chosen_shipping_rates ) ) {
unset( $available_gateways['stripe'], $available_gateways['ppec_paypal'] );
}

return $available_gateways;
}

Code goes in functions.php file of your active child theme (or active theme). It should works.

Disable shipping method based on chosen payment method in Woocommerce

Updated on March 2019

For COD payment gateways, you can just add in its settings the "Flat rate" shipping methods that you want to enable for it, like:

Sample Image

For Cod and other methods or for others payment gateways, here is the complete working way to disable a specific shipping method(s) for specific payment gateway(s).

You will have to set in the first function the shipping method Id that you wish to hide.

The code:

add_action( 'woocommerce_package_rates','show_hide_shipping_methods', 10, 2 );
function show_hide_shipping_methods( $rates, $package ) {
// HERE Define your targeted shipping method ID
$payment_method = 'cod';

$chosen_payment_method = WC()->session->get('chosen_payment_method');

if( $payment_method == $chosen_payment_method ){
unset($rates['flat_rate:12']);
}
return $rates;
}

add_action( 'woocommerce_review_order_before_payment', 'payment_methods_trigger_update_checkout' );
function payment_methods_trigger_update_checkout(){
// jQuery code
?>
<script type="text/javascript">
(function($){
$( 'form.checkout' ).on( 'change blur', 'input[name^="payment_method"]', function() {
setTimeout(function(){
$(document.body).trigger('update_checkout');
}, 250 );
});
})(jQuery);
</script>
<?php
}

add_action( 'woocommerce_checkout_update_order_review', 'refresh_shipping_methods' );
function refresh_shipping_methods( $post_data ){
// HERE Define your targeted shipping method ID
$payment_method = 'cod';
$bool = true;

if ( WC()->session->get('chosen_payment_method') === $payment_method )
$bool = false;

// Mandatory to make it work with shipping methods
foreach ( WC()->cart->get_shipping_packages() as $package_key => $package ){
WC()->session->set( 'shipping_for_package_' . $package_key, $bool );
}
WC()->cart->calculate_shipping();
}

Code goes in function.php file of your active child theme (or active theme). Tested and works.

To be able to get the correct shipping method ID you can use your browser inspector, this way:

Sample Image

You may need to empty cart before testing this code.

Disable Payment Gateway For Specific Shipping Method On Checkout Only

add_filter( 'woocommerce_available_payment_gateways', 'filter_woocommerce_available_payment_gateways', 10, 1 );

function filter_woocommerce_available_payment_gateways( $available_gateways ) {

if ( ! ( is_checkout_pay_page() ) ) {

$gateways_to_disable = array( 'paymentgateway1', 'paymentgateway2', 'paymentgateway3' );
$shipping_methods = array( 'shippingmethod1', 'shippingmethod2', 'shippingmethod3' );
$disable_gateways = false;

// Check if we need to disable gateways
foreach ( $shipping_methods as $shipping_method ) {
if ( strpos( WC()->session->get( 'chosen_shipping_methods' )[0], $shipping_method ) !== false ) $disable_gateways = true;
}

// If so, disable the gateways
if ( $disable_gateways ) {
foreach ( $available_gateways as $id => $gateway ) {
if ( in_array( $id, $gateways_to_disable ) ) {
unset( $available_gateways[$id] );
}
}
}
return $available_gateways;
}
else { return $available_gateways;
}
}

Hide shipping and payment methods in WooCommerce

To hide specific shipping method based on the cart total, you can use below code snippet. You need to update your shipping method name in the code.

Disable shipping method as per cart total

Add this snippet in your theme's functions.php file or custom plugin file.

add_filter( 'woocommerce_package_rates', 'shipping_based_on_price', 10, 2 );

function shipping_based_on_price( $rates, $package ) {

$total = WC()->cart->cart_contents_total;
//echo $total;
if ( $total > 100 ) {

unset( $rates['local_delivery'] ); // Unset your shipping method

}
return $rates;

}

Disable Payment Gateway For Specific Shipping Method

Use below code snippet. Update code as per your payment method & shipping method.

add_filter( 'woocommerce_available_payment_gateways', 'x34fg_gateway_disable_shipping' );

function x34fg_gateway_disable_shipping( $available_gateways ) {

global $woocommerce;

if ( !is_admin() ) {

$chosen_methods = WC()->session->get( 'chosen_shipping_methods' );

$chosen_shipping = $chosen_methods[0];

if ( isset( $available_gateways['cod'] ) && 0 === strpos( $chosen_shipping, 'local_pickup' ) ) {
unset( $available_gateways['cod'] );
}

}

return $available_gateways;

}

Disabling payment methods based on custom shipping methods in WooCommerce

As both shipping methods start with the same slug, you should simply need to invert them in your if / elseif statement as follows (also there are some other mistake):

add_filter( 'woocommerce_available_payment_gateways', 'gateway_disable_shipping_meth' );

function gateway_disable_shipping_meth( $available_gateways ) {
if ( ! is_admin() ) {
$chosen_shipping = WC()->session->get( 'chosen_shipping_methods' )[0];

if ( isset( $available_gateways['bacs'] ) && 0 === strpos( $chosen_shipping, 'easypack_parcel_machines_cod' ) ) {
unset( $available_gateways['bacs'] );
}
elseif ( isset( $available_gateways['cod'] ) && 0 === strpos( $chosen_shipping, 'easypack_parcel_machines' ) ) {
unset( $available_gateways['cod'] );
}
}
return $available_gateways;
}

or also this way too:

add_filter( 'woocommerce_available_payment_gateways', 'gateway_disable_shipping_meth' );

function gateway_disable_shipping_meth( $available_gateways ) {
if ( ! is_admin() ) {
$chosen_shipping = WC()->session->get( 'chosen_shipping_methods' )[0];

if ( 0 === strpos( $chosen_shipping, 'easypack_parcel_machines' ) ) {
if ( false !== strpos( $chosen_shipping, 'cod' ) && isset( $available_gateways['bacs'] ) ) {
unset( $available_gateways['bacs'] );
} elseif ( isset( $available_gateways['cod'] ) ) {
unset( $available_gateways['cod'] );
}
}
}
return $available_gateways;
}

It should work.

Hide some payment options when paying for an order from the WooCommerce account page

add_filter('woocommerce_available_payment_gateways', 'custom_available_payment_gateways');

function custom_available_payment_gateways($available_gateways) {

$payment_ids = array('paypal'); // Here define the allowed payment methods ids to keep ( cod, stripe ... )

// For Order pay
if (is_wc_endpoint_url('order-pay')) {

foreach ($available_gateways as $payment_id => $available_gateway) {
if (!in_array($payment_id, $payment_ids)) {
unset($available_gateways[$payment_id]);
}
}
}

return $available_gateways;
}


Related Topics



Leave a reply



Submit