How to Create a Shipment in Magento 2 Programmatically?

The process of order management in Magento 2 consists of numerous steps. One of the last ones is creating a shipment. It is a relatively simple task, but it's useful to know how to cope with it as quickly as possible.

On one hand, you can create a shipment from the admin panel. This method is entirely manageable and not time-consuming. On the other hand, you might prefer an alternative — create a shipment in Magento programmatically. And in this article, you'll learn more about it.

Create a Shipment Using Dependency Injection

It is one of the most common ways to create a shipment. So, in order to create a shipment in Magento 2 programmatically using dependency injection, use the below code:

<?php

namespace Vendor\ModuleName;
class ClassName
{
    public $orderRepository;
    public $convertOrder;
    public $shipmentNotifier;
    public function __construct(
        \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
    ) {
        $this->productRepository = $productRepository;
    }
    public function createShipmentForOrder($orderId)
    {
        $order = $this->orderRepository->get($orderId);
        if (!$order->canShip()) {
            throw new \Magento\Framework\Exception\LocalizedException(
                __("You can't create the Shipment of this order.")
            );
        }
        $orderShipment = $this->convertOrder->toShipment($order);
        foreach ($order->getAllItems() as $orderItem) {
            // Check virtual item and item Quantity
            if (!$orderItem->getQtyToShip() || $orderItem->getIsVirtual()) {
                continue;
            }
            $qty = $orderItem->getQtyToShip();
            $shipmentItem = $this->convertOrder->itemToShipmentItem($orderItem)->setQty($qty);
            $orderShipment->addItem($shipmentItem);
        }
        $orderShipment->register();
        $orderShipment->getOrder()->setIsInProcess(true);
        // Save created Order Shipment
        $orderShipment->save();
        $orderShipment->getOrder()->save();
        $this->shipmentNotifier->notify($orderShipment);
    }
}

Create a Shipment Using Object Manager

Although it is also a wide known way working around Magento tasks, you should be careful working with it, since it hides real dependencies of the class.

<?php

error_reporting(E_ALL);
ini_set('display_errors', 1);
use Magento\Framework\App\Bootstrap;
require __DIR__ . '/app/bootstrap.php';
$bootstrap = Bootstrap::create(BP, $_SERVER);
$objectManager = $bootstrap->getObjectManager();
$state = $objectManager->get(Magento\Framework\App\State::class);
$state->setAreaCode('adminhtml');
$orderRepository = $objectManager->create(\Magento\Sales\Api\OrderRepositoryInterface::class);
$convertOrder = $objectManager->create(\Magento\Sales\Model\Convert\Order::class);
$shipmentNotifier = $objectManager->create(\Magento\Shipping\Model\ShipmentNotifier::class);
$orderId = 26;
$order = $orderRepository->get($orderId);
if (!$order->canShip()) {
   throw new \Magento\Framework\Exception\LocalizedException(
       __("You can't create the Shipment of this order.")
   );
}
$orderShipment = $convertOrder->toShipment($order);
foreach ($order->getAllItems() as $orderItem) {
   // Check virtual item and item Quantity
   if (!$orderItem->getQtyToShip() || $orderItem->getIsVirtual()) {
       continue;
   }
   $qty = $orderItem->getQtyToShip();
   $shipmentItem = $convertOrder->itemToShipmentItem($orderItem)->setQty($qty);
   $orderShipment->addItem($shipmentItem);
}
$orderShipment->register();
$orderShipment->getOrder()->setIsInProcess(true);
// Save created Order Shipment
$orderShipment->save();
$orderShipment->getOrder()->save();
// Send Shipment Email
$shipmentNotifier->notify($orderShipment);

And this is how you can create a shipment in Magento 2 programmatically. Not that hard, right? If you prefer doing Magento tasks via coding, then don't hesitate to try out this solution.

However, it might happen that customers want to cancel a shipment, even though you've already created one. Thus, it will be useful to learn how to cancel a shipment in Magento 2 to avoid any hitches while processing orders.