Magento 2 APIs framework offers developers and integrators the ability to use web services that communicate with the Magento 2 system.

Magento 2 web APIs can be used to perform a wide array of tasks, such as create a shopping app, integrating with CRM/ERP/CMS, build a JS widget to access services via AJAX calls.

By default in Magento 2, custom products attributes are not included in the sales order API. When building an app or integrating your Magento 2 store with a third-party system to sync your orders, you may have many custom product attributes that you want to add to sales order API, in order to use it further in your app or third-party systems (CRM, ERP, other CMS, etc).

In this tutorial, we provide you with a step-by-step guide to add a custom product attribute to sales order API.

We will use "my_custom_product_attribute" as our custom product attribute, and we assume that "my_custom_product_attribute" already exists in sales_order_item database table.

Step 1. Declare The Custom Attribute

Create this file app/code/Vendor/Module/etc/extension_attributes.xml and add this code:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
<extension_attributes for="Magento\Sales\Api\Data\OrderItemInterface">
    <attribute code="my_custom_product_attribute" type="string"/>
</extension_attributes>
</config>

We use type="string" because our custom product attribute is of type text. You can change to your custom product attribute type. Eg. if your custom attribute is of type boolean, you can use "type="boolean"

Step 2. Declare The Plugin

Create this file app/code/Vendor/Module/etc/di.xml and add this code:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
	<type name="Magento\Sales\Api\OrderItemRepositoryInterface">
		<plugin name="order_item_custom_attribute" type="Vendor\Module\Plugin\Model\Order\AddCustomProductAttribute" />
     </type>		
</config>

Step 3. Create The Plugin

Create this file app/code/Vendor/Module/Plugin/Model/Order/AddCustomProductAttribute.php and add this code:

<?php

namespace Vendor\Module\Plugin\Model\Order;

use Magento\Catalog\Model\ProductFactory;
use Magento\Sales\Api\Data\OrderItemInterface;
use Magento\Sales\Api\OrderItemRepositoryInterface;
use Magento\Sales\Api\Data\OrderItemExtensionFactory;
use Magento\Sales\Api\Data\OrderItemSearchResultInterface;

class AddCustomProductAttribute
{

    /**
     * @var OrderItemExtensionFactory
     */	
    protected $orderItemExtensionFactory;

    /**
     * @var ProductFactory
     */	
    protected $productFactory;

    /**
     * @param OrderItemExtensionFactory $orderItemExtensionFactory
     * @param ProductFactory $productFactory
     */
    public function __construct(
        OrderItemExtensionFactory $orderItemExtensionFactory,
        ProductFactory $productFactory
    ) {
        $this->orderItemExtensionFactory = $orderItemExtensionFactory;
        $this->productFactory = $productFactory;
    }

    /**
     * Add "my_custom_product_attribute" to order item
     *
     * @param OrderItemInterface $orderItem
     *
     * @return OrderItemInterface
     */
    protected function addMyCustomProductAttributeData(OrderItemInterface $orderItem)
    {
        $product = $this->productFactory->create();
        $product->load($orderItem->getProductId());
        $customAttribute = $product->getMyCustomProductAttribute();

        if (isset($customAttribute)) {
            $orderItemExtension = $this->orderItemExtensionFactory->create();
            $orderItemExtension->setMyCustomProductAttribute($customAttribute);

            $orderItem->setExtensionAttributes($orderItemExtension);
        }
        
        return $orderItem;
    }
	
     * Add "my_custom_product_attribute" extension attribute to order data object
     * to make it accessible in API data
     *
     * @param OrderItemRepositoryInterface $subject
     * @param OrderItemInterface $orderItem
     *
     * @return OrderItemInterface
     */
    public function afterGet(OrderItemRepositoryInterface $subject, OrderItemInterface $orderItem)
    {
        $customAttribute = $orderItem->getData('my_custom_product_attribute');
 
        $extensionAttributes = $orderItem->getExtensionAttributes();
        $extensionAttributes = $extensionAttributes ? $extensionAttributes : $this->extensionFactory->create();

         $extensionAttributes->setMyCustomProductAttribute($customAttribute);
        $orderItem->setExtensionAttributes($extensionAttributes);

        return $orderItem;
    }

    /**
     * Add "my_custom_product_attribute" extension attribute to order data object
     * to make it accessible in API data
     *
     * @param OrderItemRepositoryInterface $subject
     * @param OrderItemSearchResultInterface $searchResult
     *
     * @return OrderItemSearchResultInterface
     */
    public function afterGetList(OrderItemRepositoryInterface $subject, OrderItemSearchResultInterface $searchResult)
    {
        $orders = $searchResult->getItems();

        foreach ($orders as &$order) {
            $order = $this->addMyCustomProductAttributeData($order);
        }

        return $searchResult;
    }
}
  • replace: Vendor\Module with your vendor and module name
  • replace "my_custom_product_attribute" with your custom product attribute
  • replace setMyCustomProductAttribute and getMyCustomProductAttribute with your custom product attribute set/get methods

Step 4. Empty Generated Folder

Make sure to empty the generated folder under your Magento 2 root directory before testing.

Step 5. Testing

We will use:

  • order_id is: 176
  • access Token: cm6r32nsyqa1vdr40a9udgpel2jp4zyp
  • base URL: mydomain.com

From the command line, we make a web API call:

curl -X GET "http://mydomain.com/index.php/rest/V1/orders/176" -H "Authorization: Bearer cm6r32nsyqa1vdr40a9udgpel2jp4zyp"

The custom product attribute "my_custom_product_attribute" appear in the API response, under "extension_attributes" section

{
   .....,
   "items":[
      {
         .....
         "extension_attributes":{
            "my_custom_product_attribute":"My Custom Product Data"
         }
      }
   ],
   ....
}

We hope you find this helpful. Feel free to share this article.

If you have any issues or questions in adding custom product attributes to sales order API in Magento 2, feel free to let us know in the comment field below.

If you're looking to adjust the code for your specific needs, feel free to contact us

Tags: magento 2 api api