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:
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:
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:
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
Call to Undefined Function Odbc_Connect() Message While Connecting Sap Hana Database
Get All Orders Ids from a Product Id in Woocommerce
Pushnotification Server Side Implementation
PHP Web Scraping of JavaScript Generated Contents
Mysqli Prepared Statement Column with Variable
Which MySQL Datatype to Use for an Ip Address
Why Use Sprintf Function in PHP
In PHP What Does It Mean by a Function Being Binary-Safe
Why a Function Checking If a String Is Empty Always Returns True
Flip Associative Array and Store New Values in Subarrays to Prevent Losing Duplicated Values
PHP in Background Exec() Function
Convert Exponential Number to Decimal in PHP
How to Get Data in Function Extend Controller
PHP Convert Xml to JSON Group When There Is One Child
Can PHP Detect If Its Run from a Cron Job or from the Command Line
#1193 - Unknown System Variable 'Lc_Messages' When Trying to Login to PHPmyadmin