2

I want to add custom field "comment" to the order as an extension attribute. So, the first, I have added this column to following tables in database: "quote" and "sales_order".

It's my xml file:

<?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="comment" type="string"/>
    </extension_attributes>
</config>

It's my observer ("sales_order_save_after"), where I'm trying to set "comment":

use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Event\Observer;
use Magento\Sales\Api\OrderRepositoryInterface;

class SaveComment implements ObserverInterface
{
    protected $_rep;

    public function __construct(OrderRepositoryInterface $rep)
    {
        $this->_rep = $rep;
    }

    public function execute(Observer $observer)
    {
        $order = $observer->getEvent()->getData('order');
        $ext = $order->getExtensionAttributes();
        $ext->setComment('Hi, Magento!');
        $order->setExtensionAttributes($ext);
        $this->_rep->save($order);
    }
}

And it works, but doesn't add any attributes to database, so when I try to get it in another place with:

$comment = $order->getExtensionAttributes()->getComment();

I get null. Please, help me.

5
  • You must not add new columns to existing core table, you should create own tables instead. And in that case, you need to retrieve extension attributes from another table, as an example github.com/magento/magento2/blob/develop/app/code/Magento/Vault/… how to achieve it.
    – joni jones
    Sep 26, 2017 at 7:33
  • Accept the answer If you find my answer helpful @Skorzhyk
    – Keyur Shah
    Oct 3, 2017 at 18:49
  • Link in the comments is dead. Any chance on a new one? I keep seeing this link everywhere.
    – JNDPNT
    Dec 21, 2017 at 10:00
  • Make sure to delete the generations folder. Jun 28, 2018 at 22:50
  • @JNDPNT I've added an answer with an updated link Jun 4, 2021 at 9:06

3 Answers 3

6

You need to add the below plugin to di.xml

<type name="Magento\Sales\Api\OrderRepositoryInterface">
    <plugin name="get_order_comment" type="Vendor\Sample\Plugin\OrderGet"/>
</type>

Now add the plugin to add the data to the api

class OrderGet {

    protected $_orderExtensionFactory;

    public function __construct(
        \Magento\Sales\Api\Data\OrderExtensionFactory $orderExtensionFactory
    ) {
        $this->_orderExtensionFactory = $orderExtensionFactory;
    }

    public function afterGet(
        \Magento\Sales\Api\OrderRepositoryInterface $subject,
        \Magento\Sales\Api\Data\OrderInterface $order
    ) {
        $extensionAttributes = $order->getExtensionAttributes();
        $orderExtension = $extensionAttributes ? $extensionAttributes : $this->_orderExtensionFactory->create();

        $comment = {write the logic to get the comment. e.g. $order->getComment()}
        $orderExtension->setComment($comment);

        $order->setExtensionAttributes($orderExtension);

        return $order;
    }
}
2

You can add extension attributes in Magento 2 Order data by creating aextension_attributes.xml file under etc folder.

Get insight into extension attributes in Magento 2 by referring blog,

Magento 2 Order Extension Attribute

add 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\OrderInterface">
        <attribute code="order_comment" type="string" />
    </extension_attributes>
</config>
2
  • How can we use order extension attribute with custom total(row) model ? Jan 3, 2019 at 5:56
  • Links can become stale and broken; please consider adding the critical information from the linked resource to your post Jun 4, 2021 at 9:08
0

The dead link in the comments refers to a branch which is no longer available.

Here is a permalink which points to the 2.4 branch: https://github.com/magento/magento2/blob/33242e4b19cf207d7b73f7791ef894b48bb41f8a/app/code/Magento/Vault/Plugin/PaymentVaultAttributesLoad.php

...and because posting links in comments is bad practice for Stack Exchange sites, here is the content of that file:

<?php
/**
 *
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

namespace Magento\Vault\Plugin;

use Magento\Sales\Api\Data\OrderPaymentExtensionInterface;
use Magento\Sales\Api\Data\OrderPaymentInterface;
use Magento\Vault\Api\PaymentTokenManagementInterface;
use Magento\Sales\Api\Data\OrderPaymentExtensionFactory;
use Magento\Vault\Api\Data\PaymentTokenInterface;

/**
 * Plugin for loading vault payment extension attribute to order/payment entity
 */
class PaymentVaultAttributesLoad
{
    /**
     * @var OrderPaymentExtensionFactory
     */
    protected $paymentExtensionFactory;

    /**
     * @var PaymentTokenManagementInterface
     */
    protected $paymentTokenManagement;

    /**
     * @param OrderPaymentExtensionFactory $paymentExtensionFactory
     * @param PaymentTokenManagement|PaymentTokenManagementInterface $paymentTokenManagement
     */
    public function __construct(
        OrderPaymentExtensionFactory $paymentExtensionFactory,
        PaymentTokenManagementInterface $paymentTokenManagement
    ) {
        $this->paymentExtensionFactory = $paymentExtensionFactory;
        $this->paymentTokenManagement = $paymentTokenManagement;
    }

    /**
     * Load vault payment extension attribute to order/payment entity
     *
     * @param OrderPaymentInterface $payment
     * @param OrderPaymentExtensionInterface|null $paymentExtension
     * @return OrderPaymentExtensionInterface
     */
    public function afterGetExtensionAttributes(
        OrderPaymentInterface $payment,
        OrderPaymentExtensionInterface $paymentExtension = null
    ) {
        if ($paymentExtension === null) {
            $paymentExtension = $this->paymentExtensionFactory->create();
        }

        $paymentToken = $paymentExtension->getVaultPaymentToken();
        if ($paymentToken === null) {
            $paymentToken = $this->paymentTokenManagement->getByPaymentId($payment->getEntityId());
            if ($paymentToken instanceof PaymentTokenInterface) {
                $paymentExtension->setVaultPaymentToken($paymentToken);
            }
            $payment->setExtensionAttributes($paymentExtension);
        }

        return $paymentExtension;
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.