Press ESC to close

Magento 2 Attach PDF to Invoice Email – Easy Step-by-Step Guide

If you’re running an e-commerce site built on Magento 2, chances are you have needed to attach a PDF file to the invoice email at least once. Magento 2 attach pdf to invoice email happens a lot actually so it’s not a strange need. The point is that it will take too much time and effort to manually add each PDF file whenever you need.

Understanding your concern, this blog will guide you on how to attach a PDF file to the invoice email programmatically.

Let’s head straight to the instructions!

Note: This solution has been thoroughly tested on Magento 2.4.x versions and is compatible with the latest Magento releases.

How To Attach PDF File To Invoice Email in Magento 2 Programmatically

Step-by-Step Implementation Guide For Magento 2 attach pdf to invoice email

Step 1: Create registration.php

First, we need to create a custom module with the proper directory structure. Place this file in the app/code/Vendor/Module directory.

<?php

\Magento\Framework\Component\ComponentRegistrar::register(

    \Magento\Framework\Component\ComponentRegistrar::MODULE,

    'Vendor_Module',

    __DIR__

);

Step 2: Create module.xml

Next, create the module.xml file inside the etc folder to define the module configuration. Place this file in app/code/Vendor/Module/etc.

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

        xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">

    <module name="Vendor_Module" setup_version="1.0.0">

    </module>

</config>

Step 3: Create di.xml

Configure di.xml to override the TransportBuilder class and add a plugin to InvoiceSender

Path: app/code/Vendor/Module/etc/di.xml

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">

   <preference for="Magento\Framework\Mail\Template\TransportBuilder"

            type="Vendor\Module\Mail\Template\TransportBuilder" />

      <type name="Magento\Sales\Model\Order\Email\Sender\InvoiceSender">

        <plugin name="add_invoice_attachment_plugin"

                type="Vendor\Module\Plugin\Email\AddInvoiceAttachmentPlugin" />

    </type>

</config>

Step 4: Extend the TransportBuilder Class

Extend TransportBuilder to Support Attachments.Override the TransportBuilder class to support PDF attachments.

Path: app/code/Vendor/Module/Mail/Template/TransportBuilder.php

<?php

namespace Vendor\Module\Mail\Template;

use Laminas\Mime\Mime;

use Laminas\Mime\Message as MimeMessage;

use Laminas\Mime\Part;

class TransportBuilder extends \Magento\Framework\Mail\Template\TransportBuilder

{

    protected $attachments = [];

    public function addAttachment(

        $body,

        $filename = null,

        $mimeType = Mime::TYPE_OCTETSTREAM,

        $disposition = Mime::DISPOSITION_ATTACHMENT,

        $encoding = Mime::ENCODING_BASE64

    ) {

        $attachmentPart = new Part($body);

        $attachmentPart->setType($mimeType);

        $attachmentPart->setFileName($filename);

        $attachmentPart->setDisposition($disposition);

        $attachmentPart->setEncoding($encoding);

        $this->attachments[] = $attachmentPart;

        return $this;

    }

    public function getTransport()

    {

        $transport = parent::getTransport();

        if (!empty($this->attachments)) {

            $message = $transport->getMessage();

            // Get original body

            $originalBody = $message->getBody();

            if ($originalBody instanceof MimeMessage) {

                $parts = $originalBody->getParts();

            } else {

                $htmlPart = new Part($originalBody);

                $htmlPart->setCharset('utf-8');

                $htmlPart->setEncoding(Mime::ENCODING_QUOTEDPRINTABLE);

                $htmlPart->setDisposition(Mime::DISPOSITION_INLINE);

                $htmlPart->setType(Mime::TYPE_HTML);

                $parts = [$htmlPart];

            }

            $body = new MimeMessage();

            $body->setParts(array_merge($parts, $this->attachments));

            $message->setBody($body);

        }

        return $transport;

    }

}

Step 5: Create a Plugin for Invoice Email

Add Plugin for Invoice Email.Create a plugin on InvoiceSender::send() to attach the generated PDF before sending the email.

Path: app/code/Vendor/Module/Plugin/Email/AddInvoiceAttachmentPlugin.php

