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.
6 Answers
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>
-
It would be a better experience for the email link to open in a new tab/window by adding target="_blank" to the link Nov 17, 2020 at 21:42
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.
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.
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
-
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 !– styzzzAug 4, 2017 at 23:12
-
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/
There's also this open-source module that makes tracking numbers clickable. The URLs can be configured in store-config: