When can you deliver? (FedEx)

As a customer, there are two things prioritizing choices of shipping methods. First one, of course, is shipping price and other is delivery date. Since Magento is already showing us shipping prices on the checkout we don’t need to worry about that.
Magento offers us a lot of different shipping possibilities and each one has its own way of communicating and returning shipping details so there is not one single solution for all of them, but for now, we can show you how to do this for FedEx.
Changing FedEx API
Biggest problem we encounter with getting delivery date is that shipping provider as FedEx is not returning that date back to us. To resolve this, we need to request this data from Fedex and to do so, we need to change our API request.
That is why we want to overwrite _formRateRequest method in Mage_Usa_Model_Shipping_Carrier_Fedex class and add “ReturnTransitAndCommit” in API call.
protected function _formRateRequest($purpose)
{
$ratesRequest = parent::_formRateRequest($purpose);
$ratesRequest['ReturnTransitAndCommit'] = true;
return $ratesRequest;
}
Adding this attribute in call will request that Transit Time information is included in the reply from Fedex.
Fedex will return to us delivery timestamp for each method, but to make this more readable and accessible to shipping rate we will overwrite _prepareRateResponse method in same class and split it into date and time.
protected function _prepareRateResponse($response)
{
$costArr = array();
$priceArr = array();
$errorTitle = 'Unable to retrieve tracking';
if (is_object($response)) {
if ($response->HighestSeverity == 'FAILURE' || $response->HighestSeverity == 'ERROR') {
if (is_array($response->Notifications)) {
$notification = array_pop($response->Notifications);
$errorTitle = (string)$notification->Message;
} else {
$errorTitle = (string)$response->Notifications->Message;
}
} elseif (isset($response->RateReplyDetails)) {
$allowedMethods = explode(",", $this->getConfigData('allowed_methods'));
if (is_array($response->RateReplyDetails)) {
foreach ($response->RateReplyDetails as $rate) {
$serviceName = (string)$rate->ServiceType;
if (in_array($serviceName, $allowedMethods)) {
$amount = $this->_getRateAmountOriginBased($rate);
$costArr[$serviceName] = $amount;
$priceArr[$serviceName] = $this->getMethodPrice($amount, $serviceName);
$deliveryTimestamp[$serviceName] = $rate->DeliveryTimestamp;
}
}
asort($priceArr);
} else {
$rate = $response->RateReplyDetails;
$serviceName = (string)$rate->ServiceType;
if (in_array($serviceName, $allowedMethods)) {
$amount = $this->_getRateAmountOriginBased($rate);
$costArr[$serviceName] = $amount;
$priceArr[$serviceName] = $this->getMethodPrice($amount, $serviceName);
}
}
}
}
$result = Mage::getModel('shipping/rate_result');
if (empty($priceArr)) {
$error = Mage::getModel('shipping/rate_result_error');
$error->setCarrier($this->_code);
$error->setCarrierTitle($this->getConfigData('title'));
$error->setErrorMessage($errorTitle);
$error->setErrorMessage($this->getConfigData('specificerrmsg'));
$result->append($error);
} else {
foreach ($priceArr as $method=>$price) {
$rate = Mage::getModel('shipping/rate_result_method');
$rate->setCarrier($this->_code);
$rate->setCarrierTitle($this->getConfigData('title'));
$rate->setMethod($method);
$rate->setMethodTitle($this->getCode('method', $method));
$rate->setDeliveryDate(date("l, F d",strtotime($deliveryTimestamp[$method])));
$rate->setDeliveryTime(date("h:i A", strtotime($deliveryTimestamp[$method])));
$rate->setCost($costArr[$method]);
$rate->setPrice($price);
$result->append($rate);
}
}
return $result;
}
Now we made sure that Fedex is returning transit data.
Displaying delivery data
Before we can use this on a template we need to add it to shipping rate. To do this we will overwrite importShippingRate method in Mage_Sales_Model_Quote_Address_Rate class and append our new data to shipping.
public function importShippingRate(Mage_Shipping_Model_Rate_Result_Abstract $rate)
{
$shippingRate = parent::importShippingRate($rate);
if($rate->getDeliveryDate()){
$shippingRate->setDeliveryDate($rate->getDeliveryDate());
$shippingRate->setDeliveryTime($rate->getDeliveryTime());
}
return $shippingRate;
}
Now we can simply access this in checkout\onepage\shipping_method\available.phtml template as $_rate attribute and create our delivery message.
<label for="s_method_<?php echo $_rate->getCode() ?>"><?php echo $this->escapeHtml($_rate->getMethodTitle()) ?>
<?php $_excl = $this->getShippingPrice($_rate->getPrice(), $this->helper('tax')->displayShippingPriceIncludingTax()); ?>
<?php $_incl = $this->getShippingPrice($_rate->getPrice(), true); ?>
<?php echo $_excl; ?>
<?php if ($this->helper('tax')->displayShippingBothPrices() && $_incl != $_excl): ?>
(<?php echo $this->__('Incl. Tax'); ?> <?php echo $_incl; ?>)
<?php endif; ?>
<?php if($_rate->getDeliveryDate()): ?>
<?php echo "Delivery on " . $_rate->getDeliveryDate(). " in " . $_rate->getDeliveryTime(); ?>
<?php endif ?>
</label>
This was a simple modification on an existing call and it gave us one useful feature that makes it easier for a customer to decide what shipping method to use. But there are many cool things that Fedex Api offers that are not used in Magento. I invite you to play with it and give a little more flexibility to your shipping methods.
If you find this useful and would like this functionality on some other shipping method please comment below.
8 comments
Thank you for share this awesome bog.
I want to customize the same thing for Magento 2. Can you please tell me how can I do the same thing for Magento 2.
How to do it with Magento 2?
That’s a good idea to show your customers shipping information. I would think that would be a good way to let them know when to expect the package. I would think it would be nice to know so that you could make sure that you get it inside the house before package thieves do.
I am having a bit of a hard time getting this to work.
Can you possible post a download of the modified files? It would be greatly appreciated.
Thank you
Any chance you will be posting a download?
Possible to post a download for an example extension utilizing these overwrites?
Thanks!
This is awesome if only we’re using Fedex. Too bad our local courier doesn’t have an API as powerful as Fedex. 🙁
Almost got it 🙂 After done, it was easy, working – magento 1.9.2.3
Thank You, Inchoo team!