<?php

namespace Vendor\Module\Plugin\Email;

use Magento\Sales\Model\Order\Email\Sender\InvoiceSender;

use Magento\Framework\Mail\Template\TransportBuilder;

use Vendor\Module\Helper\Data as InvoiceHelper;

use Magento\Framework\Filesystem\Driver\File;

use Magento\Sales\Api\Data\InvoiceInterface;

class AddInvoiceAttachmentPlugin

{

    protected $transportBuilder;

    protected $invoiceHelper;

    protected $file;

    public function __construct(

        TransportBuilder $transportBuilder,

        InvoiceHelper $invoiceHelper,

        File $file

    ) {

        $this->transportBuilder = $transportBuilder;

        $this->invoiceHelper = $invoiceHelper;

        $this->file = $file;

    }

    public function beforeSend(

        InvoiceSender $subject,

        InvoiceInterface $invoice,

        $forceSyncMode = false

    ) {

        $order = $invoice->getOrder();

        $pdfData = $this->invoiceHelper->createPdfFile($invoice, $order->getId());

        if (!empty($pdfData['filename']) && !empty($pdfData['pdfFile'])) {

            $this->transportBuilder->addAttachment(

                $this->file->fileGetContents($pdfData['pdfFile']),

                $pdfData['filename'],

                'application/pdf'

            );

        }

    }

}

Step 6: Create Helper for PDF Generation

Create Helper to Generate Invoice PDF.The Data.php file inside the Helper directory is responsible for generating the invoice PDF file using Magento’s built-in PDF generation classes.

Path: app/code/Vendor/Module/Helper/Data.php

<?php

namespace Vendor\Module\Helper;

use Magento\Framework\App\Helper\AbstractHelper;

use Magento\Framework\Filesystem;

use Magento\Framework\App\Filesystem\DirectoryList;

use Magento\Sales\Model\Order\Pdf\Invoice as InvoicePdf;

use Magento\Sales\Api\InvoiceRepositoryInterface;

class Data extends AbstractHelper

{

    protected $filesystem;

    protected $invoicePdf;

    public function __construct(

        \Magento\Framework\App\Helper\Context $context,

        Filesystem $filesystem,

        InvoicePdf $invoicePdf

    ) {

        parent::__construct($context);

        $this->filesystem = $filesystem;

        $this->invoicePdf = $invoicePdf;

    }

    public function createPdfFile($invoice, $orderId)

    {

        if (!$invoice || !$invoice->getId()) {

            return [];

        }

        $pdf = $this->invoicePdf->getPdf([$invoice]);

        $fileName = 'invoice_' . $invoice->getIncrementId() . '.pdf';

        $varDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::VAR_DIR);

        $folderPath = 'invoices/';

        $filePath = $varDirectory->getAbsolutePath($folderPath . $fileName);

        $varDirectory->create($folderPath);

        file_put_contents($filePath, $pdf->render());

        return [

            'filename' => $fileName,

            'pdfFile' => $filePath

        ];

    }

}

Step 7: Run Magento Commands

After creating these files, run the following Magento commands to deploy your module:

php bin/magento setup:upgrade

php bin/magento setup:di:compile

php bin/magento setup:static-content:deploy

php bin/magento cache:clean

php bin/magento cache:flush

Screenshot of Magento 2 attach pdf to invoice email, showing the final output after implementing the above solution.

Magento 2 attach pdf to invoice email

Looking to automate your entire invoice process? Try our Magento 2 Auto Invoice extension to generate and send invoices automatically upon order placement, complete with PDF attachments.


Conclusion

Through the implementation of Magento 2 attach PDF to invoice email solution your business gains superior customer experience together with operational simplification. The programmatic method provides your customers with automatic and standardized delivery of important documents. The functionality of attaching PDF invoices via email to Magento 2 enhances your business reputation as well as lowers your support load for invoice documentation requests. By implementing this module you will achieve better time management and operational efficiency as well as deliver superior shopping simplicity to your clients.

Have you implemented PDF attachments in your Magento store? Share your experience in the comments below!

jhjbhjbhjbhjjjhbj

Share Post

Leave a Reply

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