Search code examples
phpwordpresswoocommercepayment-gatewayhook-woocommerce

Disable Payment Gateway For Specific Shipping Method


Following Disable Payment Gateway For Specific Shipping Method On Checkout Only answer to my previous question, which:

Disables Payment Gateways ('cardgatecreditcard', 'cardgategiropay', 'cardgateideal', 'cardgatesofortbanking') When Specific Shipping Methods are Selected ('flat_rate', 'request_shipping_quote')

However, it seems that the last part is causing a conflict with the WooCommerce Home page:

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

function filter_woocommerce_available_payment_gateways( $available_gateways ) { 

    $gateways_to_disable = array( 'cardgatecreditcard', 'cardgategiropay', 'cardgateideal', 'cardgatesofortbanking' );
    $shipping_methods = array( 'flat_rate', 'request_shipping_quote' );
    $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;
}

How do I go about troubleshooting this further?

This is the Fatal Error:

Fatal error: Uncaught Error: Call to a member function get() on null in /home/customer/www/multitrance.com/public_html/wp-content/themes/oceanwp-child/functions.php:304
Stack trace:
#0 /home/customer/www/multitrance.com/public_html/wp-includes/class-wp-hook.php(287): filter_woocommerce_available_payment_gateways(Array)
#1 /home/customer/www/multitrance.com/public_html/wp-includes/plugin.php(212): WP_Hook->apply_filters(Array, Array)
#2 /home/customer/www/multitrance.com/public_html/wp-content/plugins/woocommerce/includes/class-wc-payment-gateways.php(160): apply_filters('woocommerce_ava...', Array)
#3 /home/customer/www/multitrance.com/public_html/wp-content/plugins/woocommerce/packages/woocommerce-admin/src/Features/OnboardingTasks.php(92): WC_Payment_Gateways->get_available_payment_gateways()
#4 /home/customer/www/multitrance.com/public_html/wp-content/plugins/woocommerce/packages/woocommerce-admin/src/Features/OnboardingTasks.php(149): Automattic\WooCommerce\Admin\Features\OnboardingTasks::get_settings()
#5 /home/custo in /home/customer/www/multitrance.com/public_html/wp-content/themes/oceanwp-child/functions.php on line 304

Line 304:

if ( strpos( WC()->session->get( 'chosen_shipping_methods' )[0], $shipping_method ) !== false ) $disable_gateways = true;


Solution

  • You need to restrict your code to only checkout page:

    add_filter( 'woocommerce_available_payment_gateways', 'filter_woocommerce_available_payment_gateways' );
    function filter_woocommerce_available_payment_gateways( $available_gateways ) { 
        if( is_checkout() && ! is_wc_endpoint_url() ) {
            $gateways_to_disable = array( 'cardgatecreditcard', 'cardgategiropay', 'cardgateideal', 'cardgatesofortbanking' );
            $shipping_methods    = array( 'flat_rate', 'request_shipping_quote' );
            $chosen_shipping     = WC()->session->get( 'chosen_shipping_methods' )[0];
            $disable_gateways    = false;
        
            // Check if we need to disable gateways
            foreach ( $shipping_methods as $shipping_method ) {
                if ( strpos( $chosen_shipping, $shipping_method ) !== false ) {
                    $disable_gateways = true;
                }
            }
            
            // If so, disable the gateways
            if ( $disable_gateways ) {
                foreach ( $available_gateways as $payment_id => $gateway ) {
                    if ( in_array( $payment_id, $gateways_to_disable ) ) {
                        unset( $available_gateways[$payment_id] );
                    }
                }
            }
        }
        return $available_gateways;
    }
    

    It should work without making trouble in home page