Cookies setting

Cookies help us enhance your experience on our site by storing information about your preferences and interactions. You can customize your cookie settings by choosing which cookies to allow. Please note that disabling certain cookies might impact the functionality and features of our services, such as personalized content and suggestions. Cookie Policy

Cookie Policy
Essential cookies

These cookies are strictly necessary for the site to work and may not be disabled.

Information
Always enabled
Advertising cookies

Advertising cookies deliver ads relevant to your interests, limit ad frequency, and measure ad effectiveness.

Information
Analytics cookies

Analytics cookies collect information and report website usage statistics without personally identifying individual visitors to Google.

Information
mageplaza.com

Attach PDF to Invoice Email in Magento 2 Programmatically

Vinh Jacker | 11-11-2024

Attach PDF to Invoice Email in Magento 2 Programmatically

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. This 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.

Understand 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!

How to Attach PDF to Invoice Email in Magento 2

Step 1: Create a TransportBuilder class

Magento 2 sends emails by using the TransportBuilder, but it doesn’t allow admins to attach files.​​​​​​​ So, the first step is to create a TransportBuilder class in app/code/Vendor/Module /Mail/Template/ TransportBuilder.php

<?php


namespace Vendor\Module\Mail\Template;


class TransportBuilder extends \Magento\Framework\Mail\Template\TransportBuilder
{
   /**
    * addAttachment
    *
    * @param mixed $body
    * @param string $filename
    * @param mixed $mimeType
    * @param mixed $disposition
    * @param mixed $encoding
    * @return object
    */
    public function addAttachment(
        $body,
        $filename = null,
        $mimeType = \Zend_Mime::TYPE_OCTETSTREAM,
        $disposition = \Zend_Mime::DISPOSITION_ATTACHMENT,
        $encoding = \Zend_Mime::ENCODING_BASE64
    ) {
        $attachmentPart = new \Zend\Mime\Part();
        $attachmentPart->setContent($body)
            ->setType($mimeType)
            ->setFileName($filename)
            ->setEncoding($encoding)
            ->setDisposition($disposition);


        return $attachmentPart;
    }
}

Step 2: Create the SenderBuilder class

Next, you need to create the SenderBuilder class in order to attach files. This class will allow you to add PDF, image, and calendar files to emails. Add the SenderBuilder class in app/code/Vendor/Module/Model/Sales/Order/Email/SenderBuilder.php

<?php


namespace Vendor\Module\Model\Sales\Order\Email;


use Magento\Framework\Mail\Template\TransportBuilder;
use Magento\Framework\Mail\Template\TransportBuilderByStore;
use Magento\Sales\Model\Order\Email\Container\IdentityInterface;
use Magento\Sales\Model\Order\Email\Container\Template;


/**
 * Email sender builder for attachments
 */
