While Magento has been designed with best e-commerce practices in mind, it is sometimes desirable to change it’s default behavior to meet our specific requirements. In one of my recent projects shop was configured to accept two payments for the same shipping service – flat rate for smaller purchases and free shipping when customer spends higher amount of money. In this case it’s reasonable to present only one method depending on the total purchase and automatically preselect this option (saving customer the hassle to click on radio button while there’s only one option to choose). This functioanlity could be achieved with simple module presented below:
This module will overwrite Mage_Checkout_Onepage_Shipping_Method_Availabile block, here goes module configuration file
app/code/local/MageDev/Checkout/etc/config.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <?xml version="1.0"?> <config> <modules> <MageDev_Checkout> <version>0.0.1</version> </MageDev_Checkout> </modules> <global> <blocks> <checkout> <rewrite> <onepage_shipping_method_available>MageDev_Checkout_Block_Onepage_Shipping_Method_Available</onepage_shipping_method_available> </rewrite> </checkout> </blocks> </global> </config> |
And block definition goes into file:
app/code/local/MageDev/Checkout/Block/Onepage/Shipping/Method/Available.php
1 2 3 4 5 6 7 8 9 10 11 12 13 | <?php class MageDev_Checkout_Block_Onepage_Shipping_Method_Available extends Mage_Checkout_Block_Onepage_Shipping_Method_Available { public function getShippingRates() { $rates = parent::getShippingRates(); if (array_key_exists('freeshipping', $rates)) { $rates = array('freeshipping' => $rates['freeshipping']); } return $rates; } } |
This block gets array of available shipping methods from core Magento class and checks it against occurance of freeshipping index. In this case it returns only free shipping method.
Now it’s time to change template based on app/design/frontend/default/default/template/checkout/onepage/shipping_method/available.phtml. My version of this template is presented below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | <?php if (!($_shippingRateGroups = $this->getShippingRates())): ?> <strong><?php echo $this->__('Sorry, no quotes are available for this order at this time.') ?></strong> <?php else: ?> <dl class="shipment-methods"> <?php foreach ($_shippingRateGroups as $code => $_rates): ?> <dt><?php echo $this->getCarrierName($code) ?></dt> <dd> <ul> <?php foreach ($_rates as $_rate): ?> <li> <?php if ($_rate->getErrorMessage()): ?> <ul class="messages"><li class="error-msg"><ul><li><?php echo $_rate->getErrorMessage() ?></li></ul></li></ul> <?php else: ?> <?php if (1 == count($_shippingRateGroups) && 1 == count($_rates)) : ?> <input name="shipping_method" type="radio" value="<?php echo $_rate->getCode() ?>" id="s_method_<?php echo $_rate->getCode() ?>" checked="checked" style="display: none" /> <?php else : ?> <input name="shipping_method" type="radio" value="<?php echo $_rate->getCode() ?>" id="s_method_<?php echo $_rate->getCode() ?>"<?php if($_rate->getCode()===$this->getAddressShippingMethod()) echo ' checked="checked"' ?> /> <?php endif; ?> <label for="s_method_<?php echo $_rate->getCode() ?>"><?php echo $this->__($_rate->getMethodTitle()) ?> <strong> <?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; ?> </strong> </label> <?php endif ?> </li> <?php endforeach; ?> </ul> </dd> <?php endforeach; ?> </dl> <?php endif; ?> |
After enabling the module by setting app/etc/modules/MageDev_Checkout.xml only free shipping method, when available, will be displayed during checkout process. Furthermore radio input for selecting shipping method will be hidden if only one method is available.



