How would I add a custom attribute to an Order in Magento. It seems clear for Product and Customer, but I can't find any info for adding extra attributes to orders.


3 Answers 3


Create your own module and create the Setup/InstallData.php


namespace Own\Module\Setup;

use Magento\Customer\Model\Customer;
use Magento\Framework\Encryption\Encryptor;
use Magento\Framework\Indexer\IndexerRegistry;
use Magento\Framework\Setup\UpgradeDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Catalog\Setup\CategorySetupFactory;
use Magento\Quote\Setup\QuoteSetupFactory;
use Magento\Sales\Setup\SalesSetupFactory;

 * @codeCoverageIgnore
class InstallData implements InstallDataInterface
     * EAV setup factory
     * @var EavSetupFactory
    private $eavSetupFactory;

     * Category setup factory
     * @var CategorySetupFactory
    protected $categorySetupFactory;

     * Quote setup factory
     * @var QuoteSetupFactory
    protected $quoteSetupFactory;

     * Sales setup factory
     * @var SalesSetupFactory
    protected $salesSetupFactory;

     * Init
     * @param CategorySetupFactory $categorySetupFactory
     * @param SalesSetupFactory $salesSetupFactory
    public function __construct(
        SalesSetupFactory $salesSetupFactory
    ) {
        $this->salesSetupFactory = $salesSetupFactory;

     * {@inheritdoc}
     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
    public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)

        /** @var \Magento\Sales\Setup\SalesSetup $salesSetup */
        $salesSetup = $this->salesSetupFactory->create(['setup' => $setup]);

         * Remove previous attributes
        $attributes =       ['NEW_ATTRIBUTE'];
        foreach ($attributes as $attr_to_remove){


         * Add 'NEW_ATTRIBUTE' attributes for order
        $options = ['type' => 'varchar', 'visible' => false, 'required' => false];
        $salesSetup->addAttribute('order', 'NEW_ATTRIBUTE', $options);


Also you could use the same structure to assign new attribute to items. @RiccardoT for you aswell

Edit: How insert Values on the new Attributes (I use this on my Model/Orders.php that is a cron job):

use Magento\Directory\Model\Currency;
use Magento\Framework\Api\AttributeValueFactory;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Pricing\PriceCurrencyInterface;
use Magento\Sales\Api\Data\OrderInterface;
use Magento\Sales\Api\Data\OrderStatusHistoryInterface;
use Magento\Sales\Model\Order\Payment;
use Magento\Sales\Model\ResourceModel\Order\Address\Collection;
use Magento\Sales\Model\ResourceModel\Order\Creditmemo\Collection as CreditmemoCollection;
use Magento\Sales\Model\ResourceModel\Order\Invoice\Collection as InvoiceCollection;
use Magento\Sales\Model\ResourceModel\Order\Item\Collection as ImportCollection;
use Magento\Sales\Model\ResourceModel\Order\Payment\Collection as PaymentCollection;
use Magento\Sales\Model\ResourceModel\Order\Shipment\Collection as ShipmentCollection;
use Magento\Sales\Model\ResourceModel\Order\Shipment\Track\Collection as TrackCollection;
use Magento\Sales\Model\ResourceModel\Order\Status\History\Collection as HistoryCollection;

class Orders

     * @param \Magento\Sales\Model\Order $order

    public function __construct(
        \Magento\Sales\Model\Order $order,
        \Psr\Log\LoggerInterface $loggerInterface,
        \Magento\Sales\Api\OrderRepositoryInterface $orderRepositoryInterface
    ) {

        $this->order = $order;
        $this->logger = $loggerInterface;
        $this->orderRepository = $orderRepositoryInterface;

    public function execute(){

       $order = $this->order->loadByIncrementId($incrementId);
       $order->setNewAttribute('NEW VALUE');

This is in general how to get access to an order and set values to attributes.

  • THis is to add attributes, but later I cannot find any way to save information on new attributes, it seems to filter them out. Commented May 20, 2016 at 7:39
  • 1
    @RiccardoT I edited the code, there you could see a part of my code that i use to insert values on my new attributes.
    – ntzz
    Commented May 23, 2016 at 10:03

For Magento 2.3 and above:

Create your own module and create etc/db_schema.xml

<?xml version="1.0"?>
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
    <table name="sales_order" resource="sales" engine="innodb" comment="Sales Order">
        <column xsi:type="int" name="NEW_ATTRIBUTE" nullable="true" comment="NEW_ATTRIBUTE_COMMENT"/>


php bin/magento setup:upgrade
  • When adding a new attribute to customer we need to use DataPatchInterface in Magento 2.3. This is not the same for a new order attribute?
    – jstuardo
    Commented Jul 29, 2021 at 15:27
  • How to make custom attribute visible in admin / orders?
    – kovinet
    Commented Oct 11, 2021 at 14:14

There are 5 steps:

  1. Create a basic custom module
  2. Create the custom order attribute
  3. Save the order attribute using observer
  4. Syncing the sales_order table and sales_order_grid table
  5. Show order attribute in grid

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.