Introduction
Invoice is an important part of the Magento Order Process. Generally, Magento generates an invoice for an order when the payment for the order is successfully captured. However, you might come up with cases when you do not depend on the payment status of the order for generating the invoice.
For example, instead of physical products, if your store sells services (virtual products) where customers book the service and do the payment when they receive the service. In this case, you might need to generate the invoice for the order before receiving the payment. In such cases you can create invoice programmatically through a Magento 2 Module.
In this tutorial we will learn how to create invoice programmatically in Magento 2. Depending upon your requirement you can determine whether you need to write the code to create invoice programmatically in a Controller or Model or may be a Cron. For this tutorial, I will use an example of Model.
Method to Create Invoice Programmatically in Magento 2
Create a new model in your module and add the below code.
For example: app/code/Vendor/Module/Model/CreateInvoice.php
<?php
namespace Vendor\Module\Model;
use Magento\Sales\Api\OrderRepositoryInterface;
use Magento\Sales\Model\Order\Email\Sender\InvoiceSender;
use Magento\Framework\DB\TransactionFactory;
use Magento\Sales\Model\Service\InvoiceService;
class CreateInvoice
{
protected $_orderRepository;
protected $_invoiceSender;
protected $_transactionFactory;
protected $_invoiceService;
public function __construct(
OrderRepositoryInterface $orderRepository,
InvoiceSender $invoiceSender,
TransactionFactory $transactionFactory,
InvoiceService $invoiceService
) {
$this->_orderRepository = $orderRepository;
$this->_invoiceSender = $invoiceSender;
$this->_transactionFactory = $transactionFactory;
$this->_invoiceService = $invoiceService;
}
public function execute($orderId)
{
$order = $this->_orderRepository->get($orderId);
if ($order->canInvoice()) {
$invoice = $this->_invoiceService->prepareInvoice($order);
$invoice->setRequestedCaptureCase(\Magento\Sales\Model\Order\Invoice::CAPTURE_OFFLINE);
$invoice->register();
$invoice->getOrder()->setCustomerNoteNotify(true);
$invoice->getOrder()->setIsInProcess(true);
$invoice->save();
$transactionSave = $this->_transactionFactory->create()->addObject(
$invoice
)->addObject(
$invoice->getOrder()
);
$transactionSave->save();
try {
$this->_invoiceSender->send($invoice);
$order->addCommentToStatusHistory(
__('Notified customer about invoice #%1.', $invoice->getId())
)->setIsCustomerNotified(true);
} catch (\Magento\Framework\Exception\LocalizedException $e) {
$order->addStatusHistoryComment('Cannot send the invoice Email right now.', false);
}
$order->addStatusHistoryComment('Automatically Invoice Generated.', false);
$order->save();
}
}
}
Similarly, check this tutorial to Create Customer Accounts Programmatically in Magento 2.
I hope this tutorial is helpful for you. For any queries, please leave a comment.