7

When I ship any order with a UPS label and add the tracking number. it shows Track Order in the backend. I want to send this URL to the customer's email also. Currently, it sends the tracking number and shipment method only.

Magento 2 shipment email

1
  • I would like an answer for this one also please !
    – styzzz
    Jul 31, 2017 at 17:28

6 Answers 6

9

Please override this file:

vendor/magento/module-sales/view/frontend/templates/email/shipment/track.phtml

by creating this path:

/app/design/frontend/Custom/theme/Magento_Sales/templates/email/shipment/track.phtml

Please add below code in foreach loop

    <?php
    $trackurl = '';
    if($_item->getCarrierCode() === 'fedex'){
        $trackurl = 'https://www.fedex.com/apps/fedextrack/?action=track&trackingnumber='.$_item->getNumber();
    }elseif ($_item->getCarrierCode() === 'usps') {
        $trackurl = 'https://tools.usps.com/go/TrackConfirmAction_input?qtc_tLabels1='.$_item->getNumber();
    }elseif ($_item->getCarrierCode() === 'ups') {
        $trackurl = 'https://wwwapps.ups.com/WebTracking/returnToDetails?tracknum='.$_item->getNumber();
    }
    ?>
    <tr>
        <td><?= $block->escapeHtml($_item->getTitle()) ?>:</td>

         <td style="padding:3px 9px"><a href="<?php echo $trackurl ?>"><?php echo $this->escapeHtml($_item->getNumber()) ?></a></td>

    </tr>
1
  • It would be a better experience for the email link to open in a new tab/window by adding target="_blank" to the link
    – asherrard
    Nov 17, 2020 at 21:42
2

I recently had to implement tracking URL's in the shipment emails as well.

The template to edit is:


This block is referenced in 2 email templates:


I referenced the shipment tracking "popup" template (which already has the tracking URL functionality) to implement tracking URL's in Magento_Sales/templates/email/shipment/track.phtml:

<?php

$obj = \Magento\Framework\App\ObjectManager::getInstance();
$_info = $obj->create('Magento\Shipping\Model\Info');
$_shipment = $block->getShipment();

$shipments = $_info->setProtectCode(
    // Necessary for the $_info model to be able to get tracking info
    $_shipment->getProtectCode()
)->setShipId(
    $_shipment->getId()
)->getTrackingInfoByShip();

if (!empty($shipments)): ?>
<table class="shipment-track">
    <thead>
        <tr>
            <th><?= /* @escapeNotVerified */  __('Shipped By') ?></th>
            <th><?= /* @escapeNotVerified */  __('Tracking Number') ?></th>
        </tr>
    </thead>
    <tbody>
    <?php foreach ($shipments as $id => $shipment): ?>
        <?php if (!empty($shipment)): ?>
            <?php foreach ($shipment as $counter => $track): ?>
            <tr>
                <td><?= $track->getCarrierTitle() ?></td>
                <td>
                    <?php if ($track->getUrl()): ?>
                        <a href="<?= $track->getUrl() ?>" target="_blank"><?= $track->getTracking() ?></a>
                    <?php else: ?>
                        <b><?= $track->getTracking() ?></b>
                    <?php endif ?>
                </td>
            </tr>
            <?php endforeach ?>
        <?php endif ?>
    <?php endforeach ?>
    </tbody>
</table>
<?php endif ?>

The only questionable thing here is the direct use of the Object Manager. My answer assumes familiarity with Magento 2 theming - please feel free to ask questions about the other steps.




Update

A more "correct" way to implement this might be to use a di.xml preference for the template's block class.

Please note, this example is not tested:

<?php

namespace Vendor\Module\Block\Order\Email\Shipment;

class Items extends \Magento\Sales\Block\Order\Email\Shipment\Items
{
    /**
     * @var \Magento\Shipping\Model\InfoFactory
     * */
    protected $shippingInfo;

    /**
     * @param \Magento\Shipping\Model\InfoFactory $shippingInfoFactory
     * @param \Magento\Framework\View\Element\Template\Context $context
     * @param array $data
     * @param \Magento\Sales\Api\OrderRepositoryInterface $orderRepository
     * @param \Magento\Sales\Api\ShipmentRepositoryInterface $creditmemoRepository
     */
    public function __construct(
        \Magento\Shipping\Model\InfoFactory $shippingInfoFactory,
        \Magento\Framework\View\Element\Template\Context $context,
        array $data = [],
        ?\Magento\Sales\Api\OrderRepositoryInterface $orderRepository = null,
        ?\Magento\Sales\Api\ShipmentRepositoryInterface $creditmemoRepository = null
    ) {
        parent::__construct($context, $data, $orderRepository, $creditmemoRepository);
        $this->shippingInfoFactory = $shippingInfoFactory;
    }

