Creating New Product Type and Product Attribute in Magento 2

Mai Xuan Truong

In Magento, there are 6 types of products by default: simple, configurable, virtual, downloadable, bundle and grouped products, and they delivers various unique features and options that common merchants will find it sufficient for their webstore. However, sometimes we need more than those, so In this post we will find out how to create a new product type and also how to create a new attribute for a product type.

1. Create a new product type

To add a new product type, you just have to create a new file named product_types.xml in etc folder. The content of the file should be something like:

<?xml version="1.0"?>

<config xmlns:xsi="//" xsi:noNamespaceSchemaLocation="../../../Magento/Catalog/etc/product_types.xsd">
    <type name="magenest" label="Your Product Type Label" modelInstance="Vendor\Module\Model\Product\Type\Magenest" composite="false" isQty="true" canUseQtyDecimals="false" sortOrder="70">
            <attribute name="refundable" value="false"/>
            <attribute name="is_real_product" value="true"/>

Above we are creating a new product type named “Magenest” and have the type id of “magenest”. The custom attributes is of your choice. Now you should create a file at Vendor\Module\Model\Product\Type and have the name “Magenest” with the following content:

namespace Vendor\Module\Model\Product\Type;
class Wrapper extends \Magento\Catalog\Model\Product\Type\AbstractType {
    public function deleteTypeSpecificData(\Magento\Catalog\Model\Product $product)

This is the minimum amount of code that you should implement. In the future, maybe you will need to write some helper methods that you can call on the object of the product of this type.

Done, the above steps should create a new product type for you. If you check the Add new product dropdown, here is what you should see:

Create a new product type

2. Create a new attributes

This part should also be no trouble for you. Lets go ahead and create a new file named InstallData.php in Setup folder and add some lines of code:


namespace Vendor\Module\Setup;
use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
class InstallData implements InstallDataInterface
    private $eavSetupFactory;
    public function __construct(EavSetupFactory $eavSetupFactory)
        $this->eavSetupFactory = $eavSetupFactory;
    public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
        $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);
                'group' => 'Product Details',
                'type' => 'varchar',
                'backend' => '',
                'frontend' => '',
                'sort_order' => 50,
                'label' => 'Can be wrapped?',
                'input' => 'boolean',
                'class' => '',
                'source' => '',
                'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_GLOBAL,
                'visible' => true,
                'required' => false,
                'user_defined' => false,
                'default' => '',
                'searchable' => false,
                'filterable' => false,
                'comparable' => false,
                'visible_on_front' => false,
                'used_in_product_listing' => true,
                'unique' => false,

This will add a new product attribute in the Product Details group of your backend product detail page. This attribute will be of type varchar and will be displayed as a dropdown since the input is set to Boolean. Other options is up to you to choose.

One more thing here, if you create a new product of type Magenest but you can’t see where to set the price, add these lines into your InstallData.php, method install.

$fieldList = [
foreach ($fieldList as $field) {
    $applyTo = explode(
        $eavSetup->getAttribute(\Magento\Catalog\Model\Product::ENTITY, $field, 'apply_to')
    if (!in_array('magenest', $applyTo)) {
        $applyTo[] = 'magenest';
            implode(',', $applyTo)

This will add some fields into your product types. Now if you look back, you should see an attribute as following:

Create a new attributes

That’s about it for this post. Hope you can soon apply these to your extension.

Latest Insights

How to Start a Shopify Store in Just Over an Hour Course

Don't want to miss out on our latest insights?
Subscribe to our newsletter.

Disclaimer: By clicking submit, you agree to share your information with us to receive news, announcements, and resources when they are available.