I have used custom product types a couple times in the past for different projects where it made sense (for example for a product rental plugin I created both a ‘simple rental’ and ‘variable rental’ product). It is only recommended to create a custom product type when it is really necessary and it doesn’t fit in the existing options of the current product types.

Getting started

In this post I will be using some examples of how to create a Simple Rental and Variable Rental product types. This will be packed in a small and overly simple plugin.

Register a new class

To get started you first need to create a class that is extending the existing WC_Product class. It is vital to have the product class named the same as in the classes’ parameter product_type, (‘same’ as in same name, each first letter of the class name should be capitalised and should have underscore separators). It is vital because WooCommerce uses the product type to get the class name and if its called differently it will not be recognised.

In my example I called my class WC_Product_Simple_Rental.

On itself, this doesn’t do much as you will not see it in the drop down when you select a product type. To add it do the product type drop down, use the following code.

Thats it!, the most basic form of adding a new product type! You will now be able to select your new product type from the drop down on the edit product pages.woocommerce-custom-product-type


In the rest of the post I will show a couple examples how you can further extend your own custom product type.

Regaining the price fields for a custom product type

One of the first things you might notice, is that the price fields are no longer available for your custom product type. Although it isn’t relevant for the Rental product types, it may be for your situation. Unfortunately there is no ‘official’ way of regaining those fields (via hooks for example), so we have to manually display them via a bit of Javascript/jQuery.

Adding a new settings panel for your custom product type

If you examine the code above, you will see that a class name show_if_simple_rental is being added, WooCommerce automatically shows or hides certain elements on the page that have related classes. A couple examples of available HTML classes that you can add to elements;

show_if_simple / hide_if_simple / show_if_variable / show_if_downloadable / hide_if_virtual

Each product type (also virtual and downloadable options) has its own classes to show or hide elements.

You can use the following code to add a new settings panel and it will only show for the new Simple Rental and Variable Rental product types.

WooCommerce will auto-load the values of the new custom fields if the id and the post meta field name (key) are the same.

Hiding an existing data panel for your custom product type

Good chance you will not need all the data panels for your new product type, and under the motto “less is more” it is a good idea to remove the unnecessary data panels. With the following code the “Attributes” data panel will not show for the custom product types we just created.

End result – a small custom product plugin

This is my end result when creating this post and posting the code snippets. It will work, but its a plugin in its utter most basic form. That is why its highly recommended to use this as example work, and not actually use it on your website.

Last words

I would love to hear from you if you found this useful, would like to see something else, missing something or just a simple thank you 🙂

Jeroen Sormani

I'm a professional WordPress plugin developer on a mission to create the best plugins for my clients. I'm specialised in developing general WordPress, WooCommerce and Easy Digital Downloads plugins.

Interested in talking about a WordPress project? Get in touch!

Follow me on Twitter

77 thoughts on “Adding a custom WooCommerce product type

a-coder January 22, 2016 at 11:30 am

Great guide! many thanks

jeroen January 22, 2016 at 10:29 pm

Thanks for commenting 🙂
Glad to hear you like it!

Dave January 29, 2016 at 12:34 am

This is just what I was looking for! One follow-up question: how do you move a field from one tab to another? For example, to simplify for my users I’d like to hide all the existing tabs and just put the fields I want onto one custom tab (for example, just price and weight).


jeroen January 29, 2016 at 7:20 pm

Hi Dave,

Basically it is not possible to move a field from one to another. It is possible to hide the old one and create a new one, but that will give conflicts.
Another hack-ish way of doing so is (re)move the field through Javascript and maybe re-create them, but that won’t be a stable way of doing things..

Am afraid there’s not solid solution for your current wishes…


Adrian February 12, 2016 at 8:30 am

Great Post !!

One question. Are you able to get a button to display on single product page for your custom type ? I tried everything but no luck.

jeroen February 13, 2016 at 11:21 am

(replied over mail :-))

