Magento 2 How To Programmatically Create Invoice

In Magento 2, there is facility of partial payments but order status does not depend on the total amount paid.

Every time a partial payment installment is paid, Magento 2 considers an order fulfilled and generates an invoice but we do not want to generate the invoice every time. So the solution is to programmatically create invoice in Magento 2.

Method to create invoice in Magento 2 programmatically:

  1. Create a xml file routes.xml in app/code/Magemeta/Invoice/etc/frontend Folder add the following code:
<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="standard">
        <route frontName="mageinvoice" id="mageinvoice">
            <module name="Magemeta_Invoice"/>
        </route>
    </router>
</config>

2. Create a php file as Invoice.php in app/code/Magemeta/Invoice/Controller folder and write the following code:

<?php
 
namespace Magemeta\Invoice\Controller;
 
use Magento\Framework\App\Action\Context;
use Magento\Framework\App\Action\Action;
use Magento\Sales\Api\OrderRepositoryInterface;
use Magento\Sales\Model\Service\InvoiceService;
use Magento\Framework\DB\Transaction;
use Magento\Sales\Model\Order\Email\Sender\InvoiceSender;
class Invoice extends Action
{
    protected $orderRepository;
    protected $invoiceService;
    protected $transaction;
    protected $invoiceSender;
 
    public function __construct(
        Context $context,
        OrderRepositoryInterface $orderRepository,
        InvoiceService $invoiceService,
        InvoiceSender $invoiceSender,
        Transaction $transaction
    )
    {
        $this->orderRepository = $orderRepository;
        $this->invoiceService = $invoiceService;
        $this->transaction = $transaction;
        $this->invoiceSender = $invoiceSender;
        parent::__construct($context);
    }
 
    public function execute()
    {
        $orderId = 10; //it should be an order id
        $order = $this->orderRepository->get($orderId);
        if ($order->canInvoice()) {
            $invoice = $this->invoiceService->prepareInvoice($order);
            $invoice->register();
            $invoice->save();
            $transactionSave = $this->transaction->addObject(
                $invoice
            )->addObject(
                $invoice->getOrder()
            );
            $transactionSave->save();
            $this->invoiceSender->send($invoice);
 //Send Invoice mail to customer
            $order->addStatusHistoryComment(
                __('Notified customer for invoice creation #%1.', $invoice->getId())
            )
                ->setIsCustomerNotified(true)
                ->save();
        }
    }
}

We can call this controller as per our requirement in our custom module.

Leave a Reply