Create Invoice Programmatically in Magento 2

As we all know, the invoice will be created after the store owner received the payment for an order. In online payment methods (PayPal, Authorize.net, etc), the invoice will be automatically created after they captured the payment. But in offline payment methods (Check / Money Order, Bank Transfer, etc), the store owner will have to create the invoice on the admin side by manually. If you wish to create the invoice on the admin side, follow the below simple steps,

  • Log in to your Magento 2 admin.
  • Click SALES in the admin sidebar.
  • Choose Orders from the Operations section.
  • From the order grid, click View link to which order you wish to create the invoice. The order view page will be opened.
  • Click the Invoice button on the header section and the New Invoice page will be opened.
  • Enter all the valid data and click the Submit Invoice button to create the invoice.

After completing the above steps, you can see the newly created invoice by clicking the Invoice tab on the order view page.

In some cases, you may require to create the invoice by programmatically. So here is the full set of code which will help you to create the invoice programmatically.

Create Invoice Using Dependence Injection

Here is the full set of code to create the invoice using dependence injection method,

<?php
namespace BlogTreat\CreateInvoice\Controller;

class Invoice extends \Magento\Framework\App\Action\Action
{
    /**
     * @var \Magento\Sales\Api\OrderRepositoryInterface
     */
    protected $orderRepository;

    /**
     * @var \Magento\Sales\Model\Service\InvoiceService
     */
    protected $invoiceService;

    /**
     * @var \Magento\Framework\DB\TransactionFactory
     */
    protected $transactionFactory;

    /**
     * @var \Magento\Framework\Message\ManagerInterface
     */
    protected $messageManager;

    /**
     * @var \Magento\Sales\Model\Order\Email\Sender\InvoiceSender
     */
    protected $invoiceSender;

    public function __construct(
        \Magento\Framework\App\Action\Context $context,
        \Magento\Sales\Api\OrderRepositoryInterface $orderRepository,
        \Magento\Sales\Model\Service\InvoiceService $invoiceService,
        \Magento\Framework\DB\TransactionFactory $transactionFactory,
        \Magento\Framework\Message\ManagerInterface $messageManager,
        \Magento\Sales\Model\Order\Email\Sender\InvoiceSender $invoiceSender,
        array $data = []
    ) {
        $this->orderRepository = $orderRepository;
        $this->invoiceService = $invoiceService;
        $this->transactionFactory = $transactionFactory;
        $this->messageManager = $messageManager;
        $this->invoiceSender = $invoiceSender;
        parent::__construct($context);
    }

    /**
     * order invoice controller.
     *
     * @return \Magento\Framework\View\Result\Page
     */
    public function execute()
    {
        $orderId = 1;
        try {
            $order = $this->orderRepository->get($orderId);
            if (!$order->getId()) {
                throw new \Magento\Framework\Exception\LocalizedException(
                    __('The order no longer exists.')
                );
            }

            if(!$order->canInvoice()) {
                throw new \Magento\Framework\Exception\LocalizedException(
                    __('The order does not allow an invoice to be created.')
                );
            }

            $invoice = $this->invoiceService->prepareInvoice($order);
            if (!$invoice) {
                throw new \Magento\Framework\Exception\LocalizedException(
                    __('Can\'t save the invoice right now.')
                );
            }

            if (!$invoice->getTotalQty()) {
                throw new \Magento\Framework\Exception\LocalizedException(
                    __('Can\'t able to create an invoice.')
                );
            }

            $invoice->setRequestedCaptureCase(\Magento\Sales\Model\Order\Invoice::CAPTURE_OFFLINE);
            $invoice->register();
            $invoice->getOrder()->setCustomerNoteNotify(false);
            $invoice->getOrder()->setIsInProcess(true);
            $order->addStatusHistoryComment(__('Notified customer about invoice #%1.', $invoice->getId()));

            $transactionSave = $this->transactionFactory->create()
                                    ->addObject($invoice)
                                    ->addObject($invoice->getOrder());
            $transactionSave->save();

            try {
                $this->invoiceSender->send($invoice);
            } catch (\Exception $e) {
                $this->messageManager->addError(__('Can\'t send the invoice email right now.'));
            }
        } catch (\Exception $e) {
            $this->messageManager->addError($e->getMessage());
        }
    }
}

Create Invoice Using Object Manager

Here is the full set of code to create the invoice using object manager method,

<?php
use Magento\Framework\App\Bootstrap;
  
/**
 * If the external file is in the root folder
 */
require __DIR__ . '/app/bootstrap.php';
 
$params = $_SERVER;
  
$bootstrap = Bootstrap::create(BP, $params);
  
$obj = $bootstrap->getObjectManager();
  
$state = $obj->get('Magento\Framework\App\State');
$state->setAreaCode('adminhtml');

$orderId = 1;
$order = $obj->get('\Magento\Sales\Api\OrderRepositoryInterface')->get($orderId);
if($order->canInvoice()) {
	$invoice = $obj->get('\Magento\Sales\Model\Service\InvoiceService')->prepareInvoice($order);
	$invoice->setRequestedCaptureCase(\Magento\Sales\Model\Order\Invoice::CAPTURE_OFFLINE);
	$invoice->register();
	$invoice->getOrder()->setCustomerNoteNotify(false);
	$invoice->getOrder()->setIsInProcess(true);

	$transaction = $obj->get('\Magento\Framework\DB\Transaction')->addObject(
		$invoice
	)->addObject(
		$invoice->getOrder()
	);
	$transaction->save();

	$obj->get('\Magento\Sales\Model\Order\Email\Sender\InvoiceSender')->send($invoice);
	$order->addStatusHistoryComment(
		__('Notified customer about invoice #%1.', $invoice->getId())
	)
	->setIsCustomerNotified(true)
	->save();
}

Read Also: Programmatically Create New Order in Magento 2

Hope this helps.

Leave a Reply

Your email address will not be published. Required fields are marked *