Hello Magento Friends,
In Magento 2, managing order statuses is key to streamlining order fulfillment. By default, Magento provides the ability to create shipments to orders, but sometimes you want to either restrict or allow the Ship button only to selected order statuses.
For example:
- You may want to remove the Ship button when an order is “Pending Payment” or “Canceled.”
- You may want it to be enabled only for Paid or Processing orders.
In this tutorial, we’ll show you how to enable/disable the Ship button in Magento 2 depending on the order status.

Why Control the Ship Button in Magento 2?
Controlling the availability of the Ship button is important for merchants.
- Reduces the chances of mistakes such as shipping out unpaid or canceled orders.
- Simplifies workflows by shipping only when necessary.
- Improves customer experience by removing errors in order processing.
By default, the ship button will be visible as soon as the order gets placed.

Steps to Disable Ship Button Based on Order Status in Magento 2:
Step 1: Create a di.xml file at the given path
app/code/Vendor/Extension/etc/adminhtml/di.xml
Now add the code as follows:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Backend\Block\Widget\Context">
<plugin name="remove_button_from_sales_veiw" type="Vendor\Extension\Plugin\Widget\Context" sortOrder="1"/>
</type>
</config>
Step 2: Create a Context.php file at the given path
app/code/Vendor/Extension/Plugin/Widget/Context.php
Now add the code as follows:
<?php
namespace Vendor\Extension\Plugin\Widget;
use Magento\Framework\Registry;
class Context
{
/**
* @var Registry
*/
private $registry;
/**
* Context constructor.
*
* @param Registry $registry
*/
public function __construct(
Registry $registry
) {
$this->registry = $registry;
}
/**
* @param \Magento\Backend\Block\Widget\Context $subject
* @param \Magento\Backend\Block\Widget\Button\ButtonList $buttonList
* @return mixed
*/
public function afterGetButtonList(
\Magento\Backend\Block\Widget\Context $subject,
$buttonList
) {
if ($subject->getRequest()->getFullActionName() == 'sales_order_view') {
if ($this->getOrder() && ($this->getOrder()->getStatus() == 'pending')) {
$buttonList->remove('order_ship');
}
}
return $buttonList;
}
/**
* Retrieve order model object
*
* @return \Magento\Sales\Model\Order
*/
private function getOrder()
{
return $this->registry->registry('sales_order');
}
}
Replace the following condition with your condition:
if ($this->getOrder() && ($this->getOrder()->getStatus() == 'pending'))
Output:
Using the above code, the ship button will be disabled.
Conclusion:
Controlling the Ship button in Magento 2 will also ensure that only eligible orders can ship out, which will help store admins avoid errors and have a much smoother workflow. With only a small customization, you can enable or disable the Ship button based on the order status and optimize your order fulfillment process.
Happy Coding!

FAQ
- What is the Ship button in Magento 2?
The Ship button in Magento 2 provides a means for store admins to create a shipment for an order, and is typically available whenever an order is ready to ship.
- Why would I want to disable the Ship button?
You would want to disable it as a way to help prevent errors like shipping canceled, unpaid, or on-hold orders. Disabling the Ship button would essentially help you only ship valid orders.
- Can I choose which order statuses allow shipping?
Yes. You can configure order statuses in Magento 2 to only enable the Ship button for a specified status, like “Processing” or “Complete”, and disable allowed order statuses like “Pending Payment” or “Canceled”.
- Will disabling the Ship button affect my customers?
No. Disabling the Ship button will only affect the Magento 2 admin panel. Customers will see no difference on the front edge of your store.