23

What would be the latest best practice to load Order using increment ID (instead of Order ID) using OrderRepository

3
  • 2
    Not a duplicate - the linked answer is about retrieving the order by order id, not by increment id Oct 12, 2016 at 18:45
  • ekk! Is there a way to undo the mark as duplicate? I meant to mark the answer below as the answer to the solution.
    – frostshoxx
    Oct 12, 2016 at 20:53
  • 1
    Too late, now that it is already closed. But I nominated the question to be reopened. Oct 12, 2016 at 20:58

2 Answers 2

35

Magento 2 uses Service Contracts for retrieving and saving objects. In Magento this layer is formed by Repositories, which are managers with get() and save() methods. This keeps user code away from Model calls. Don't call model methods (like load() or save() or loadByIncrementId()) directly, they are being deprecated as custom code should use the Service Contracts. Also, don't use the API from within Magento like Khoa is suggesting, it does not make sense. The API is for connecting Magento with other systems.

Inject OrderRepository and SearchCriteriaBuilder in your constructor:

private $orderRepository;
private $searchCriteriaBuilder;

public function __construct(
        \Magento\Framework\App\Helper\Context $context,
        \Magento\Sales\Model\OrderRepository $orderRepository,
        \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder
){
$this->orderRepository = $orderRepository;
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
parent::__construct($context);
}

And in your function:

$searchCriteria = $this->searchCriteriaBuilder
    ->addFilter('increment_id', '000000001', 'eq')->create();
$orderList = $this->orderRepository->getList($searchCriteria)->getItems();

// $orderList is now an array of Orders with this incrementId, which is just one order obviously

/** @var \Magento\Sales\Model\Order $order */
$order = reset($orderList);
// Your logic here
$order = $this->orderRepository->save($order);

Official Magento PHP Developer guide on magento.com

Code by Mulderea on github

7
  • I am getting error like : Cannot use object of type Magento\Sales\Model\ResourceModel\Order\Collection as array at $order = $orderList[0];
    – Ashish Raj
    Feb 13, 2017 at 14:26
  • That's odd, I got an array. Which version are you on? But with a collection you can just replace $order = $orderList[0] with $order = $orderList->getFirstItem() to get the first (and only) item from the collection.
    – Jacques
    Feb 14, 2017 at 8:42
  • I am in version 2.1.3. and I need to load order object for load payment object .. I have done $order = $orderList->getFirstItem(); $payment = $order->getPayment(); But getting nothing in $payment Please check my problem here magento.stackexchange.com/questions/158935/…
    – Ashish Raj
    Feb 14, 2017 at 9:20
  • 1
    I had a bug with the accepted answer. This solved it. Thanks for the good solution Aug 31, 2018 at 2:44
  • 1
    @ph.dev $order = end($orderList) would be better since '000000001' here is order ID which you probably don't know. Nov 18, 2019 at 11:59
21

As far as I know, we should use \Magento\Sales\Api\Data\OrderInterface.

/** @var \Magento\Sales\Api\Data\OrderInterfaceFactory $order **/

protected $orderFactory;

public function __construct(
    \Magento\Sales\Api\Data\OrderInterfaceFactory $orderFactory,
    ......
) {
    $this->orderFactory = $orderFactory;

}

Load order object by increment id:

$this->orderFactory->create()->loadByIncrementId('00001952-42');

[EDIT] should try with service contracts. Try Jacco's answer.

11
  • 3
    Please don't use underscores in your variable names. PHP has had access modifiers since PHP 5, which is now 12 years old. You should use modern programming practices, especially in answers here.
    – Jacques
    Jan 18, 2017 at 11:18
  • 1
    This method should not be used even if it "works". One: the di injection is a shared object unless it is specified to not be; anytime you insert OrderInterface in you'll be using the exact same object. If you really want to go this route use OrderInterfaceFactory and then call create(). Second, you should be using the service contracts as in Jacco's answer.
    – Ian
    Jul 18, 2017 at 22:03
  • 2
    version 2.2.2, use \Magento\Sales\Api\OrderRepositoryInterface and its get() method
    – LucScu
    Mar 6, 2018 at 14:41
  • 2
    service contracts must be taken in consideration. Jul 2, 2018 at 10:25
  • 1
    @ThiagoLima yes, I agreed with you! I also voted the service contracts answer. Jul 3, 2018 at 1:15

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.