🔥 Just Launched! Werra Premium Template for HyväSee it in Action

How to decrease Magento 2 stock inventory on Invoice instead of Order

By Sanjay JethvaUpdated on May 22, 2025 2 min read

In default Magento 2, the inventory is managed based on the orders placed. For example, the inventory decreases from 1 to 0 when a user places the order. However, what if that order was a test order. Or, if the user chose Cash On Delivery method and the payment was not captured due to some reasons!

In such scenarios, the storefront shows out of stock which is not the case in reality. Due to failure in payment processing, the order was cancelled. Hence, the product was not out of stock. If any other visitor is interested in that product, your store might lose a sale due to this conflict!

The solution is to manage the stock inventory when an invoice is generated instead of the order placed. That’s because the invoice is only generated once the payment is confirmed in any case.

The programmatic solution to decrease Magento 2 stock inventory on invoice instead of order is given here.

Note: The solution works with Magento 2.2.x

Steps to Decrease Magento 2 Stock Inventory on Invoice Instead of Order:

Step 1: Set ‘No’ to Admin > Store > Catalog > Catalog > Inventory > Decrease Stock When Order is placed

Step 2: Create observer sales_order_invoice_save_after in Vendor\Extension\etc\adminhtml\events.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="sales_order_invoice_save_after">
        <observer name="meetanshi_sales_order_invoice_save_after" instance="Vendor\Extension\Observer\UpdateInventory"/>
    </event>
</config>

Step 3: Create observer file

<?php
namespace Vendor\Extension\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Event\Observer;
use Magento\CatalogInventory\Api\StockRegistryInterface;
use Magento\Catalog\Model\ProductRepository;
class UpdateInventory implements ObserverInterface
{
    protected $productRepository;
    protected $stockRegistry;
    public function __construct(ProductRepository $productRepository,
    StockRegistryInterface $stockRegistry)
    {
        $this->productRepository = $productRepository;
        $this->stockRegistry = $stockRegistry;
    }
    public function execute(Observer $observer)
    {
        try 
        {
            $invoice = $observer->getEvent()->getInvoice();
            $invoiceItems = $invoice->getAllItems();
            foreach ($invoiceItems as $item) 
            {
                $productId = $item->getProductId();
                $product = $this->productRepository->getById($productId);
                $sku = $product->getSku();
                $stockItem = $this->stockRegistry->getStockItemBySku($sku);
                $qty = $stockItem->getQty() - $item->getQty();
                $stockItem->setQty($qty);
                $stockItem->setIsInStock((bool)$qty);
                $this->stockRegistry->updateStockItemBySku($sku, $stockItem);
            }
        } 
        catch (\Exception $e) 
        {
            return $e->getMessage();
        }
    }
}

Implement the above solution and your Magento 2 store stock inventory management will be flawless! No visitors will ever face a false out-of-stock status for their interested products. Get Product salable quantity in Magento 2 to have the sum of available resources, grouped in stocks.

Thank you.

Sanjay Jethva Full Image
Article bySanjay Jethva

Sanjay is the co-founder and CTO of Meetanshi with hands-on expertise with Magento since 2011. He specializes in complex development, integrations, extensions, and customizations. Sanjay is one the top 50 contributor to the Magento community and is recognized by Adobe. His passion for Magento 2 and Shopify solutions has made him a trusted source for businesses seeking to optimize their online stores. He loves sharing technical solutions related to Magento 2 & Shopify.