In Magento, we need to generate the invoice of an order automatically when the order is placed, or the payment status is successful for a particular order.
If you want to programmatically create the invoice for a particular order, then please follow the solution below.
Here you can learn how to create an invoice for a particular order or a part of a particular order using item IDs.
Create an invoice for a new order-
Step 1. Create a Controller CreateInvoice.php in your custom module at app / code / { vendorname } / { modulename } / Controller / { Action } /
Write the code below inside your controller file (CreateInvoice.php) :
<?php
/**
* Webkul Software.
*
* @category Webkul
* @package Webkul_Grid
* @author Webkul
* @copyright Copyright (c) 2010-2016 Webkul Software Private Limited (https://webkul.com)
* @license https://store.webkul.com/license.html
*/
namespace Webkul\TestBlogs\Controller\Blogs;
class CreateInvoice 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\Transaction
*/
protected $_transaction;
public function __construct(
\Magento\Framework\App\Action\Context $context,
\Magento\Sales\Api\OrderRepositoryInterface $orderRepository,
\Magento\Sales\Model\Service\InvoiceService $invoiceService,
\Magento\Sales\Model\Order\Email\Sender\InvoiceSender $invoiceSender,
\Magento\Framework\DB\Transaction $transaction
) {
$this->_orderRepository = $orderRepository;
$this->_invoiceService = $invoiceService;
$this->invoiceSender = $invoiceSender;
$this->_transaction = $transaction;
parent::__construct($context);
}
/**
* Marketplace order invoice controller.
*
* @return \Magento\Framework\View\Result\Page
*/
public function execute()
{
$orderId = 9; //order id for which want to create invoice
$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 notification code
$order->addStatusHistoryComment(
__('Notified customer about invoice #%1.', $invoice->getId())
)
->setIsCustomerNotified(true)
->save();
}
}
}
The above example will let you generate an order invoice for the complete order.
Now, If there are multiple items in your order and you want to generate an invoice for a particular item in your order, then please follow the code below to be able to do so.
Step 1. Create a Controller CreateInvoice.php in your custom module at app / code / { vendorname } / { modulename } / Controller / { Action } /
Create an invoice for a particular item in your order
<?php
/**
* Webkul Software.
*
* @category Webkul
* @package Webkul_Grid
* @author Webkul
* @copyright Copyright (c) 2010-2016 Webkul Software Private Limited (https://webkul.com)
* @license https://store.webkul.com/license.html
*/
namespace Webkul\Grid\Controller;
class CreateInvoice 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\Transaction
*/
protected $_transaction;
public function __construct(
\Magento\Framework\App\Action\Context $context,
\Magento\Sales\Api\OrderRepositoryInterface $orderRepository,
\Magento\Sales\Model\Order\Email\Sender\InvoiceSender $invoiceSender,
\Magento\Sales\Model\Service\InvoiceService $invoiceService,
\Magento\Framework\DB\Transaction $transaction
) {
$this->_orderRepository = $orderRepository;
$this->_invoiceService = $invoiceService;
$this->invoiceSender = $invoiceSender;
$this->_transaction = $transaction;
parent::__construct($context);
}
/**
* Marketplace order invoice controller.
*
* @return \Magento\Framework\View\Result\Page
*/
public function execute()
{
$orderId = 1; //order id for which want to create invoice
$order = $this->_orderRepository->get($orderId);
if($order->canInvoice()) {
$itemsArray = ['80'=>2]; //here 80 is order item id and 2 is it's quantity to be invoice
$shippingAmount = '10.00';
$subTotal = '110.00';
$baseSubtotal = '110.00';
$grandTotal = '110.00';
$baseGrandTotal = '110.00';
$invoice = $this->_invoiceService->prepareInvoice($order, $itemsArray);
$invoice->setShippingAmount($shippingAmount);
$invoice->setSubtotal($subTotal);
$invoice->setBaseSubtotal($baseSubtotal);
$invoice->setGrandTotal($grandTotal);
$invoice->setBaseGrandTotal($baseGrandTotal);
$invoice->register();
$transactionSave = $this->_transaction->addObject(
$invoice
)->addObject(
$invoice->getOrder()
);
$transactionSave->save();
$this->invoiceSender->send($invoice);
//send notification code
$order->addStatusHistoryComment(
__('Notified customer about invoice #%1.', $invoice->getId())
)
->setIsCustomerNotified(true)
->save();
}
}
}
How to programmatically create an invoice in Magento
In this way, you can create an invoice for a particular product in an order or for a complete order. After creation of the invoice, you can check it in the admin panel’s sales order grid.
You may also check the links below:
- https://webkul.com/blog/how-to-programmatically-create-shipment-in-magento2/
- https://developer.adobe.com/commerce/webapi/rest/tutorials/inventory/create-invoice/
If you require technical support, feel free to email us at [email protected]
Additionally, explore a wide array of solutions to boost your store’s capabilities by visiting our Adobe Commerce modules section and Adobe Commerce marketplace addons.
Or looking to improve your store’s speed and overall performance? Check out our Magento 2 Speed & Optimization services.
Get expert support and build customized solutions by hiring skilled Adobe Commerce developers for your project.

12 comments
This is working fine. I am creating invoice using ajax request.
I am using try catch in my controller.
But I am having problem with this code :
$this->invoiceSender->send($invoice);
When I removed this code ajax response in successful. Please suggest.
Sure we will try to add the blog in future for the topic asked. Thanks
We are working on warehouse management integration for our client.
While we receive order updates from warehouse, we are doing the following activities:
1. invoice creation
2. capture invoice amount that was authorized during order placement
3. create shipment
4. send notification email
5. order cancellation (if applicable)
6. create credit memo (if applicable, while cancelling invoices)
We have to do this process in a loop, for each order updates that we receive.
While doing this process for n number of orders, the script always process the 1st order on the collection.
When it tries to process for the 2nd order, we are getting the below error:
“set order for existing transactions not allowed”
Could you please highlight the cause for this error and solution to fix this error.
I tried the same solution for partial invoice but when i checked from sales_order_item table it shows other products as well. and when i open invoice from admin it does’t shows the invoice items. It shows blank under invoice items
1. Why, in the first example, you save the invoice twice ? first with the $invoice->save() statement, then with the $transactionSave
2. Is there a point to setting the isInProcess flag on the Order before saving it ? $invoice->getOrder()->setIsInProcess(true);
Like you want to create invoice for an order using a controller file (which we used in this post), then you will need to create a controller file CreateInvoice.php (as created in this post) in the path magnetoroot/app/code/VendorDirectory/ModuleName/Controller.
Thanks!
Thanks!