---
title: "Magento 2: How to Add Download Invoice Button in Order Email?"
url: "https://magecomp.com/blog/magento-2-add-download-invoice-button-in-order-email/"
date: "2022-11-14T15:52:33+00:00"
modified: "2025-02-13T13:02:10+00:00"
author:
  name: "Dhiren Vasoya"
  url: "https://magecomp.com/"
categories:
  - "How To"
  - "Magento 2"
word_count: 1861
reading_time: "10 min read"
summary: "Hello Magento Friends,"
description: "Let your customers easily download order invoice from the order confirmation email in Magento 2. Check out the steps."
keywords: "How To, Magento 2"
language: "en"
schema_type: "Article"
related_posts:
  - title: "How to set image gallery Fotorama thumbnail as vertical view in Magento 2"
    url: "https://magecomp.com/blog/set-image-gallery-fotorama-thumbnail-as-vertical-view-in-magento-2/"
  - title: "Best Magento 2 Google One Tap Login Extensions in 2026"
    url: "https://magecomp.com/blog/best-magento-2-google-one-tap-login-extensions/"
  - title: "Solved: cluster_block_exception [TOO_MANY_REQUESTS/12/disk usage exceeded flood-stage watermark, index has read-only-allow-delete block] in Magento 2"
    url: "https://magecomp.com/blog/solved-cluster-block-exception-magento-2/"
---

# Magento 2: How to Add Download Invoice Button in Order Email?

_Published: November 14, 2022_  
_Author: Dhiren Vasoya_  