    /**
     * Get tracking info
     */
    public function getTrackingInfo()
    {
        $info = $this->shippingInfoFactory->create();
        $info->setShipId($this->getShipment()->getEntityId());
        return $info->getTrackingInfoByShip();
    }
}

From there, you should be able to call $block->getTrackingInfo() from the .phtml template to get the tracking info.

2

We came across an excellent solution from Scommerce which allows you to not only add tracking link to one shipping system but any number of shipping methods. The tracking URL can be added to the configuration and the shipment carrier is available in the list. It generates the tracking link in the admin panel, My account section as well as in the shipment email. You can give it try if you don't want to go the code route.

enter image description here

1
  • exactly what I am looking for, do you have the link to this extension?
    – MageWizard
    Nov 28 at 10:18
1

You can copy vendor/magento/module-sales/view/frontend/email/shipment_new.html to your theme and edit line 56 (here you can change block for which display track information), you can change it like this {{block class='Your_Package\\Your_Module\\Block\\Sales\\Email\\Shipment\\Track' area='frontend' template='Magento_Sales::email/shipment/track.phtml' shipment=$shipment order=$order}}.

After that you need create this block

<?php

namespace Your_Package\Your_Module\Block\Sales\Email\Shipment;

use \Magento\Framework\View\Element\Template;

class Track extends Template
{
    /**
     * @var \Magento\Shipping\Model\Order\TrackFactory
     */
    protected $_trackFactory;

    /**
     * Constructor
     *
     * @param \Magento\Shipping\Model\Order\TrackFactory $trackFactory
     * @param Template\Context $context
     * @param array $data
     */
    public function __construct(
        \Magento\Shipping\Model\Order\TrackFactory $trackFactory,
        Template\Context $context,
        array $data = [])
    {
        $this->_trackFactory = $trackFactory;
        parent::__construct($context, $data);
    }

    /**
     * Retrieve tracking by tracking entity id
     *
     * @return array
     */
    public function getTrackingInfoByTrackId($trackId)
    {
        /** @var \Magento\Shipping\Model\Order\Track $track */
        $track = $this->_trackFactory->create()->load($trackId);
        if ($track->getEntityId()) {
            $result = $track->getNumberDetail();
        } else {
            $result = null;
        }
        return $result;
    }
}

Then copy template vendor/magento/module-sales/view/frontend/templates/email/shipment/track.phtml to your theme and change line 25 to

<td>
    <?php 
        $trackingInfo = $block->getTrackingInfoByTrackId($_item->getEntityId());
    ?>
    <?php if ($trackingInfo->getUrl()): ?>
        <a href="<?= $block->escapeHtml($trackingInfo->getUrl()) ?>"
           onclick="this.target='_blank'">
            <?= $block->escapeHtml($_item->getNumber()) ?>
        </a>
    <?php else: ?>
        <?= $block->escapeHtml($_item->getNumber()) ?>
    <?php endif; ?>
</td>

You also may need copy vendor/magento/module-sales/view/frontend/email/shipment_new_guest.html the same like shipment_new.html

2
  • does anyone know if the above solution works? I would like to see something that you can add to the transactional email to send the tracking number into google, so the customer can look it up that way. There has to be a simpler way !
    – styzzz
    Aug 4, 2017 at 23:12
  • I combined Logan's solution with this one and it worked.
    – newbie
    Oct 21, 2020 at 4:39
0

This is the best way - you override this file:

vendor/magento/module-sales/view/frontend/templates/email/shipment/track.phtml

by creating this path:

/app/design/frontend/Vendor/theme/Magento_Sales/templates/email/shipment/track.phtml

and the line in track.phml where it says "$_item->getNumber"

replace with

<td style="padding:3px 9px"><a href="https://tools.usps.com/go/TrackConfirmAction_input?qtc_tLabels1=<?php echo $this->escapeHtml($_item->getNumber()) ?>"><?php echo $this->escapeHtml($_item->getNumber()) ?></a></td>

Note: this is for USPS shipments. If you wanted all tracking numbers, you can have them just go to google by replacing tools.usps.com with google.com/

0

There's also this open-source module that makes tracking numbers clickable. The URLs can be configured in store-config:

https://github.com/shipperhq/module-shipping-tracker

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.