Home > database >  Disable payment gateway based on custom product type in WooCommerce
Disable payment gateway based on custom product type in WooCommerce

Time:10-12

I'm trying to unset COD payment gateway based on a custom product type, but it seems the code doesn't do anything with product type: doarcard.

If I set it to simple then it will work:

//new product type 
add_filter("product_type_options", function ($product_type_options) {
        $product_type_options['doarcard'] = array(
            'id' => '_doarcard',
            'wrapper_class' => 'show_if_simple show_if_variable',
            'label' => __( 'Doar Card', 'woodmart' ),
            'description' => __( 'Activare doar plata cu card sau transfer bancar', 'woodmart' ), 
            'default' => 'no');
             return $product_type_options;
});

add_action("save_post_product", function ($post_ID, $product, $update) {
        update_post_meta(
            $product->ID
            , "_doarcard"
            , isset($_POST["_doarcard"]) ? "yes" : "no");
            }, 10, 3);
//disable cod for doarcard
add_filter('woocommerce_available_payment_gateways', 'conditional_payment_gateways', 10, 1);
function conditional_payment_gateways( $available_gateways ) {
    
    if( is_admin() ) 
        return $available_gateways;
 $prod_doarcard  = false;
    foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
    
        $product = wc_get_product($cart_item['product_id']);
        // Get the product types in cart (example)
        if($product->is_type('doarcard')) $prod_doarcard = true;
        
    }
    if($prod_doarcard)
        unset($available_gateways['cod']); // unset 'cod'
    
    return $available_gateways;
}

Any advice?

CodePudding user response:

you should use unset inside foreach loop like this:

foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item ) {

   $product = wc_get_product($cart_item['product_id']);
   // Get the product types in cart (example)
   if($product->is_type('doarcard')){
       unset($available_gateways['cod']); // unset 'cod'
   } 

 }

CodePudding user response:

You are using the wrong hook/code to create a custom product type. The hook you use is for the product type options.

So use:

// Add a custom product type
function filter_product_type_selector( $product_types ){
    $product_types[ 'doarcard' ] = __( 'Doar card product', 'woocommerce' );
    return $product_types;
}
add_filter( 'product_type_selector', 'filter_product_type_selector', 10, 1 );

// Each product type has a PHP class WC_Product_{type}
function action_init(){
    class WC_Product_Doarcard extends WC_Product {
        /**
         * Initialize product.
         *
         * @param WC_Product|int $product Product instance or ID.
         */
        public function __construct( $product = 0 ) {
            $this->supports[] = 'ajax_add_to_cart';
            parent::__construct( $product );
        }
        
        /**
         * Get internal type.
         *
         * @return string
         */
        public function get_type() {
            return 'doarcard';
        }
        
        /**
         * Returns the product's active price.
         *
         * @param  string $context What the value is for. Valid values are view and edit.
         * @return string price
         */
        public function get_price( $context = 'view' ) {
            return $this->get_prop( 'price', $context );
        }
        
        /**
         * Get the add to url used mainly in loops.
         *
         * @return string
         */
        public function add_to_cart_url() {
            $url = $this->is_purchasable() && $this->is_in_stock() ? remove_query_arg(
                'added-to-cart',
                add_query_arg(
                    array(
                        'add-to-cart' => $this->get_id(),
                    ),
                    ( function_exists( 'is_feed' ) && is_feed() ) || ( function_exists( 'is_404' ) && is_404() ) ? $this->get_permalink() : ''
                )
            ) : $this->get_permalink();
            return apply_filters( 'woocommerce_product_add_to_cart_url', $url, $this );
        }

        /**
         * Get the add to cart button text.
         *
         * @return string
         */
        public function add_to_cart_text() {
            $text = $this->is_purchasable() && $this->is_in_stock() ? __( 'Add to cart', 'woocommerce' ) : __( 'Read more', 'woocommerce' );

            return apply_filters( 'woocommerce_product_add_to_cart_text', $text, $this );
        }

        /**
         * Get the add to cart button text description - used in aria tags.
         *
         * @since 3.3.0
         * @return string
         */
        public function add_to_cart_description() {
            /* translators: %s: Product title */
            $text = $this->is_purchasable() && $this->is_in_stock() ? __( 'Add “%s” to your cart', 'woocommerce' ) : __( 'Read more about “%s”', 'woocommerce' );

            return apply_filters( 'woocommerce_product_add_to_cart_description', sprintf( $text, $this->get_name() ), $this );
        }
    }
}
add_action( 'init', 'action_init' );

function filter_woocommerce_product_class( $classname, $product_type ) {
    if ( $product_type == 'doarcard' ) {
        $classname = 'WC_Product_Doarcard';
    }
    
    return $classname;
}
add_filter( 'woocommerce_product_class', 'filter_woocommerce_product_class', 10, 2 );

// Define the admin_head callback 
function action_admin_head() {
    global $post, $pagenow;
    ?>
    <script>    
    jQuery( function( $ ) {
        // For price tab
        $( '.product_data_tabs .general_tab' ).addClass( 'show_if_doarcard' ).show();
        $( '#general_product_data .pricing' ).addClass( 'show_if_doarcard' ).show();
    } );
    </script>
    <?php
}
add_action( 'admin_head', 'action_admin_head', 10, 0 );

Result:

enter image description here


Then you can use:

function filter_woocommerce_available_payment_gateways( $payment_gateways ) {
    // Not on admin
    if ( is_admin() ) return $payment_gateways;
    
    $prod_doarcard = false;
    
    // WC Cart
    if ( WC()->cart ) {
        // Loop through cart items
        foreach ( WC()->cart->get_cart() as $cart_item ) {
            // Get the WC_Product object
            $product = wc_get_product( $cart_item['product_id'] );
            
            // Get the product types in cart
            if ( $product->is_type('doarcard') ) {
                $prod_doarcard = true;
                break;
            }
        }
    
        // True
        if ( $prod_doarcard ) {
            // Cod
            if ( isset( $payment_gateways['cod'] ) ) {
                unset( $payment_gateways['cod'] );
            }  
        }
    }
    
    return $payment_gateways;
}
add_filter( 'woocommerce_available_payment_gateways', 'filter_woocommerce_available_payment_gateways', 10, 1 );

Used in my answer: Product Types Tutorial

  • Related