How to Seamlessly Add Attachments to Magento Email Last Updated on 18 December 20236 August 2025 Mark Mac General In Magento, enhancing your communication strategy can significantly impact customer satisfaction and engagement. One effective way to achieve this is to add attachments to your emails, providing customers with comprehensive information, and improving the overall user experience. In this blog post, we’ll guide you through the process of creating a Magento module to seamlessly attach invoices to your emails, enhancing the overall user experience. Table of Contents Toggle Why adding attachments to Magento email is a valuable enhancementWith businessesEfficiency and Time SavingsProfessional Brand ImageWith customersComprehensive Order DetailsSimplified CommunicationStep-by-step Instructions to Add an Invoice Attachment to Magento Email1. Create Module Files2. Override TransportBuilder3. Plugin for SenderBuilderResultConclusion Why adding attachments to Magento email is a valuable enhancement Attaching files to Magento email proves beneficial for both enterprises and customers alike. With businesses Efficiency and Time Savings With the automatic preparation of invoice attachments beforehand, businesses save time and effort. Senders can effortlessly click “send”, streamlining the communication process. Professional Brand Image Including well-designed attachments contributes to a professional image for the company. It reflects a commitment to organized and detailed communication, enhancing the overall perception of the business. With customers Comprehensive Order Details Attachments provide customers with detailed order information, such as invoices, receipts, and shipping details, directly within the email. This eliminates the need for customers to navigate external platforms and ensures a comprehensive understanding of their purchase. Simplified Communication Attachments offer an easy-to-follow format, reducing the need for customers to read lengthy emails. Important information is presented clearly and concisely, enhancing the overall user experience. Step-by-step Instructions to Add an Invoice Attachment to Magento Email 1. Create Module Files To begin, you need to set up the basic structure of your module with the following files: File 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="Tigren\SendPdf\Mail\Template\TransportBuilder"/> <type name="Magento\Sales\Model\Order\Email\SenderBuilder"> <plugin name="add.attachment.email" type="Tigren\SendPdf\Plugin\SenderBuilder"/> </type> </config> File module.xml <?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="Tigren_SendPdf" /> </config> File registration.php <?php /* * @author Tigren Solutions <info@tigren.com> * @copyright Copyright (c) 2023 Tigren Solutions <https://www.tigren.com>. All rights reserved. * @license Open Software License (“OSL”) v. 3.0 */ use Magento\Framework\Component\ComponentRegistrar; ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Tigren_SendPdf', __DIR__); 2. Override TransportBuilder Then, we need to override the TransportBuilder file in the Tigren\SendPdf\Mail\Template directory of Magento to include the attachment functionality. <?php declare (strict_types=1); namespace Tigren\SendPdf\Mail\Template; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Mail\AddressConverter; use Magento\Framework\Mail\EmailMessageInterfaceFactory; use Magento\Framework\Mail\MessageInterface; use Magento\Framework\Mail\MessageInterfaceFactory; use Magento\Framework\Mail\MimeMessageInterfaceFactory; use Magento\Framework\Mail\MimePartInterfaceFactory; use Magento\Framework\Mail\Template\FactoryInterface; use Magento\Framework\Mail\Template\SenderResolverInterface; use Magento\Framework\Mail\TransportInterfaceFactory; use Magento\Framework\ObjectManagerInterface; use Laminas\Mime\Mime; use Laminas\Mime\Message; use Laminas\Mime\PartFactory; /** * Class TransportBuilder * @package Tigren\SendPdf\Mail\Template */ class TransportBuilder extends \Magento\Framework\Mail\Template\TransportBuilder { /** * @var Message */ protected $messageMime; /** * @var */ protected $message; /** * @var array */ protected $attachments = []; /** * @var PartFactory|mixed */ protected $partFactory; /** * @param Message $messageMime * @param PartFactory $partFactory * @param FactoryInterface $templateFactory * @param MessageInterface $message * @param SenderResolverInterface $senderResolver * @param ObjectManagerInterface $objectManager * @param TransportInterfaceFactory $mailTransportFactory * @param MessageInterfaceFactory|null $messageFactory * @param EmailMessageInterfaceFactory|null $emailMessageInterfaceFactory * @param MimeMessageInterfaceFactory|null $mimeMessageInterfaceFactory * @param MimePartInterfaceFactory|null $mimePartInterfaceFactory * @param AddressConverter|null $addressConverter */ public function __construct( Message $messageMime, PartFactory $partFactory, FactoryInterface $templateFactory, MessageInterface $message, SenderResolverInterface $senderResolver, ObjectManagerInterface $objectManager, TransportInterfaceFactory $mailTransportFactory, MessageInterfaceFactory $messageFactory = null, EmailMessageInterfaceFactory $emailMessageInterfaceFactory = null, MimeMessageInterfaceFactory $mimeMessageInterfaceFactory = null, MimePartInterfaceFactory $mimePartInterfaceFactory = null, AddressConverter $addressConverter = null ) { $this->templateFactory = $templateFactory; $this->partFactory = $partFactory; $this->messageMime = $messageMime; parent::__construct( $templateFactory, $message, $senderResolver, $objectManager, $mailTransportFactory, $messageFactory, $emailMessageInterfaceFactory, $mimeMessageInterfaceFactory, $mimePartInterfaceFactory, $addressConverter ); } /** * @return $this|TransportBuilder * @throws LocalizedException */ protected function prepareMessage() { $result = parent::prepareMessage(); if (!empty($this->attachments)) { foreach ($this->attachments as $attachment) { $body = $this->message->getBody(); if (!$body) { $body = $this->messageMime; } $body->addPart($attachment); $this->message->setBody($body); } $this->attachments = []; } return $result; } /** * @param $content * @param $fileName * @param $fileType * @return $this */ public function addAttachment($content, $fileName, $fileType) { $attachmentPart = $this->partFactory->create(); $attachmentPart->setContent($content) ->setType($fileType) ->setFileName($fileName) ->setDisposition(Mime::DISPOSITION_ATTACHMENT) ->setEncoding(Mime::ENCODING_BASE64); $this->attachments[] = $attachmentPart; return $this; } } 3. Plugin for SenderBuilder <?php namespace Tigren\SendPdf\Plugin; use Laminas\Validator\Date; use Tigren\SendPdf\Mail\Template\TransportBuilder; use Magento\Sales\Model\Order\Email\Container\Template; use Magento\Sales\Model\Order\Pdf\Invoice; use Magento\Framework\Stdlib\DateTime\DateTime; class SenderBuilder { private TransportBuilder $transportBuilder; private Template $templateContainer; private Invoice $renderInvoice; private DateTime $dateTime; public function __construct( DateTime $dateTime, Invoice $renderInvoice, Template $templateContainer, TransportBuilder $transportBuilder ) { $this->transportBuilder = $transportBuilder; $this->templateContainer = $templateContainer; $this->renderInvoice = $renderInvoice; $this->dateTime = $dateTime; } public function beforeSend(\Magento\Sales\Model\Order\Email\SenderBuilder $subject) { $dataInvoice = $this->_getDataTemplate(); try { if(!empty($dataInvoice)){ $pdfContent = $this->renderInvoice->getPdf($dataInvoice)->render(); $date = $this->dateTime->date('Y-m-d_H-i-s'); $this->transportBuilder->addAttachment($pdfContent, 'invoice' . $date . '.pdf', 'application/pdf'); } } catch (\Exception $e) { return; } } private function _getDataTemplate() { $data = $this->templateContainer->getTemplateVars(); if (array_key_exists('invoice_id', $data)) { return [$data['invoice']]; } if (isset($data['order']) && $data['order']->hasInvoices()) { return $data['order']->getInvoiceCollection()->getItems(); } return [$data['invoice']] ?? ''; } Result When an email for an invoice or order is dispatched, an invoice attachment is seamlessly appended to the email. Conclusion Following these steps, you can seamlessly add invoice attachments to your Magento emails. This enhances your communication strategy, providing customers with detailed information and contributing to a positive shopping experience. Customize the module as needed for your specific use case, and elevate your customer engagement in the competitive world of e-commerce. Reach out to us for more tailor-made services that cater specifically to the needs of your online store. Mark Mac Share Table of Contents Toggle Why adding attachments to Magento email is a valuable enhancementWith businessesEfficiency and Time SavingsProfessional Brand ImageWith customersComprehensive Order DetailsSimplified CommunicationStep-by-step Instructions to Add an Invoice Attachment to Magento Email1. Create Module Files2. Override TransportBuilder3. Plugin for SenderBuilderResultConclusion