Search

Create a Product Type with Custom Settings in WooCommerce

    Praveen Chauhan
Listen to this article

WooCommerce Product TypesWooCommerce has four product types, ‘Simple Product’, ‘Grouped Product’, ‘External/Affiliate Product’ and ‘Variable Product’.

Now, if you were happy with these product types, this article wouldn’t help you much. 😉

We had a recent client, who wanted to create a certain kind of product, which did not ‘fit’ any of the current product types. Instead of customizing existing products, we concluded, the best way to move forward with this was to create a new product type.

[space]

Creating a Custom Product Type in WooCommerce

Having your own product type, allows you to have control on product settings. For example, you could set default values like price, visibility, etc.

If you wanted to create a new product type, this is what you would have to do. Add the below code in functions.php of your active theme, or a custom plugin.

// add a product type
add_filter( 'product_type_selector', 'wdm_add_custom_product_type' );
function wdm_add_custom_product_type( $types ){
    $types[ 'wdm_custom_product' ] = __( 'Wdm Product' );
    return $types;
}
add_action( 'plugins_loaded', 'wdm_create_custom_product_type' );
function wdm_create_custom_product_type(){
     // declare the product class
     class WC_Product_Wdm extends WC_Product{
        public function __construct( $product ) {
           $this->product_type = 'wdm_custom_product';
           parent::__construct( $product );
           // add additional functions here
        }
    }
}

[space]

Adding Custom Fields to Product Settings

Now that you have your custom product type, it is understandable, you would probably need to add some extra settings fields, for your custom product type. WooCommerce provides functions to add:

  • A Text or Numeric Field: woocommerce_wp_text_input()
  • A DropDown List: woocommerce_wp_select()
  • A Text Area: woocommerce_wp_textarea_input()
  • A Checkbox Option: woocommerce_wp_checkbox()
  • An Hidden Input Field: woocommerce_wp_hidden_input()

[space]

You can use these functions to add settings options, using specified hooks. Below is an example, which adds a numeric field and a checkbox to the product settings:

// add the settings under ‘General’ sub-menu
add_action( 'woocommerce_product_options_general_product_data', 'wdm_add_custom_settings' );
function wdm_add_custom_settings() {
    global $woocommerce, $post;
    echo '<div class="options_group">';

    // Create a number field, for example for UPC
    woocommerce_wp_text_input(
      array(
       'id'                => 'wdm_upc_field',
       'label'             => __( 'UPC', 'woocommerce' ),
       'placeholder'       => '',
       'desc_tip'    => 'true',
       'description'       => __( 'Enter Unique Product Code.', 'woocommerce' ),
       'type'              => 'number'
       ));

    // Create a checkbox for product purchase status
      woocommerce_wp_checkbox(
       array(
       'id'            => 'wdm_is_purchasable',
       'label'         => __('Is Purchasable', 'woocommerce' )
       ));

    echo '</div>';
}

[space]

So, this was fairly simple to do. But just showing these options is not enough. We need to save and use these options. You would have to do the following:

add_action( 'woocommerce_process_product_meta', 'wdm_save_custom_settings' );
function wdm_save_custom_settings( $post_id ){
// save UPC field
$wdm_product_upc = $_POST['wdm_upc_field'];
if( !empty( $wdm_product_upc ) )
update_post_meta( $post_id, 'wdm_upc_field', esc_attr( $wdm_product_upc) );

// save purchasable option
$wdm_purchasable = isset( $_POST['wdm_is_purchasable'] ) ? 'yes' : 'no';
update_post_meta( $post_id, 'wdm_is_purchasable', $wdm_purchasable );
}

// to use the field values just use get_post_meta, and you are good to go!

[space]

This code has been written by trained professionals. For your own safety, Do try this at home 😉

Praveen Chauhan

Praveen Chauhan

60 Responses

    1. Hi Chris,

      You can create a plugin and put the code there (in functions.php). Or you can add the code in functions.php of your child theme. Let me know if this answers your question or in case you have any more doubts.

      1. Also, is there a way to isolate certain product settings to a particular product type? woocommerce_product_options_general_product_data seems to not give you the ability to query which product type is currently selected. Is there a way to get that?

        1. Hi Chris,

          If your settings are placed inside a div, you can add the classes ‘hide_if_{product_type}’, to hide the settings for a particular product type. For example, adding the class ‘hide_if_simple’ will hide the settings for simple product type.

    1. @Alex , you are correct it adds a simple product type and not a custom product type.

  1. I’ve just copied everything in my functions.php of my theme but then the admin panel crashes.
    What am I doing wrong?

    Don’t need the extra options just need an copy of “simple product” type with a different theme file.

    thanks

    1. Oke it works now the [ ‘ ] are wrong when i copy them to my file editor.

      Only thing is there is no price input at the admin panel.
      Also no price or buy button on the front-end.

      1. Hi Jesse,
        Glad it worked. Regarding the price input field, since you are creating a new product type, the price fields are hidden, you will need to make them visible.

        1. Hi Praveen,

          How do i unhide the price input fields?
          Not sure how to “extend” the wc_product_Simple class.

          Would be awesome to learn more about this subject. In many cases its an good solution to build extra “simple” or “custom” products. Only a price input would be nice!

          1. Hi Jesse,
            Currently there isn’t a possibility to use a hook to display the price fields. However you can use the below code, and you should be able to see the needed fields.

            add_action('woocommerce_product_options_sku', 'wdm_start_buffer');
            add_action('woocommerce_product_options_pricing', 'wdm_end_buffer');
            
            function wdm_start_buffer(){
              ob_start();
            }
            
            function wdm_end_buffer(){
              // Get value of buffering so far
              $getContent = ob_get_contents();
            
             // Stop buffering
             ob_end_clean();
            
             $getContent = str_replace('options_group pricing show_if_simple show_if_external', 'options_group pricing show_if_simple show_if_external show_if_wdm_custom_product', $getContent);
             echo $getContent;
            }
            

            Do note “show_if_wdm_custom_product”, should be “show_if_{your_product_type}”

          2. Nice thank you, fixed my problem with “tag filter”.
            But in the future i will use this solution.

            Just great to make own product types.
            ps. do you think they will work with plugins like invoices? (they also use the product types)

          3. Hi Jesse,
            Good question! Since we are adding the new product type to the WooCommerce Products list, it should work with any extension. But I haven’t tested it. But I will let you know if I test it out! 🙂

    1. Hi Mike,
      If you want to inherit all the properties of a simple product, such as price, inventory, shipping etc, you can extend the WC_Product_Simple class. You should be able to see the price fields.

      1. Hi Praveen,
        I have taken the code back to functions.php and tried to extend the new product type to WC_Product_Simple like you suggested to Mike and It didn’t change anything.
        Here is how I have done it class WC_Product_Wdm extends WC_Product_Simple

  2. Hi Praveen,
    I have added the code in the functions.php file of the theme and it worked fine.
    I would like to add it as a plugin.
    I added a new folder in the plugins which included a functions.php file with the code above. However it failed to be activated due to an unexpected error ‘add_filter’
    Thank you for your time.

  3. Hi Onisiforos,

    WooCommerce does not add the price fields by default. You could try the solution I’ve suggested to Jesse. Regarding the error, it’s surprising that you weren’t getting the error when your code was in the theme, but you get an error when it’s part of a plugin. Let me try out something and get back to you.

    1. Hi Praveen,
      I would like all the features of simple product along with added fields. Tried to extend the class as you suggested to Mike from WC_Product to WC_Product_Simple and nothing changed which is not normal as well. What if I copy the simple product code and add the extra fields I want in it?

      1. Hi Onisiforos,

        Yes, extending WC_Product_Simple does not work. I think you could use the functionality WC_Product_Simple provides. But instead of using the entire code, you could just select the functions you need.

          1. Hi Onisiforos,

            If you create a new product type, you should get other setting options except price fields. My suggestion is to add the code to display price fields as I’ve mentioned in my reply to Jesse. Also I’ve added the creation of product type class in a hook. So try it with the updated code.

  4. How can I remove a product type from the drop down.
    I need just simple product and booking product type,
    How can I remove the other two from the drop down?

    1. Hi,
      You have to use the product_type_selector filter and add your own function to remove other product types. For example to remove variable product type, use the below code

      add_filter( 'product_type_selector', 'wdm_remove_product_types' );
      function wdm_remove_product_types( $types ){
          if (isset($types['variable'])
          {
            // remove variable product type
            unset($types['variable']);
          }
          return $types;
      }
      

      Similarly you can remove other product types from the drop-down selector.

  5. Hi, thanks for great article. is there any way to show custom fields only on it’s related product type?
    I want create different product type like mobile and camera. and of course there is different fields for them. when i use your way fields shows on every product type. what’s the solution?
    thanks.

    1. Hi Peyman,

      Try adding the class ‘show_if_{product_type}’ for the options. For example, if you have a product type ‘mobile’. Try adding <div class=”options_group show_if_mobile”>

  6. Thanks for this, I followed the instructions and got a nice ‘event’ product type working – but what should I do for templates from the plugin – although the information is in the database (and I know how to display that information), there is no add to cart in the single product page for this product

    1. Hi David,

      This could be because the product price is not set. Is there a price field on the settings page for the new product type? If not you’ll have to use the code mentioned here.

      1. Hi Praveen – thanks for that – that price thing did make sense – I had my own price fields, once I used your code above it snapped into place – last part for me now is to get a custom add-to-cart/event.php working, I cannot get it to pick up the template from my plugin folder, as I want to work out the visibility of the add to car button dependent upon one of my new fields – but it appears to not want to pick up my template no matter what I try

          1. Ok – so Add to Cart is still not showing but the price is – which is very strange – nor can I get a custom add-to-cart snapping into place – final odd thing – when I ask the product what product_type it is, I get the answer ‘simple’ even though editing on the back end shows all the event fields – I guess I need to initialise the product properly somehow to make it understand it is an event not a simple product?

            I have two versions of the plugin – one is all jumbled in one file – this is where I started from – the other has been split into a nice class, functions, filters, etc set of files – neiether work properly on the front end – both work properly on the back end – which is very annoying

  7. It does not have the inventory section how I can get it, can u help me please 🙂

  8. I did it, but var_dump shows It is creating simple type product and not subscription in my case, is there anything extra I need to do for it ? please reply .

      1. Hi Prafulla,

        I sincerely apologize for not taking a look at your comment before. Glad to know you solved the issue 🙂

        1. It results good, I learned to do it myself . 🙂 thanks for this. (y) as I said I have created subscription type product , so now after adding to cart , when I will checkout I want the paypal subscription to work for me any tutorial you have written or can you give some idea here , please . 🙂

          1. I have gone through that, but I am not trying to add subscription button, for now I have developed a logic that when the subscription type product will be added to cart all other types of product will be removed from the cart and when any other types of product will be added all the subscription type product will be removed from the cart ( till now this part is finished ) now based on cart contents I am thinking to use payment gateway class.No idea if it is going to work or not, but for now this is my plan.

          2. How do you create subscription product type ?Please, can you guide me? I am also trying to create Subscription Product.

    1. Hi Jayesh,

      I didn’t get your question. Do you want to know if the product is a custom product? Or do you want to list all custom products in a template?

  9. Hello Praveen.

    I have created my custom product type, for some reason the price fields display is set to none.
    Do you have any idea why? And how can I change it to block?

  10. hello great article. Just would like to know that i want to add PRODUCT URL and BUTTON Text Option ( Same as EXTERNAL/AFFILIATE Product Type )
    How can i accomplish this?
    Please please help me out. I just want to add those two fields.

    Thanks

  11. i use this code for custom price for custom user and it display well..but when i add in to cart that time it show me original price not custom price so please help me out. 🙂

  12. Hi Praveen, Can I register the new product type to the woocomerce front-end manager plugin, when I add the new post I can’t find it in the front-end manager, is it easy to show the new product type with default ones.

    thank you

  13. Hi Praveen thank you for the excellent tutorial, learnt a lot.

    You had mentioned that a default value could be set for these custom fields we are adding. Could you please let me know how that can be done? Also would it be possibly to let these fields not be editable once a default value has been said?

    Many thanks in advance!

  14. Hi Praveen ,
    I used the same code but my custom product type is not showing as current product type after updating , can you please help ?
    Only simple product is shown as current product type..

    1. Is there any way that , if rental price added , we can filter this price in product list or shop page ?

  15. I’ve created a custom product type for discontinued products, which become unpurchasable with no price, and the product type is working perfectly. Except: It seems to be saving information, like price and stock, if the product was originally a simple product before being changed to a discontinued product. Is there anyway to “clear” the info from other product types for this product when it’s changed to a discontinued product type? I hope that makes sense!

Leave a Reply

Your email address will not be published. Required fields are marked *

Get The Latest Updates

Subscribe to our Newsletter

A key to unlock the world of open-source. We promise not to spam your inbox.

Suggested Reads

Join our 55,000+ Subscribers

    The Wisdm Digest delivers all the latest news, and resources from the world of open-source businesses to your inbox.

    Suggested Reads