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 '17 at 7:33
  • Accept the answer If you find my answer helpful @Skorzhyk
    – Keyur Shah
    Oct 3 '17 at 18:49
  • Link in the comments is dead. Any chance on a new one? I keep seeing this link everywhere.
    – JNDPNT
    Dec 21 '17 at 10:00
  • Make sure to delete the generations folder. Jun 28 '18 at 22:50
  • @JNDPNT I've added an answer with an updated link Jun 4 at 9:06
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 '19 at 5:56
  • Links can become stale and broken; please consider adding the critical information from the linked resource to your post Jun 4 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, privacy policy and cookie policy

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