Thanks for your tutorial. but
app/code/local/MageDev/Checkout/etc/config.xml doesn’t exist in 1.3.2.2 what file is meant to be changed?
Hi Popkorn,
The app/code/local directory is meant to be storage for custom modules (outside of Magento core). Here I used MageDev prefix to group all my code and Checkout for this particular module. You must create the same directory/file structure and enable the module by adding config file in app/etc/modules to use the code.
ok, thanks. i’ll try it this week.
Hi.
What exactly do you mean with:
“After enabling the module by setting app/etc/modules/MageDev_Checkout.xml”
?
Thanks in advance,
Stevo.
Hello Steve,
Each module needs to be enabled by creating xml config file inside app/etc/modules directory (in file matching [Company]_[ModuleName].xml pattern). In this case there should be created MageDev_Checkout.xml file similar to:
very nice tool but freeshipping over catalogrules or salesrules not supported…
Hi kn,
Thanks for comment. This tutorial was intended to show how to obtain certain shipping methods when using onepage checkout. If I remember correctly only freeshipping and table rates are supposed to be free when setting Free Shipping to Shopping Cart Price Rules. It should be fairly easy to apply custom shipping method selection with MageDev_Checkout_Block_Onepage_Shipping_Method_Available::getShippingRates() method. Let me know if you have any problems with that.
hey there,
I just tried this, but I couldn’t get it to work. What version of magento did you try this on?
Also, in my copy of magento 1.3.2.2, the reference to app/design/frontend/default/default/template/checkout/shipping_method/available.phtml does not exist.
I did find it here though: app/design/frontend/default/default/template/checkout/onepage/shipping_method/available.phtml.
Is the latter location correct, or is this just a difference between our copies of Magento?
Thanks again for the tutorial.
Hi Joe,
Thanks for pointing that out – template location should be placed inside ‘onepage’ directory.
I build this module for Magento 1.3.1, please let me know what exactly doesn’t work for you.
it would be nice if you create a magento community extension
No problem. The problem is that no options display in the “Shipping Method” part of the one page checkout. I’ve enabled the module appropriately and triple checked the code, so I think something else might be interfering with the output of the option.
PM me if you want me to send you a link and screenshot.
Yes, I have the same problem. I am using 1.3.2.3
Please help me out….
Hey guys,
Thanks for pointing that out. The location of Available.php file should be: app/code/local/MageDev/Checkout/Block/Onepage/Shipping/Method/Available.php and not app/code/local/MageDev/Checkout/Block/Shipping/Onepage/Shipping/Method/Available.php.
How can we disabled all the shipping methods?
I do not want shipping methods anymore.
Thanks,
Vijay Thummar
Why do you want to get rid of shipping methods? Is your product not physically dispatched to customer? If so try to use virtual products (or if user should be able to download the product – downloadable products).
Thanks for this great tutorial! This is exactely what I’ve been looking for!
It worked perfectly on a local machine with MAMP & Magento 1.3.2.4!
After uploading the files to their proper locations on my webserver the ‘shipping method’ part of onepage checkout remains empty… I checked everything twice… code, file names, file locations…
Any clue what this might be about?
Thanks in advance, PP
Thanks for this tutorial but I have a question: I enabled fix costs and free shipping, if the order has 45€ or more the shipping will be free. I am install this hack but now when I checkout:
“Your order can not be completed at this time as there is no shipping methods available for it. Please make neccessary changes in your shipping address.”
How can I solve this problem?
Thank you for this tutorial. I would like to enable the free shipping method for a virtual product (don’t ask why
. I already managed that the shipping method is shown by overriding the isVisible(), but unfortunatly it still doesn’t work. Any idea how to enable this?
Hi Joe,
Most of functionality of virtual products is about not accepting shipping. It’s much more than just displaying shipping methods – it’s also about collecting shipping address, data validation, order workflow… Do you really need to enable shipping for virtual products?
Thanks for the tutorial! It saved me hours and worked like a charm following your instructions and some comments. My shop goes into production in 2 days and this was one of the final things to do.
Ciao
- Using Magento 1.3.2.4
Hi!
How come you guys could enable checkout when no shipping method is availlable (if (!($_shippingRateGroups = $this->getShippingRates()))…).
Clearly said, I need to display some message saying shipping could not bet calculated but still being able to process order.
Thanks in advance if you can help
hi,
this approach is quite nice, but actually you can simply add
to the beginning of app/design/frontend/default/YOURTHEME/template/checkout/onepage/shipping_method/available.phtml
add the code right after
getShippingRates())): ?>
__(‘Sorry, no quotes are available for this order at this time.’) ?>
…right here, at the beginning of the ‘else’ statement, and there you go, without all the module-mumbo-jumbo…
peace!
ooops, my code got killed because of php-tags…
here’s the snippet again:
if(array_key_exists(‘freeshipping’, $_shippingRateGroups)) {
$realgroup['freeshipping'] = $_shippingRateGroups['freeshipping'];
$_shippingRateGroups = $realgroup;
}
Hi, thanks a lot for this great contribution. I tried it and it works. I am using 1.3.1 and go through Onepage.
But for some reason on the checkout/cart page (My Cart) you can still see other shipping methods at the “Estimate Shipping” section. Although if you try clicking other than free shipping it still forces it be free.
Hope you understand what I mean. But it really works good.
HI ,Thanks a lot for this great contribution
Hi,
just tested it with 1.5.1 and works fine.
Thank you!