
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.

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!
Share Post
Leave a Reply