Adrian February 15, 2016 at 6:27 am

Thanks for the reply Jeroen. For anyone else wondering how to display a button on your custom product single page you need something like this.

if (! function_exists( ‘woocommerce_CUSTOMTYPE_add_to_cart’ ) ) {

* Output the simple product add to cart area.
* @subpackage Product

function woocommerce_simple_add_to_cart() {

wc_get_template( ‘single-product/add-to-cart/CUSTOMTYPE.php’ );

You can either throw it into the woocommerce templates directory, or you can create your own template within your plugin directory and have your plugin template be called by following one of Jeroens other tutorials.

Jens February 14, 2016 at 6:55 am

Very helpful! Thanks, quite a lot of valuable info for me.

Small typo: you name simple_rental sometimes simpel_rental. This makes replacing this with your own type a tiny little bit harder.

Cheers, Jens

jeroen February 14, 2016 at 9:29 am

Thanks for noticing Jens, immediately changed it 🙂

torcat February 25, 2016 at 8:07 am

Hi Jeroen!

For my stpecial products ( customizable gifts) i have grouped products 1 main product and the custom products (etc. need crhristmas decoration or easter decoration ) but the child products its same , and its bad for inventory.

I need one custom product type with groups but the in the inventory need use the main product stock

in the normally woocomerce grouped product the main product have not stock quantity,
this product its hidden, need only for stock handling because if one product its out from stock can not deliver another from this groupbecause its same product.
Variation its bad for me, because products from group have anothe image and anthe decription

have you idee?

Natassa March 8, 2016 at 11:59 am

Hello Jeroen,

excellent instructions. Thank you.

One question. In front end I need to check if a product is of my custom product type or simple but if I use the function $product->is_type() it always return simple as product type. The only way to get the right product_type is to use get_the_terms($product_id, ‘product_type’) function.

Do you know why this is happening?

jeroen March 11, 2016 at 2:46 pm

Hi Natassa,

Hmm, it should as you are overwriting the ‘post_type’ property.
Have you tried this code snippet and see if that returns the proper custom product type?

Let me know :-),

Jitesh Patil December 16, 2016 at 2:06 pm

I was facing a similar issue.

The problem is I named my class My_Product_Simple_Rental instead of WC_Product_Simple_Rental.

WooCommerce expects the class name to have a WC_Product_ prefix.

Marc March 12, 2016 at 4:22 pm

HI Jeroen,

where should I put woocommerce-custom-product-mini-plugin.php in my wordpress installation, please?



jeroen March 13, 2016 at 11:24 am

Hi Marc,

It should go in your (child) themes functions.php

I wrote a blog post about code snippets some time ago here: https://aceplugins.com/how-to-add-a-code-snippet/

Rick March 17, 2016 at 8:56 pm

Hi Jeroen,

Thanks for this – very helpful.

I noticed that the Inventory tab disappears – is there a way to make it come back?



jeroen March 20, 2016 at 12:09 pm

Hi Rick,

It is possible to show the inventory tab for your custom product type, you’d need to add a filter to the woocommerce_product_data_tabs filter hook.
(links: https://github.com/woothemes/woocommerce/blob/beedd1c93020a9678e3d89a03c923e144b84505a/includes/admin/meta-boxes/class-wc-meta-box-product-data.php#L89)

Hope that steers you in the right direction 😉


Vishal April 4, 2016 at 9:42 am

Hi Jeroen,

Thanks for this tutorial, it helps me lot but,

I added function on ‘woocommerce_get_price_html’ action when i am trying to check the product type of my custom product type this $product->is_type() it always return simple as product type.

From other way as @natasa said right product_type get only by using get_the_terms($product_id, ‘product_type’) for me.

I don’t know i am doing wrong or right can you guide me because i need to make changes on product price when it displays on front-end.


myth99 May 8, 2016 at 9:30 am

Hi Vishal,

I got it by this code
$args = array(
‘post_type’ => ‘product’,
‘orderby’ => ‘post_title’,
‘order’ => ‘ASC’ ,
‘numberposts’ => -1,
‘tax_query’ => array(
‘relation’ => ‘AND’,
‘taxonomy’ => ‘product_type’,
‘field’ => ‘term_id’,
‘terms’ => 110, // change this to term id in your database *** table name – term_taxonomy
‘include_children’ => false

$the_query = new WP_Query( $args );

Ryan Weiss January 9, 2017 at 1:28 am

The solution I found was to set the product_type in the custom class’s constructor AFTER the call the parent::__construct(), ie:

public function __construct( $product ) {
parent::__construct( $product );
$this->product_type = ‘custom’;

myth99 May 8, 2016 at 9:31 am

thanks jeroen 🙂

Andrew May 14, 2016 at 1:59 am

Hello Jeroen,

Thank you for this great article!

And I have a question 🙂 Is there any way to extend a Variable product type? In the beginning of the article you mentioned that you will also create “variable rental” but I have not found it in the code…

Simeoncvetkov June 2, 2016 at 9:00 am

HI Jeroen,
I admire you on what you do have one vapros can I recreate this plugin thanks

Behrad June 6, 2016 at 4:42 pm

Hi Jeroen,

Where I live, Iran, it is almost impossible for anyone to do international shopping, i.e Amazon etc. . So basically what I’m trying to do is building an e-commerce website with two functionalities. One is the classic shop with listed products etc. which Woocommerce handles beautifully. But I would also like to make customers able to order from third-party websites, so basically customers will enter an URL and I’ll do the shopping for them, is it possible to make a Woocommerce product which is simply a URL field? I need it to use Woocommerce because I need each order to be reviewed and saved in each users’ profile.


jeroen June 6, 2016 at 8:31 pm

Hi Behrad,

Everything is possible 😉

Though I don’t think a custom product type is the best way to go here. I think just creating a new product and then add a custom field through a plugin like ‘Product Add-Ons’ that allows one to enter the URL would be more fitting for you 😉

Hope that helps.


Behrad June 8, 2016 at 3:38 pm

Thanks for the quick reply.

I tried a few things, including your advice, but unfortunately it seems that no existing plugin is fit for my case! 🙁

It’d seem that I’ll have to go down the dirty road of writing a plugin myself. I tried to use WooCommerce but it’s only capable of classic shopping, select a product, add to cart, checkout, pay and etc.. but in my special case I need the customer to be able place a custom order which is a non-specific webpage, and that should be saved to their profile, without the need for cart, checkout and other hassles. I need to review the order and then disclose the price for them and then they’ll be notified of this and be able to pay. I looked very hard but couldn’t find any setting or plugin that would do this for me. Is there something I’m missing?

Daniele June 7, 2016 at 2:28 pm


Finaly somebody who knows how woocommerce works inside, thanks!
I have a question:

I need to calculate the price of my product on a file uploaded by customer, so i make a ajax call to server to obtain the price in runtime.
Actualy i made this with many hooks and filter but in this way i loose the possibility to use ohter plugins.
So i decide to write my own product class following this tutorial.
The problem is that the product extendeds variable product instead of single product because the price depeneds on the choice of customer and now i don’t know where puts my code to call the ajax api.
Best regards,


Matt June 22, 2016 at 10:33 pm

Thanks a bunch, this saved me from trawling through the WC source for another two hours. I love event/hook-driven architecture, but it’s a nightmare to follow when you’re trying to figure out someone else’s code. Little guides like this help a lot.

D November 10, 2016 at 5:01 pm

Nice, clear and complete!
Thank you!

Myles November 18, 2016 at 1:23 am

Thanks for posting this!

Kenneth December 6, 2016 at 10:28 am

Great article!
Just one question: can you show a different product page in the front-end based on the product?

Jeroen December 7, 2016 at 1:57 pm

Hi Kenneth,

It is possible to do something like that, though it would require some extra efforts if you want to setup a whole different product page. You could go two ways about with this:
1) Remove parts that WooCommerce is adding through their hooks on the template page, and add your own here.
2) Completely change the template to start with in the template loader when WordPress is loading the templates you can override this with your own (‘template_include’ hook).


Kenneth December 13, 2016 at 5:28 pm

Hi Jeroen,

I did it slightly different, as it seems to be using the Simple product type parts.
The only thing it is not using is the add-to-cart items in the template.

Any idea why that could be?

Mte90 December 22, 2016 at 7:01 pm

There is a bug in the js code:
`jQuery( ‘.options_group.pricing’ ).removeClass(‘hidden’).addClass( ‘show_if_simple_ticket’ ).addClass(‘hidden’);`
Is the right snippet becase can be problems with the switching if hidden is not the last class for the css rules.

Jeroen December 23, 2016 at 10:04 am


Why would it be an issue if the ‘hidden’ isn’t the last class? I’m pretty confident WooCommerce core works either way, and CSS also doesn’t care about that.

Would love to hear your reasoning! 🙂


Caroline January 15, 2017 at 9:38 am

Thank you for a very useful post Jeroen! 🙂
It’s something with that jQuery that doesn’t work entirely right for me either though. If I refresh the page, including when I update the product, with my custom product type selected, then the general tab with the pricing fields disappear. It will only show again if I switch product type from my custom to another and then back again. Any clue of how to get around that? Mte90’s code snippet didn’t solve my problem.

Caroline January 15, 2017 at 11:15 am

Maybe not the best solution, but I finally solved it by adding these lines to the script:

jQuery( ‘#linked_product_data’ ).addClass( ‘hidden’ ).hide(); //Hide Linked Products Data Tab on load
jQuery( ‘#general_product_data’ ).removeClass( ‘hidden’ ).show(); //Show General Products Data Tab on load
jQuery( ‘.general_options’ ).addClass( ‘show_if_bookable active’ ).show(); //Activate General Link in left Menu
jQuery( ‘.linked_product_options’ ).removeClass( ‘active’ ); //Deactivate Linked Products Link in left Menu

Peter February 20, 2017 at 7:42 pm

Hi Caroline,

Thanks for the idea. I was suffering from the same problem as you. I also went a step further and checked that the current product is my custom product, with an if statement.

Here is my code:
// check which product type is selected
var selectedProductType = jQuery(‘#product-type’).val();
if(selectedProductType == ‘simple_non_purchasable’) {
// Deactivate shipping Link in left Menu
jQuery( ‘.shipping_tab’ ).removeClass( ‘active’ );
// Hide Shipping Panel on load
jQuery( ‘#shipping_product_data’ ).addClass( ‘hidden’ ).hide();
// Activate General Link in left Menu
jQuery( ‘.general_tab’ ).addClass( ‘active’ ).show();
// Show General Panel on load
jQuery( ‘#general_product_data’ ).removeClass( ‘hidden’ ).show();

This way product types that don’t have the ‘price’ field, won’t be affected, such as ‘grouped’ products.

Chris March 6, 2017 at 4:26 pm

Not sure if this is the same issue you are talking about but I had the issue that Caroline describes, where the general tab doesn’t show when you are editing a product until you toggle the product type selector.

I fixed this by putting the following in the same jQuery block output by simple_rental_custom_js():

jQuery( ‘select#product-type’ ).trigger(‘change’);

It just triggers the change event on that input, which WooCommerce js listens to and updates the displayed fields.

Rakesh January 4, 2017 at 3:34 pm

very useful thanks

Brend January 23, 2017 at 11:04 am

Hello Jeroen,

Very useful tutorial, thank you!

Thanks to your tutorial I was able to set up a simple custom product type, amazing!. However, I find myself in need of setting up a variable custom product type. You mentioned in the beginning of the article that the steps include how to do this, but I can’t seem to find it. Am I missing something? If not, would you mind elaborating on how to do that as well? That would be so helpful! 🙂

Thanks in advance

Jeroen January 25, 2017 at 10:18 am

Hi Brend,

Hmm, seems like I indeed missed to into that deeper.
I haven’t exactly done any verification on this, but I believe you should get far with just extending the existing Variable_Product class instead of the Simple_Product.

I’ll be sure to see if I can update this entire post to reflect this.

Thanks for noting 🙂


Carl February 2, 2017 at 7:12 am

Curious, I know this is a little off topic but you seem to have a firm understanding of this. I have an existing product type called Accommodation Bookings. By default, it’s a virtual product. But in my case, I need it to not be virtual. Do you know if you can change whether it’s a virtual product with a simple script? I can edit the changes in the code but if the plugin is updated it would be overwritten. I’d like a better solution but not sure how to go about it.

Jeroen February 2, 2017 at 9:19 am

Hi Carl,

It would depend on the plugin’s code that is used to set the virtual attribute.
Thats not something I’d be able to get to you out of the blue, it’d need to be researched in the plugin’s code first.


Carl February 2, 2017 at 5:45 pm

Not sure if this would help. It contains the class as well as the function:

Carl February 2, 2017 at 5:46 pm

Striped the script from the comment. Here is a link: https://gist.github.com/anonymous/c8e576d4bb31a218bf6a0e7f63ce8dd8

Jeroen February 16, 2017 at 9:55 pm

Hi Carl,

Going from your code you always return false for the product being virtual. What you’d want/need is to investigate how the Booking plugin you’re using is setting it to being virtual by default. Then see if you can reverse/undo that default setting.


Emil February 15, 2017 at 1:40 pm

Hi Jeroen

Thanx for a good guide on setting this up. I have a question for you if you are willing to answer.

I have Woocommerce Pre-Order plugin and want to have the Pre-Order tab visible on my custom product. How can i manage to do that? The tab is visible on Woocommerce “standard” product types.

Jeroen February 16, 2017 at 9:52 pm

Hi Emil,

Its possible to show/hide tabs by using a css class; show_if_variable where ‘variable’ is the product type. You can also use hide_if_variable


Peter February 17, 2017 at 1:56 pm

Hi Jeroen,

Thank you for this excellent tutorial. Everything you have suggested has worked for me.

Although there is still one small problem. The ‘price’ field and the ‘general’ tab both disappear when the product is saved. In other words, when I want to edit the price, I cannot see the ‘price’ field or the ‘general’ tab on the ‘edit product’ page. I actually have to change the product type back to ‘simple product’, and then back to the new ‘custom product type’ to make the ‘price’ field reappear. This is a bit strange.

Is there a way around this? Is there a way to make the ‘price’ field and ‘general’ tab appear when the edit product page first loads?

Also, I know this is beyond the scope of this tutorial, but if you could give me some tips or point me in the right direction. How would I show a different product page for the new custom product type. In other words, I want to hide the ‘add to basket’ button from the ‘product page’, and add an enquiry form instead. Also I need to remove the ‘add to basket’ button from the ‘catalog’ page too. Any ideas?

Many thanks again,

Jeroen February 17, 2017 at 7:25 pm

Hi Peter,

Under the head “Regaining the price fields for a custom product type” I described how you can get the pricing fields back for custom product types.

Re custom pages: this would indeed be a bit too in-depth for a comment. I’m trying to revise the post soon to include more info about custom product types 😉


Peter February 20, 2017 at 7:04 pm

Hi Jeroen,

Thanks for your reply. But I have already applied the JavaScript fix which you suggested. It works as far as making the ‘price’ field reappear when you select ‘Simple Rental’ from the product type dropdown, but when you reload the product edit page (e.g. when you are coming from the product list page, or when you ‘click’ update to save the simple rental product), the ‘price’ field is no longer showing. It disappears again. Is there a workaround for this problem? Or will it only show when the value of the dropdown changes?

Regarding my other question, I worked out how to remove the ‘add to cart’ button. I had to add a filter to the ‘woocommerce_is_purchasable’ filter. In other words, I had to tell the system that my new ‘custom non-purchasable’ product is not purchasable. This entirely removes the purchasing functionality for those products, not just the ‘add to cart’ button.

Here is the code:
* Make non-purchasable product ‘non-purchasable’ according to WooCommerce
* Add filter to woocommerce_is_purchasable function
function simple_non_purchasable_product_is_not_purchasable ( $is_purchasable, $product ) {

// Need to check class, as checking ‘product_type’ does not work
$class_name = get_class($product);
if($class_name == ‘WC_Product_Simple_Non_Purchasable’) {
$is_non_purchasable = true;
} else {
$is_non_purchasable = false;

// if product is non-purchasable
if($is_non_purchasable) {
return false;
else {
return $is_purchasable; // normal
add_filter(‘woocommerce_is_purchasable’, ‘simple_non_purchasable_product_is_not_purchasable’, 10, 2);

Furthermore, to add stuff to the product page for certain product types, you can check the class as above and use ‘hooks’ to add stuff. See this blog post for more info: https://businessbloomer.com/woocommerce-visual-hook-guide-single-product-page/

Many thanks,

Peter February 20, 2017 at 7:44 pm


I have the same problem as Caroline posted above. I have copied and modified here solution, by making sure the JavaScript checks the current product, with an if statement.

Here is the full script, modified:

* Show pricing fields for simple_non_purchasable product.
function simple_non_purchasable_custom_js() {

if ( ‘product’ != get_post_type() ) :

jQuery( document ).ready( function() {
jQuery( ‘.options_group.pricing’ ).addClass( ‘show_if_simple_non_purchasable’ ).show();

// check which product type is selected
var selectedProductType = jQuery(‘#product-type’).val();
if(selectedProductType == ‘simple_non_purchasable’) {
// Deactivate shipping Link in left Menu
jQuery( ‘.shipping_tab’ ).removeClass( ‘active’ );
// Hide Shipping Panel on load
jQuery( ‘#shipping_product_data’ ).addClass( ‘hidden’ ).hide();
// Activate General Link in left Menu
jQuery( ‘.general_tab’ ).addClass( ‘active’ ).show();
// Show General Panel on load
jQuery( ‘#general_product_data’ ).removeClass( ‘hidden’ ).show();
add_action( 'admin_footer', 'simple_non_purchasable_custom_js' );

I hope that helps other people experiencing the same problem.

All the best,

Justin March 1, 2017 at 2:39 am

Great tutorial! Very clear.

Unfortunately, I can’t get it to work for me. I’m creating a ‘Yarn’ product type and have registered the custom product type and registered it in the ‘Product Data’ drop down menu but it doesn’t show up. I’m more of a front end guy so I’m not sure where I’m going wrong. I see people talking about using this in a plugin but I was just wanting to put it in my php-includes/ directory and require_once() it in my functions.php. Is mine not working because it is just being called into functions.php?

Jeroen March 1, 2017 at 9:44 am

Hi Justin,

You can put the code anywhere and include it in your themes functions.php file, it doesn’t really matter as long as its executed on time.


Justin March 1, 2017 at 5:31 pm

Hmm. I got it working about an hour after I commented. On my end, it only worked when I made it into a plugin. Just adding it to the functions.php or including it into functions.php didn’t work, whatsoever.

Thank you for the quick response, though. Now I’m trying to get the General Tab and others showing by default and not disappearing when the product is saved. Thankfully, someone has already commented with a fix. Hopefully that works out.

Thank you again for the excellent article and ‘customer service’ lol.

Justin March 1, 2017 at 8:47 pm

Never mind my other comments. Finally figured it all out. Have this running as a plugin.
This creates a custom product type (‘yarn’, in my case), registers it in the Product Data drop down field. If the current product type is the custom one (‘yarn’, in my case), add a ‘show_if_customType’ (‘show_if_yarn’, in my example) to the desired Product Data tabs and their fields, make them visible with ‘show()’. I tried storing the multiple selectors for the tabs and their fields in an array variable but for some reason it just wouldn’t work for me. So, they’re just literally a list of chained selectors that target the various Product Data tab and field containing elements that get hidden or shown per respective product type.

Here’s the source snippet: http://pastebin.com/vYy57Hth

If anyone can tell me how to make the multiple chained selectors into a working array variable, let me know. I tried it in different scopes and it just wouldn’t jive. If I can make this a really organize and tidy plugin, I’ll publish it on Github or WordPress Plugin Directory.

Joe April 13, 2017 at 6:16 am

It looks like one small change is necessary to get this to work with WC 2.7+. Instead of having the product class set a property named “product_type” to your product type, it needs to implement the method “get_type()”. For example your class would become

	class WC_Product_Simple_Rental extends WC_Product_Simple {

		public function get_type( ) {

			return  'simple_rental';


Tom April 17, 2017 at 1:18 pm

Give this man a medal! 🙂

Tom April 17, 2017 at 1:38 pm

Just a heads up — after trying to figure out why things won’t save in Woo 3.0+ I finally figured it out!

Custom product type class must extend WC_Product class NOT WC_Product_Simple

Lisa April 23, 2017 at 8:54 pm

Hi Tom (and Joe),

thanks a lot, I did these two changes (extend WC_Product instead of WC_Product_Simple and the get_type() function), but unfortunately, I still can’t save my custom products in the admin area (with Woo 3.0+), the product type always jumps back to “simple product” everytime I try to save. Any ideas? 🙁

Tom April 26, 2017 at 6:21 pm

Sorry for the slow reply (only just spotted your reply)

If you did not fix it yet —

@ https://gist.github.com/stirtingale/753ac6ddb076bd551c3261007c9c63a5/revisions#diff-179610a896570d04e25227a886de04a5

Joe’s initial gist is correct (it is called at “init”) but his “End result – a small custom product plugin” gist is wrong. It is called at plugin loaded.

It must be called at init to play nice with Woo 3.0+

Joe’s initial gist is correct (add_action = init) but the “

Lisa April 27, 2017 at 1:28 am

Hi Tom,

thanks for your reply, I finally figured it out. 🙂 I tried every variation of code I found on the internet (changed “plugins_loaded” to “init” too) but nothing worked. My code was something like this (and always worked with previous woocommerce versions):

function register_custom_product_type() {

class WC_Product_Some extends WC_Product {

public function __construct( $product ) {

$this->product_type = ‘some_product’;

parent::__construct( $product );
add_action( ‘init’, ‘register_custom_product_type’ );

With Woo 3.0+ I also needed to change the class name to ‘WC_Product_Some_Product’ in the example above, or else my product type just wouldn’t save anymore (the type always jumped back to ‘Simple Product’ when saving).

Manisha Sharma August 16, 2017 at 7:24 am

How can I have attributes for this custom product as the plugin you provided is not showing attribute tab.

remsu September 1, 2017 at 11:43 am

I have a problem with the “add to cart” not showing up on product page(the custom one). Did anyone solve that ?

RGH September 29, 2017 at 9:55 pm

Thank you for this excellent tutorial!
i use from dooplay theme with post types likes films and tvshowes.
is it possilble change these post type like woocommerce downloadable product?
i will be thanksfull if you send my answer to my email.

Mohsin November 16, 2017 at 1:52 am

I have a question. Can we combine two product types . For example i want to add one product of two type rent and simple product . I want to add both rental and sale price in one product and on front end user select from drop down that he want to buy the product or take the product on rent .

In short i want to merge two type of product to create a single type. Because my client do not want to create two different product for rent and sale. He want a single product having option to add rent and sale price.

Jeroen November 16, 2017 at 9:08 am


You could have a look at grouped products, they allow one to show two different products.
Alternatively just a custom view for the products would probably be best, shouldn’t be too difficult to create that. I wouldn’t recommend to actually combine two product types into one, just keep it simple and stick with a modified view.


AT-2017 November 21, 2017 at 3:53 pm

Hello Jeroen (I guess, it’s Jero-en)! I was googling and luckily got your blog for WordPress solution. It’s really great and am willing to know about almost the same thing with a slight difference. I’ve worked with PHP few years earlier and can understand the syn-taxes. I am trying to hide the hourly price in the rental products of the booking-and-rental-system-WooCommerce plugin. I can see it isn’t possible to hide the hourly price from the dashboard and was trying to do something in the code. I got two PHP files for it and tried to modify. I know, this is kind of risky and seems like I am missing something to do that (Tried to remove the code that works for the hourly price). The files are – \wp-content\plugins\booking-and-rental-system-woocommerce\templates\single-product\add-to-cart\redq_rental.php and \wp-content\plugins\booking-and-rental-system-woocommerce\includes\class-redq-product-cart.php. I don’t know if I can disable the hourly price feature but if you have gone through this situation, let me know and would be happy to have a solution from you. Thanks.

My Scenario: In a website, when a customer selects the date, like from 20/11/2017 and to 20/11/2017, then it counts hourly price as in the plugin given (In the dashboard precisely) – ‘Hourly price will be applicabe if booking or rental days min 1day’ and this should work as a single day not hourly. But works fine for the general price when the date range is like this from 20/11/2017 and to 22/11/2017. So I just want to enable the date-wise rental price.

Jeroen November 22, 2017 at 10:51 am


I’d advise to contact the plugin author for support on that. This post is meant for adding your own custom product type, not support on a different plugin that has done that 😉

Given the folder structure, it does look like the site support WC template system; https://docs.woocommerce.com/document/template-structure/


Mahendra Prasath March 6, 2018 at 7:26 am

How to get the custom product type in front
product object returns a product-simple only
could you please let me know how to get the custom product type in front end.

Toby May 12, 2018 at 2:51 am

Thank you very much for this first step tutorial for WC beginners like me. I will try to build my first WC plugin for a friend based on this. Thanks 🙂

Paul September 9, 2018 at 1:42 pm

Hey Jeroen,

I’m setting out to create a new ‘combo’ product type that improves on WC’s own grouped type:

– listing a single price that’s the sum of the component products’ prices, not a price range from the lowest-priced component product to the highest.

– allowing only one quantity to be selected for the combo, not for each grouped product separately.

– grouping not just simple products but also variable products’ variations.

– limiting the inventory of the combo product to the smallest inventory of any of its component products.

– going out of stock when any of its component products goes out of stock.

If all that proves to be too daunting (I’m experienced with WP and PHP but find reverse-engineering the WC source code to be eye-crossing), my fall-back idea is to create a dynamic connection between the inventory of one product and the inventories of two or more other products, so that when product A is purchased then the inventories of linked products B & C are decremented, and vice versa.

I’ll let you know if I’m successful in either endeavor; in the meantime if you have any suggestions beyond what’s in this blog post I’d be grateful for your support.

Thanks for a great post,

Rachael Portier January 27, 2021 at 7:29 pm

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!

Jeroen Sormani January 27, 2021 at 7:49 pm

Hi Rachael,

Its possible to do this, either by a snippet using PHP or JavaScript, either would be capable of doing so.
Unfortunately I don’t have something ready to go to provide for this. Feel free to reach out through my contact form if you want help with this.


Kirti February 19, 2021 at 10:28 am

It’s nice one. But can we add variable custom type product?

Jeroen Sormani February 19, 2021 at 10:44 am

hi Kirti,

Sure thats possible. I haven’t done this myself (yet), but I do expect it would require additional work to ensure the proper variation data is stored (something vaguely comes to mind that Woo does a check to store data such as the variations, so a custom product type may not trigger this).

Leave a Reply