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.


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. May 20 '16 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
    May 23 '16 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
    Jul 29 at 15:27
  • How to make custom attribute visible in admin / orders?
    – kovinet
    Oct 11 at 14:14

This is super easy.

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

See in detail step by step code and implemetation here and watch video

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.