class SenderBuilder extends \Magento\Sales\Model\Order\Email\SenderBuilder
{
    /**
     * @param Template $templateContainer
     * @param IdentityInterface $identityContainer
     * @param TransportBuilder $transportBuilder
     * @param TransportBuilderByStore $transportBuilderByStore
     * @param \Magento\Framework\Filesystem\Driver\File $reader
     */
    public function __construct(
        Template $templateContainer,
        IdentityInterface $identityContainer,
        TransportBuilder $transportBuilder,
        TransportBuilderByStore $transportBuilderByStore = null,
        \Vendor\Module\Helper\Data $helper,
        \Magento\Framework\Filesystem\Driver\File $reader
    ) {
        parent::__construct(
            $templateContainer,
            $identityContainer,
            $transportBuilder
        );
        $this->helper = $helper;
        $this->reader = $reader;
    }
    /**
     * Prepare and send email message
     *
     * @return void
     */
    public function send()
    {
        $this->configureEmailTemplate();


        $this->transportBuilder->addTo(
            $this->identityContainer->getCustomerEmail(),
            $this->identityContainer->getCustomerName()
        );


        $copyTo = $this->identityContainer->getEmailCopyTo();
        if (!empty($copyTo) && $this->identityContainer->getCopyMethod() == 'bcc') {
            foreach ($copyTo as $email) {
                $this->transportBuilder->addBcc($email);
            }
        }


        /* to attach events in invoice email */
        $templateVars = $this->templateContainer->getTemplateVars();
        $transport = $this->transportBuilder->getTransport();
        if (!empty($templateVars['order'])) {
            $order = $templateVars['order'];
            foreach ($order->getAllItems() as $item) {
                $data = $this->helper->createPdfFile($item, $order->getId());
                if (!empty($data) && !empty($data['filename']) && !empty($data['pdfFile'])) {
                    // adds attachment in mail
                    $attachmentPart = $this->transportBuilder->addAttachment(
                        $this->reader->fileGetContents($data['pdfFile']),
                        $data['filename'],
                        'application/pdf'
                    );


                    $message = $transport->getMessage();
                    $body = \Zend\Mail\Message::fromString($message->getRawMessage())->getBody();
                    $body = \Zend_Mime_Decode::decodeQuotedPrintable($body);
                    $html = '';


                    if ($body instanceof \Zend\Mime\Message) {
                        $html = $body->generateMessage(\Zend\Mail\Headers::EOL);
                    } elseif ($body instanceof \Magento\Framework\Mail\MimeMessage) {
                        $html = (string) $body->getMessage();
                    } elseif ($body instanceof \Magento\Framework\Mail\EmailMessage) {
                        $html = (string) $body->getBodyText();
                    } else {
                        $html = (string) $body;
                    }


                    $htmlPart = new \Zend\Mime\Part($html);
                    $htmlPart->setCharset('utf-8');
                    $htmlPart->setEncoding(\Zend_Mime::ENCODING_QUOTEDPRINTABLE);
                    $htmlPart->setDisposition(\Zend_Mime::DISPOSITION_INLINE);
                    $htmlPart->setType(\Zend_Mime::TYPE_HTML);
                    $parts = [$htmlPart, $attachmentPart];


                    $bodyPart = new \Zend\Mime\Message();
                    $bodyPart->setParts($parts);
                    $message->setBody($bodyPart);
                }
            }
        }


        $transport->sendMessage();
    }
}

Finally, run this code in app/code/Vendor/Module/etc/di.xml to activate the new TransportBuilder class you created in step 1.

<?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\Model\Mail\TransportBuilder" />
</config>

A Better Solution to Attach PDF File to Invoice Email

If you’re not an expert developer, the programmatic method may not be an ideal choice. Instead, using an extension would be easier. All the features are displayed as fields in the backend clearly for store owners to use.

Among the choices, we would like to introduce PDF Invoice for Magento 2. It can automatically send PDF Invoices to your customers via emails with essential information, including order details, payment methods, etc.

Highlight features:

  • Compatible with API/GraphQL
  • Provide attractive pre-made PDF templates
  • Send PDF documents
  • Offer various convenient payment methods
  • Download and print professional PDF documents from My Order page
  • Download and print PDF documents in mass
  • Allow documents to be printed in customer and admin accounts

Learn more on how to use the extension here.

Final Word

Sending a PDF file with detailed order information to invoice emails would be solid proof of e-commerce dedication to customers. If you’re confident with coding skills, the programmatic method would be a good option. In case you’re not, that’s okay. Using the Magento extension can solve the problem since it’s much easier to use.

Table of content
    Jacker

    With over a decade of experience crafting innovative tech solutions for ecommerce businesses built on Magento, Jacker is the mastermind behind our secure and well-functioned extensions. With his expertise in building user-friendly interfaces and robust back-end systems, Mageplaza was able to deliver exceptional Magento solutions and services for over 122K+ customers around the world.



    Related Post

    Website Support
    & Maintenance Services

    Make sure your store is not only in good shape but also thriving with a professional team yet at an affordable price.

    Get Started
    mageplaza services