Magento comes with a new design pattern called the service contracts.
A service contract is a set of PHP interfaces used in a module. You can check an interface in any module API folder. Service contracts include service and data interfaces, which hide business logic details.
In Magento 2 You can add extension attributes for Order by creating an extension_attributes.xml file.
Extension attributes are the persistent Attribute so you can’t find extension_attributes values in a database.
Let’s assume we need to add a new Order Comment field to the order entity.
You need to use the interface Magento\Sales\Api\Data\OrderInterface to add extension_attributes in the Order entity. Thus, we need to define our order_comment extension attribute for the order extensible data object.
FilePath: app/code/Rbj/OrderComment/etc/extension_attributes.xml
<?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\OrderInterface"> <attribute code="order_comment" type="string" /> </extension_attributes> </config>
Using the above action we will define the additional setOrderComment()
and getOrderComment()
for auto-generated Magento\Sales\Api\Data\OrderExtension class.
We need to add the custom order_comment field value during the order data loaded. For this purpose, we need to create a plugin for get()
and getList()
methods of order repository class. The plugin declaration is the following in the global scope area,
File Path: app/code/Rbj/OrderFeedback/etc/di.xml
<?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\OrderRepositoryInterface"> <plugin name="ordercomment_extension_attribute" type="Rbj\OrderComment\Plugin\OrderRepositoryPlugin" /> </type> </config>
The afterGet and afterGetList methods will be called after the corresponding repository methods execution. So, this way we can affect the results:
<?php namespace Rbj\OrderComment\Plugin; use Magento\Sales\Api\Data\OrderExtensionFactory; use Magento\Sales\Api\Data\OrderInterface; use Magento\Sales\Api\Data\OrderSearchResultInterface; use Magento\Sales\Api\OrderRepositoryInterface; class OrderRepositoryPlugin { public const ORDER_COMMENT_FIELD_NAME = 'order_comment'; public function __construct(private OrderExtensionFactory $orderExtensionFactory) { } /** * Add "order_comment" extension attribute to order data object to make it accessible in API data of order record * * @return OrderInterface */ public function afterGet(OrderRepositoryInterface $subject, OrderInterface $order) { $this->setOrderComment($order); return $order; } /** * Add "order_comment" extension attribute to order data object to make it accessible in API data of all order list * * @return OrderSearchResultInterface */ public function afterGetList(OrderRepositoryInterface $subject, OrderSearchResultInterface $searchResult) { $orders = $searchResult->getItems(); foreach ($orders as $order) { $this->setOrderComment($order); } return $searchResult; } public function setOrderComment(OrderInterface $order): void { $orderComment = $order->getData(self::ORDER_COMMENT_FIELD_NAME); $extensionAttributes = $order->getExtensionAttributes(); $extensionAttributes = $extensionAttributes ?? $this->orderExtensionFactory->create(); $extensionAttributes->setOrderComment($orderComment); $order->setExtensionAttributes($extensionAttributes); } }
Once the order entity is loaded, the Order Comment value will be added to the extension attributes data object.
Using the above way, You can get the OrderComment field in any third-party API service also.