phpwordpresswoocommerceproduct

Disabling the a specific payment method for variable-product with specific attribute value in woocommerce


I have a WordPress website: I want to disable one of the payment methods (snapppay) for variable products with 3ml, 5ml, or 10ml values for attribute vol if only these products are in the cart. For example, my customer should be allowed any number of products with 3ml, 5ml, or 10ml values WITH AT LEAST one product with any different vol (not 3, 5 or 10ml) I tried this code but my website stops working:

function modify_available_payment_gateways($gateways) {
$flag = false;
$cart = WC()->cart;
$cart_num = count($cart->get_cart());
$dec_num = 0;
// Loop through cart items
foreach( $cart->get_cart() as $cart_item ) {
    if( $cart_item['variation_id'] > 0 ){
            // Loop through product attributes values set for the variation
            foreach( $cart_item['variation'] as $term_slug ){
                // comparing attribute term value with current attribute value
                if ($term_slug === '3ml' || $term_slug === '5ml' || $term_slug === '10ml') {
                    $dec_num = $dec_num + 1;
                }
            }
        }
    if ($cart_num === $dec_num){
        $flag = true;
    }
}

// When the flag is true
if ( $flag) {
    // Clear all other notices          
    wc_clear_notices();

    // Avoid checkout displaying an error notice
    wc_add_notice( __( 'My Error Message.', 'woocommerce' ), 'error' );
    
    // Optional: remove the payment method you want to hide
    unset($gateways['snapppay']);
}
return $gateways;
}
add_filter('woocommerce_available_payment_gateways', 'modify_available_payment_gateways');

Solution

  • To avoid this issue, you need first to target checkout only and also your code can be simplified.

    Try the following:

    add_filter('woocommerce_available_payment_gateways', 'modify_available_payment_gateways');
    function modify_available_payment_gateways( $available_gateways ) {
        if ( is_checkout() && ! is_wc_endpoint_url() && isset($available_gateways['snapppay']) ) {
    
            // Loop through cart items
            foreach( WC()->cart->get_cart() as $cart_item ) {
                if( $cart_item['variation_id'] > 0 ){
                    // Loop through product attributes values set for the variation
                    foreach( $cart_item['variation'] as $term_slug ){
                        // comparing attribute term value with current attribute value
                        if ( ! in_array($term_slug, ['3ml', '5ml', '10ml']) ) {
                            return $available_gateways;
                        }
                    }
                } else {
                    return $available_gateways;
                }
            }
    
            unset($available_gateways['snapppay']);
        }
        return $available_gateways;
    }
    

    Code goes in functions.php file of your child theme (or in a plugin). It should work.