![How to Add Download Invoice Button in Order Email in M2](https://magecomp.com/blog/wp-content/uploads/2022/11/How-to-Add-Download-Invoice-Button-in-Order-Email-in-M2-1024x512.webp)

**Hello Magento Friends,**

In today’s tutorial, I will explain How to Add a “Download Invoice” Button in Magento 2 Order Email.
[![Magento version upgrade](https://magecomp.com/blog/wp-content/uploads/2025/02/Magento-2-Version-Upgrade-CTA-3.webp)](https://magecomp.com/services/magento-upgrade-services/)

Once the payment is completed successfully, an [**order confirmation email**](https://magecomp.com/magento-2-order-confirmation-email.html) is sent to the customer’s email. Order confirmation email helps customers get detailed information about their orders. You can allow users to easily download order invoice from the order confirmation email itself in Magento 2.
Let’s look at the steps to add download invoice button in the order email in Magento 2.
## Steps to Add Download Invoice Button in Order Email in Magento 2:
**Step 1:** Firstly, go to the below file path
**app\code\Vendor\Extension\view\frontend\layout\sales_email_order_items.xml**

Then add the code as follows
```
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd" label="Email Order Items List" design_abstraction="custom">
    <body>
        <referenceBlock name="items">
            <action method="setTemplate">
                <argument name="template" translate="true" xsi:type="string">Vendor_Extension::email/items.phtml</argument>
            </action>
        </referenceBlock>
    </body>
</page>
```

**Step 2:** Next, move to the file path as given below
**app\code\Vendor\Extension\view\frontend\templates\email\items.phtml**

And embed the below code
```
<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

// phpcs:disable Magento2.Templates.ThisInTemplate

/** @var $block MagentoSalesBlockOrderEmailItems */
?>
<?php $_order = $block->getOrder() ?>
<?php if ($_order) : ?>
    <?php $_items = $_order->getAllItems(); ?>
        <?php foreach ($_items as $_item) : ?>
            <?php if (!$_item->getParentItem()) : ?>
                    <?= $block->getItemHtml($_item) ?>
            <?php endif; ?>
        <?php endforeach; ?>
        <tr>
            <td style="font-size: 18px;font-weight: bold;border-bottom: 1px solid #ccc;padding-bottom: 10px;font-family: Arial, Helvetica, sans-serif;">
                Order Total
            </td>
        </tr>

        <tr class="order-totals">
            <?= $block->getChildHtml('order_totals') ?>
        </tr>
       <?php if(count($_order->getInvoiceCollection())):
        $objectManager =  MagentoFrameworkAppObjectManager::getInstance();

        $storeManager = $objectManager->get('MagentoStoreModelStoreManagerInterface');
        $store = $storeManager->getStore();
        $baseUrl = $store->getBaseUrl();
        ?>
        <tr>
            <td style="text-align: center;font-family: Arial, Helvetica, sans-serif;">
                <a href="&lt;?= $baseUrl ?" data-wpel-link="internal" target="_blank" rel="follow">emailcustomisation/invoice/printinvoice/order_id/<?= $_order->getId() ?>" class="download" >Download
                </a>
            </td>
        </tr>
        <?php endif; ?>
    <?php if ($this->helper(MagentoGiftMessageHelperMessage::class)
            ->isMessagesAllowed('order', $_order, $_order->getStore())
        && $_order->getGiftMessageId()
    ) : ?>
        <?php $_giftMessage = $this->helper(MagentoGiftMessageHelperMessage::class)
            ->getGiftMessage($_order->getGiftMessageId()); ?>
        <?php if ($_giftMessage) : ?>
            <br />
            <table class="message-gift">
                <tr>
                    <td>
                        <h3><?= $block->escapeHtml(__('Gift Message for this Order')) ?></h3>
                        <strong><?= $block->escapeHtml(__('From:')) ?></strong> <?= $block->escapeHtml($_giftMessage->getSender()) ?>
                        <br /><strong><?= $block->escapeHtml(__('To:')) ?></strong> <?= $block->escapeHtml($_giftMessage->getRecipient()) ?>
                        <br /><strong><?= $block->escapeHtml(__('Message:')) ?></strong>
                        <br /><?= $block->escapeHtml($_giftMessage->getMessage()) ?>
                    </td>
                </tr>
            </table>
        <?php endif; ?>
    <?php endif; ?>
<?php endif; ?>
```

**Step 3:** Now navigate to the following file path
**app\code\Vendor\Extension\etc\frontend\routes.xml**

Then add the below code snippet
```
<?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 id="yourrouteid" frontName="yourfrountname">
            <module name="Vendor_Extension" />
        </route>
    </router>
</config>
```

**Step 4:** Next, you need to go to the below-mentioned file path
**app\code\Vendor\Extension\Controller\Invoice\Printinvoice.php**

And include the code as given below
```
<?php

namespace VendorExtensionControllerInvoice;

use MagentoFrameworkAppResponseInterface;
use MagentoFrameworkAppFilesystemDirectoryList;

class Printinvoice extends MagentoFrameworkAppActionAction
{
    /**
     * Authorization level of a basic admin session
     *
     * @see _isAllowed()
     */
    const ADMIN_RESOURCE = 'Magento_Sales::sales_invoice';

    /**
     * @var MagentoFrameworkAppResponseHttpFileFactory
     */
    protected $_fileFactory;

    /**
     * @var MagentoBackendModelViewResultForwardFactory
     */
    protected $resultForwardFactory;

    /**
     * @param MagentoBackendAppActionContext $context
     * @param MagentoFrameworkAppResponseHttpFileFactory $fileFactory
     * @param MagentoBackendModelViewResultForwardFactory $resultForwardFactory
     */
    public function __construct(
        MagentoFrameworkAppActionContext $context,
        MagentoFrameworkAppResponseHttpFileFactory $fileFactory,
        MagentoBackendModelViewResultForwardFactory $resultForwardFactory,
        MagentoSalesModelOrderFactory $order)
    {
        $this->_fileFactory = $fileFactory;
        parent::__construct($context);
        $this->resultForwardFactory = $resultForwardFactory;
        $this->order = $order;
    }

    /**
     * @return ResponseInterface|void
     * @throws Exception
     */
    public function execute()
    {
       $orderId = $this->getRequest()->getParam('order_id');
       $orderdetails = $this->order->create()->load($orderId);
        $invoiceId = 0;
        foreach ($orderdetails->getInvoiceCollection() as $invoice)
        {
            $invoiceId = $invoice->getId();
        }
        if ($invoiceId != 0)
        {
            $invoice = $this->_objectManager->create(
                MagentoSalesApiInvoiceRepositoryInterface::class
            )->get($invoiceId);
            if ($invoice)
            {
                $pdf = $this->_objectManager->create(MagentoSalesModelOrderPdfInvoice::class)->getPdf([$invoice]);
                $date = $this->_objectManager->get(
                    MagentoFrameworkStdlibDateTimeDateTime::class
                )->date('Y-m-d_H-i-s');
                $fileContent = ['type' => 'string', 'value' => $pdf->render(), 'rm' => true];

                return $this->_fileFactory->create(
                    'invoice' . $date . '.pdf',
                    $fileContent,
                    DirectoryList::VAR_DIR,
                    'application/pdf'
                );
            }
        }
        else
        {
            return;
            return $this->resultForwardFactory->create()->forward('noroute');
        }
    }
}
```

[![Magento Malware Removal](https://magecomp.com/blog/wp-content/uploads/2025/02/Magento-Malware-Removal-CTA-6.webp)](https://magecomp.com/magento-malware-removal.html)

**Step 5:** In this step, move to the following file path
**app\code\Vendor\Extension\Model\Order\Pdf\Invoice.php**

Then incorporate the following piece of code
```
<?php

namespace VendorExtensionModelOrderPdf;

use PHPQRCodeQRcode;

class Invoice extends MagentoSalesModelOrderPdfInvoice
{
    protected function _setFontBold($object, $size = 7)
    {
        $font = Zend_Pdf_Font::fontWithPath($this->getFontPath());
        $object->setFont($font, $size);
        return $font;
    }

    public function newPage(array $settings = [])
    {
        $page = $this->_getPdf()->newPage(Zend_Pdf_Page::SIZE_A4);
        $this->_getPdf()->pages[] = $page;
        $this->y = 800;
        if (!empty($settings['table_header']))
        {
            $this->_drawHeader($page);
        }
        return $page;
    }

    protected function _drawHeader(Zend_Pdf_Page $page)
    {
        $this->_setFontRegular($page, 10);
        $page->setFillColor(new Zend_Pdf_Color_RGB(0.93, 0.92, 0.92));
        $page->setLineColor(new Zend_Pdf_Color_GrayScale(0.5));
        $page->setLineWidth(0.5);
        $page->drawRectangle(25, $this->y, 570, $this->y - 15);
        $this->y -= 10;
        $page->setFillColor(new Zend_Pdf_Color_RGB(0, 0, 0));

        $taxableAmountText = $this->string->split('Taxable Amount', 8);
        $lines[0][] = ['text' => __('Products'), 'feed' => 35];

        $lines[0][] = ['text' => __('Qty'), 'feed' => 150, 'align' => 'right'];

        $lines[0][] = ['text' => __('Price'), 'feed' => 185, 'align' => 'right'];

        $lines[0][] = ['text' => __('Subtotal'), 'feed' => 235, 'align' => 'right'];
        $lines[0][] = ['text' => __('Discount'), 'feed' => 290, 'align' => 'right'];

        $lines[0][] = ['text' => __('Tax Amt'), 'feed' => 345, 'align' => 'right'];
        $lines[0][] = ['text' => __('Custom'), 'feed' => 400, 'align' => 'right'];

        $lines[0][] = ['text' => __('Row Total'), 'feed' => 570, 'align' => 'right'];

        $lineBlock = ['lines' => $lines, 'height' => 5, $this->y];

        $this->drawLineBlocks($page, [$lineBlock], ['table_header' => true]);
        $page->setFillColor(new Zend_Pdf_Color_GrayScale(0));
        $this->y -= 20;
    }

    protected function _setFontRegular($object, $size = 7)
    {
        $font = Zend_Pdf_Font::fontWithPath($this->getFontPath());
        $object->setFont($font, $size);
        return $font;
    }

   protected function _drawFooter(Zend_Pdf_Page $page)
   {
        $this->_setFontRegular($page, 10);
        $this->y -= 10;
        $page->setFillColor(new Zend_Pdf_Color_RGB(0, 0, 0));
    }
    protected function _setFontItalic($object, $size = 7)
    {
        $font = Zend_Pdf_Font::fontWithPath($this->getFontPath());
        $object->setFont($font, $size);
        return $font;
    }
}
```

**Step 6:** At last, go to the below file path
**app\code\Vendor\Extension\Model\Sales\Order\Pdf\Items\Invoice.php**

And insert the below fragment of code
```
<?php
namespace VendorExtensionModelSalesOrderPdfItems;
use MagentoBundleModelSalesOrderPdfItemsInvoice as InvoiceDefualt;
class Invoice extends InvoiceDefualt
{
    public function draw()
    {
 		$draw = $this->drawChildrenItems();
        		$draw = $this->drawCustomOptions($draw);
		$page = $this->getPdf()->drawLineBlocks($this->getPage(), $draw, ['table_header' => true]);
		$this->setPage($page);
    }
    private function drawChildrenItems(): array
    {
        $this->_setFontRegular();
        $prevOptionId = '';
        $drawItems = [];
        $optionId = 0;
        $lines = [];
        foreach ($this->getChildren($this->getItem()) as $childItem)
        {
            $index = array_key_last($lines) !== null ? array_key_last($lines) + 1 : 0;
            $attributes = $this->getSelectionAttributes($childItem);
            if (is_array($attributes))
            {
                $optionId = $attributes['option_id'];
            }
            if (!isset($drawItems[$optionId]))
            {
                $drawItems[$optionId] = ['lines' => [], 'height' => 15];
            }
            if ($childItem->getOrderItem()->getParentItem() && $prevOptionId != 		$attributes['option_id'])
            {
                $lines[$index][] = [
                    'font' => 'italic',
                    'text' => $this->string->split($attributes['option_label'], 35, true, true),
                    'feed' => 35,
                ];
                $index++;
                $prevOptionId = $attributes['option_id'];
            }
            if ($childItem->getOrderItem()->getParentItem())
            {
                $feed = 30;
                $name = $this->getValueHtml($childItem)."<br /> SKU :".$childItem-			>getSku();
            }
            else
            {
                $feed = 25;
                $name = $childItem->getName();
            }
            $lines[$index][] = ['text' => $this->string->split($name, 15, true, true), 'feed' => $feed];
            if ($this->canShowPriceInfo($childItem))
            {
	            $tax = $this->getOrder()->formatPriceTxt($childItem->getTaxAmount());
	            $item = $this->getItem();
	            $this->_item = $childItem;
	            $feedPrice = 140;
	            $feedSubtotal = $feedPrice + 185;
	            foreach ($this->getItemPricesForDisplay() as $priceData)
	            {
	                if (isset($priceData['label']))
	                {
	                    // draw Price label
	                    $lines[$index][] = ['text' => $priceData['label'], 'feed' => $feedPrice, 'align' => 'right'];

	                    // draw Subtotal label
	                    $lines[$index][] = ['text' => $priceData['label'], 'feed' => $feedSubtotal, 'align' => 'right'];
	                    $index++;
	                }
	                $lines[$index][] = [
	                    'text' => round($childItem->getQty(), 2),
	                    'feed' => $feedPrice,
	                    'font' => 'bold',
	                    'align' => 'right',
	                ];
	                // draw Price
	                $lines[$index][] = [
	                    'text' => $priceData['price'],
	                    'feed' => $feedPrice+40,
	                    'font' => 'bold',
	                    'align' => 'right',
	                ];
	                // draw Subtotal
	                $lines[$index][] = [
	                    'text' => $priceData['subtotal'],
	                    'feed' => $feedPrice+90,
	                    'font' => 'bold',
	                    'align' => 'right',
	                ];
	                $lines[$index][] = [
	                    'text' => round($childItem->getDiscountAmount(), 2),
	                    'feed' => $feedPrice+130,
	                    'font' => 'bold',
	                    'align' => 'right',
	                ];

	                $lines[$index][] = [
	                    'text' => $tax,
	                    'feed' => $feedPrice+200,
	                    'font' => 'bold',
	                    'align' => 'right',
	                ];
	                $lines[$index][] = [
	                'text' => "Custom",
	                'feed' => $feedPrice+260,
	                'font' => 'bold',
	                'align' => 'right',
	                ];
	                $lines[$index][] = [
	                    'text' => $this->getOrder()->formatPriceTxt($childItem->getRowTotal()+$childItem->getTaxAmount()),
	                    'feed' => $feedSubtotal+230,
	                    'font' => 'bold',
	                    'align' => 'right',
	                ];
	                $index++;
	            }
	            $this->_item = $item;
	        }
	        /* drawPrices End */
        }
        $drawItems[$optionId]['lines'] = $lines;
        return $drawItems;
    }

    private function drawCustomOptions(array $draw): array
    {
        $options = $this->getItem()->getOrderItem()->getProductOptions();
        if ($options && isset($options['options']))
        {
            foreach ($options['options'] as $option)
            {
                $lines = [];
                $lines[][] = [
                    'text' => $this->string->split(
                        $this->filterManager->stripTags($option['label']),
                        40,
                        true,
                        true
                    ),
                    'font' => 'italic',
                    'feed' => 35,
                ];
                if ($option['value'])
                {
                    $text = [];
                    $printValue = $option['print_value'] ?? $this->filterManager->stripTags($option['value']);
                    $values = explode(', ', $printValue);
                    foreach ($values as $value)
                    {
                        foreach ($this->string->split($value, 30, true, true) as $subValue)
                        {
                            $text[] = $subValue;
                        }
                    }
                    $lines[][] = ['text' => $text, 'feed' => 40];
                }
                $draw[] = ['lines' => $lines, 'height' => 15];
            }
        }
        return $draw;
    }
}
```

**Step 7:** Finally, run the below commands
```
php bin/magento cache:flush
php bin/magento setup:di:compile
```

## [![Magento 2 Speed & Performance Optimization Services](https://magecomp.com/blog/wp-content/uploads/2025/02/Magento-2-Speed-Performance-Optimization-Services-CTA-1.webp)](https://magecomp.com/magento-performance-optimization.html)

## Conclusion:
With the help of the above-given steps, you can easily add download invoice button to order emails and improve the user experience. If you have difficulty in the above steps, let me know through the comment box. Share the article with your friends and stay in touch with us for more solutions.
**Happy Coding!**

</body>


---

_View the original post at: [https://magecomp.com/blog/magento-2-add-download-invoice-button-in-order-email/](https://magecomp.com/blog/magento-2-add-download-invoice-button-in-order-email/)_  
_Served as markdown by [Third Audience](https://github.com/third-audience) v3.5.3_  
_Generated: 2026-08-24 07:04:40 UTC_  
