create a custom shipping method in magento

In this blog post, we will see how to create a custom shipping method in magento.

Creating a custom shipping method is very easy, you just need to know all the useful functions to be used inside the shipping method class to put in various configuration options. We will see in this blog many different use cases and functions to use in shipping methods.
So let’s start of by creating the shipping method. I have used a module for this tutorial named Excellence_Ship. You can create your own module and change class names accordingly.
Attached is source code of the module shown in this blog
Error... Unable to load download template. Search single-download-template.tpl in your plugin folder!
These are the primary areas where the shipping method shows up

  • Admin Magento Admin - Custom Shipping Method
  • Frontend Magento Custom Shipping Method Checkout Page

To achieve this there are 3 things required

  • config.xml entries
  • system.xml entries
  • Shipping Module

    So lets start of with the steps.

    Step1

    First thing when creating a shipping method is to decide the code for the shipping method. In the current module i am using the code for shipping method as “excellence”. Next we will create the system.xml file for admin entries.

    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    <? xml version = "1.0" encoding = "UTF-8" ?>
    < config >
         < sections >
             < carriers >
                 < groups >
                     < excellence translate = "label" module = "ship" >
                         < label >Excellence Shipping Module</ label >
                         < frontend_type >text</ frontend_type >
                         < sort_order >99</ sort_order >
                         < show_in_default >1</ show_in_default >
                         < show_in_website >1</ show_in_website >
                         < show_in_store >1</ show_in_store >
                         < fields >
                             < active translate = "label" >
                                 < label >Enabled</ label >
                                 < frontend_type >select</ frontend_type >
                                 < source_model >adminhtml/system_config_source_yesno</ source_model >
                                 < sort_order >1</ sort_order >
                                 < show_in_default >1</ show_in_default >
                                 < show_in_website >1</ show_in_website >
                                 < show_in_store >1</ show_in_store >
                             </ active >
                             < title translate = "label" >
                                 < label >Title</ label >
                                 < frontend_type >text</ frontend_type >
                                 < sort_order >2</ sort_order >
                                 < show_in_default >1</ show_in_default >
                                 < show_in_website >1</ show_in_website >
                                 < show_in_store >1</ show_in_store >
                             </ title >
                             < name translate = "label" >
                                 < label >Method Name</ label >
                                 < frontend_type >text</ frontend_type >
                                 < sort_order >2</ sort_order >
                                 < show_in_default >1</ show_in_default >
                                 < show_in_website >1</ show_in_website >
                                 < show_in_store >1</ show_in_store >
                             </ name >
                             < price translate = "label" >
                                 < label >Price</ label >
                                 < frontend_type >text</ frontend_type >
                                 < sort_order >3</ sort_order >
                                 < show_in_default >1</ show_in_default >
                                 < show_in_website >1</ show_in_website >
                                 < show_in_store >0</ show_in_store >
                             </ price >
                             < specificerrmsg translate = "label" >
                                 < label >Displayed Error Message</ label >
                                 < frontend_type >textarea</ frontend_type >
                                 < sort_order >4</ sort_order >
                                 < show_in_default >1</ show_in_default >
                                 < show_in_website >1</ show_in_website >
                                 < show_in_store >1</ show_in_store >
                             </ specificerrmsg >
                             < sallowspecific translate = "label" >
                                 < label >Ship to Applicable Countries</ label >
                                 < frontend_type >select</ frontend_type >
                                 < sort_order >90</ sort_order >
                                 < frontend_class >shipping-applicable-country</ frontend_class >
                                 < source_model >adminhtml/system_config_source_shipping_allspecificcountries</ source_model >
                                 < show_in_default >1</ show_in_default >
                                 < show_in_website >1</ show_in_website >
                                 < show_in_store >0</ show_in_store >
                             </ sallowspecific >
                             < specificcountry translate = "label" >
                                 < label >Ship to Specific Countries</ label >
                                 < frontend_type >multiselect</ frontend_type >
                                 < sort_order >91</ sort_order >
                                 < source_model >adminhtml/system_config_source_country</ source_model >
                                 < show_in_default >1</ show_in_default >
                                 < show_in_website >1</ show_in_website >
                                 < show_in_store >0</ show_in_store >
                                 < can_be_empty >1</ can_be_empty >
                             </ specificcountry >
                         </ fields >
                     </ excellence >
                 </ groups >
             </ carriers >
         </ sections >
    </ config >

    So, let me explain this. first we always have to create our shipping method inside

    1
    2
    3
    < sections >
             < carriers >
                 < groups >

    As you can see the field have been created inside the ‘excellence’ tag which is our shipping method code. Next, we have created fields for active,title,name,price. There fields are required for every shipping method created. To know more details of system.xml entries please refer to this blog
    Next, i have included to more fields sallowspecific and specificcountry. This is required, when you want your shipping method to available for only few countries. To implement this restriction in the frontend (i.e suppose if user chooses India as shipping country our shipping doesnt show) we don’t have to do any more programming. Just included these two fields in the xml and country based restrictions start working automatically. Of course, we have to setup the country restriction in System Configuration in admin.
    Next, i have included specificerrmsg field. This field is used whenever there some error in our shipping method and we to show an error message to the user.

    Step2

    Next in our config.xml file of our module we add the below code directly inside the <config>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    < default >
             < carriers >
               < excellence >
                    < active >1</ active >
                    < model >ship/carrier_excellence</ model >
                    < title >Carrier Title</ title >
                    < name >Method Name</ name >
                    < price >5.00</ price >
                    < specificerrmsg >This shipping method is currently unavailable. If you would like to ship using this shipping method, please contact us.</ specificerrmsg >
                 </ excellence >
              </ carriers >
            </ default >

    As we know the <default> tag is used to assign default values to our system.xml fields created. So here we specify default values for active,title,name,price etc. The important field to notice here is the <model> which contains the path of our shipping model. This field is very important, or else the shipping method won’t show on frontend. After this step is over go to Admin -> System -> Configuration -> Shipping Methods and you should see your shipping method there with all the default values pre-filled.

    Magento Admin Custom Shipping Method

    Magento Admin Custom Shipping Method

    Step3

    Now all we need to do is to create our shipping model class. The model class name is Excellence.php and is created Model/Carrier folder.

    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
    38
    39
    40
    <?php
    class Excellence_Ship_Model_Carrier_Excellence  extends Mage_Shipping_Model_Carrier_Abstract
    implements Mage_Shipping_Model_Carrier_Interface {
         protected $_code 'excellence' ;
     
         public function collectRates(Mage_Shipping_Model_Rate_Request  $request )
         {
             if (!Mage::getStoreConfig( 'carriers/' . $this ->_code. '/active' )) {
                 return false;
             }
             
     
             $handling = Mage::getStoreConfig( 'carriers/' . $this ->_code. '/handling' );
             $result = Mage::getModel( 'shipping/rate_result' );
             $show = true;
             if ( $show ){  // This if condition is just to demonstrate how to return success and error in shipping methods
     
                 $method = Mage::getModel( 'shipping/rate_result_method' );
                 $method ->setCarrier( $this ->_code);
                 $method ->setMethod( $this ->_code);
                 $method ->setCarrierTitle( $this ->getConfigData( 'title' ));
                 $method ->setMethodTitle( $this ->getConfigData( 'name' ));
                 $method ->setPrice( $this ->getConfigData( 'price' ));
                 $method ->setCost( $this ->getConfigData( 'price' ));
                 $result ->append( $method );
     
             } else {
                 $error = Mage::getModel( 'shipping/rate_result_error' );
                 $error ->setCarrier( $this ->_code);
                 $error ->setCarrierTitle( $this ->getConfigData( 'name' ));
                 $error ->setErrorMessage( $this ->getConfigData( 'specificerrmsg' ));
                 $result ->append( $error );
             }
             return $result ;
         }
         public function getAllowedMethods()
         {
             return array ( 'excellence' => $this ->getConfigData( 'name' ));
         }
    }

    The above code is for our shipping model. The code is very basic, let go line by line

    1
    public function collectRates(Mage_Shipping_Model_Rate_Request  $request )

    This is the function which we need to implement. This function is called by magento for all the shipping methods to find out the shipping rates.

    1
    2
    3
    if (!Mage::getStoreConfig( 'carriers/' . $this ->_code. '/active' )) {
       return false;
    }

    This line simply checks if the shipping method is enabled from admin.

    1
    $result = Mage::getModel( 'shipping/rate_result' );

    here we create the result object, which is always returned from the shipping method collectRate function.

    1
    2
    3
    4
    5
    6
    7
    8
    $method = Mage::getModel( 'shipping/rate_result_method' );
    $method ->setCarrier( $this ->_code);
    $method ->setMethod( $this ->_code);
    $method ->setCarrierTitle( $this ->getConfigData( 'title' ));
    $method ->setMethodTitle( $this ->getConfigData( 'name' ));
    $method ->setPrice( $this ->getConfigData( 'price' ));
    $method ->setCost( $this ->getConfigData( 'price' ));
    $result ->append( $method );

    This code is used to return the shipping price. The code is quite clear.

    1
    2
    3
    4
    5
    $error = Mage::getModel( 'shipping/rate_result_error' );
    $error ->setCarrier( $this ->_code);
    $error ->setCarrierTitle( $this ->getConfigData( 'name' ));
    $error ->setErrorMessage( $this ->getConfigData( 'specificerrmsg' ));
    $result ->append( $error );

    The above code is used to return error message.

    After this model is created, the shipping method should be working properly. It will show up on the checkout page and cart page.

    Different Cases and Function to use inside shipping method

    All the function written below are to be implemented in the collectRates function only. I will write down function you can use to put your condition and calculate price, the price needs to be set in the result variable as shown above.
    Shipping Price is Based On Destination Country,State and Zip Code

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    //Case1: Price Depends on Country,State and Pin Code
             echo $destCountry $request ->getDestCountryId(). ': Dest Country<br/>' ;
             echo $destRegion $request ->getDestRegionId(). ': Dest Region<br/>' ;
             echo $destRegionCode $request ->getDestRegionCode(). ': Dest Region Code<br/>' ;
             print_r( $destStreet $request ->getDestStreet());  echo ': Dest Street<br/>' ;
             echo $destCity $request ->getDestCity(). ': Dest City<br/>' ;
             echo $destPostcode $request ->getDestPostcode(). ': Dest Postcode<br/>' ;
             echo $country_id $request ->getCountryId(). ': Package Source Country ID<br/>' ;
             echo $region_id $request ->getRegionId(). ': Package Source Region ID<br/>' ;
             echo $city $request ->getCity(). ': Package Source City<br/>' ;
             echo $postcode $request ->getPostcode(). ': Package Source Post Code<br/>' ;

    Use the above function to put conditions and set price based on your business logic.
    Shipping Price is based on total order cost or weight

    1
    2
    3
    4
    5
    6
    //Case2: Price Depends on Total Order Value or Weight
             echo $packageValue $request ->getPackageValue(). ': Dest Package Value<br/>' ;
             echo $packageValueDiscout $request ->getPackageValueWithDiscount(). ': Dest Package Value After Discount<br/>' ;
             echo $packageWeight $request ->getPackageWeight(). ': Package Weight<br/>' ;
             echo $packageQty $request ->getPackageQty(). ': Package Quantity <br/>' ;
             echo $packageCurrency $request ->getPackageCurrency(). ': Package Currency <br/>' ;

    Shipping Price Depends on Dimensions

    1
    2
    3
    4
    //Case3: Price Depends on order dimensions
             echo $packageheight $request ->getPackageHeight() . ': Package height <br/>' ;
             echo $request ->getPackageWeight(). ': Package Width <br/>' ;
             echo $request ->getPackageDepth(). ': Package Depth <br/>' ;

    Shipping Price Depends on Product Attributes
    As example, suppose we want to have shipping price different for each product. So for this, we create a product attribute called ‘shipping_price’ and on each product edit page in admin we assign the shipping price of the product. Now in our shipping method we need to access this shipping_price again and show the total shipping cost.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    //Case4: Price based on product attribute
             if ( $request ->getAllItems()) {
                 foreach ( $request ->getAllItems()  as $item ) {
                     if ( $item ->getProduct()->isVirtual() ||  $item ->getParentItem()) {
                         continue ;
                     }
     
                     if ( $item ->getHasChildren() &&  $item ->isShipSeparately()) {
                         foreach ( $item ->getChildren()  as $child ) {
                             if ( $child ->getFreeShipping() && ! $child ->getProduct()->isVirtual()) {
                                 $product_id $child ->getProductId();
                                 $productObj = Mage::getModel( 'catalog/product' )->load( $product_id );
                                 $ship_price $productObj ->getData( 'shipping_price' );  //our shipping attribute code
                                 $price += (float) $ship_price ;
                             }
                         }
                     else {
                         $product_id $item ->getProductId();
                         $productObj = Mage::getModel( 'catalog/product' )->load( $product_id );
                         $ship_price $productObj ->getData( 'shipping_price' );  //our shipping attribute code
                         $price += (float) $ship_price ;
                     }
                 }
             }

    Shipping Price Based on Configurable Product Option Selected
    Example, suppose on our website we have configurable product with Size as the drop down attribute. If user selected selects Size as Small the shipping cost is 15$, Medium is 20$ and Large is 25$.

    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    //Case5: Shipping option based configurable product option
             if ( $request ->getAllItems()) {
                 foreach ( $request ->getAllItems()  as $item ) {
                     if ( $item ->getProduct()->isVirtual() ||  $item ->getParentItem()) {
                         continue ;
                     }
                     if ( $item ->getHasChildren() &&  $item ->isShipSeparately()) {
                         foreach ( $item ->getChildren()  as $child ) {
                             if ( $child ->getFreeShipping() && ! $child ->getProduct()->isVirtual()) {
                                 $product_id $child ->getProductId();
                                 $value $item ->getOptionByCode( 'info_buyRequest' )->getValue();
                                 $params = unserialize( $value );
                                 $attributeObj = Mage::getModel( 'eav/config' )->getAttribute(Mage_Catalog_Model_Product::ENTITY, 'shirt_size' );  // our configurable attribute
                                 $attribute_id $attributeObj ->getAttributeId();
                                 $attribute_selected $params [ 'super_attribute' ][ $attribute_id ];
     
                                 $label '' ;
                                 foreach ( $attributeObj ->getSource()->getAllOptions(false)  as $option ){
                                     if ( $option [ 'value' ] ==  $attribute_selected ){
                                         $label =   $option [ 'label' ];
                                     }
                                 }
                                 if ( $label 'Small' ){
                                     $price += 15;
                                 else if ( $label 'Medium' ){
                                     $price += 20;
                                 else if ( $label 'Large' ){
                                     $price += 22;
                                 }
                             }
                         }
                     else {
                         $product_id $item ->getProductId();
                         $value $item ->getOptionByCode( 'info_buyRequest' )->getValue();
                         $params = unserialize( $value );
                         $attributeObj = Mage::getModel( 'eav/config' )->getAttribute(Mage_Catalog_Model_Product::ENTITY, 'shirt_size' );  // our configurable attribute
                         $attribute_id $attributeObj ->getAttributeId();
                         $attribute_selected $params [ 'super_attribute' ][ $attribute_id ];
     
                         $label '' ;
                         foreach ( $attributeObj ->getSource()->getAllOptions(false)  as $option ){
                             if ( $option [ 'value' ] ==  $attribute_selected ){
                                 $label =   $option [ 'label' ];
                             }
                         }
                         if ( $label 'Small' ){
                             $price += 15;
                         else if ( $label 'Medium' ){
                             $price += 20;
                         else if ( $label 'Large' ){
                             $price += 22;
                         }
                     }
                 }
             }

    Shipping Price based on Product Custom Options
    Example, suppose we have custom drop down options created for a simple product. The Custom Option is Delivery and values are Express,Normal. If user selects Express when adding product, the shipping cost is 50$ and for normal the cost is 10$.

    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    //Case6: Price based on custom options
             if ( $request ->getAllItems()) {
                 foreach ( $request ->getAllItems()  as $item ) {
                     if ( $item ->getProduct()->isVirtual() ||  $item ->getParentItem()) {
                         continue ;
                     }
                     if ( $item ->getHasChildren() &&  $item ->isShipSeparately()) {
                         foreach ( $item ->getChildren()  as $child ) {
                             if ( $child ->getFreeShipping() && ! $child ->getProduct()->isVirtual()) {
                                 $product_id $child ->getProductId();
                                 $value $item ->getOptionByCode( 'info_buyRequest' )->getValue();
                                 $params = unserialize( $value );
                                 $options_select $params [ 'options' ];
     
                                 $product = Mage::getModel( 'catalog/product' )->load( $product_id );
                                 $options $product ->getOptions();
                                 foreach ( $options as $option ) {
                                     if ( $option ->getGroupByType() == Mage_Catalog_Model_Product_Option::OPTION_GROUP_SELECT) {
                                         $option_id =   $option ->getId();
                                         foreach ( $option ->getValues()  as $value ) {
                                             if ( $value ->getId() ==  $options_select [ $option_id ]){
                                                 if ( $value ->getTitle() ==  'Express' ){
                                                     $price += 50;
                                                 } else if ( $value ->getTitle() ==  'Normal' ){
                                                     $price += 10;
                                                 }
                                             }
     
                                         }
                                     }
                                 }
                             }
                         }
                     else {
                         $product_id $item ->getProductId();
                         $value $item ->getOptionByCode( 'info_buyRequest' )->getValue();
                         $params = unserialize( $value );
                         $options_select $params [ 'options' ];
     
                         $product = Mage::getModel( 'catalog/product' )->load( $product_id );
                         $options $product ->getOptions();
                         foreach ( $options as $option ) {
                             if ( $option ->getGroupByType() == Mage_Catalog_Model_Product_Option::OPTION_GROUP_SELECT) {
                                 $option_id =   $option ->getId();
                                 foreach ( $option ->getValues()  as $value ) {
                                     if ( $value ->getId() ==  $options_select [ $option_id ]){
                                         if ( $value ->getTitle() ==  'Express' ){
                                             $price += 50;
                                         } else if ( $value ->getTitle() ==  'Normal' ){
                                             $price += 10;
                                         }
                                     }
     
                                 }
                             }
                         }
                     }
                 }
             }
- See more at: http://excellencemagentoblog.com/blog/2011/10/14/magento-create-custom-shipping-method/#sthash.JJ1i0tKj.dpuf
1. 用户与身体信息管理模块 用户信息管理: 注册登录:支持手机号 / 邮箱注册,密码加密存储,提供第三方快捷登录(模拟) 个人资料:记录基本信息(姓名、年龄、性别、身高、体重、职业) 健康目标:用户设置目标(如 “减重 5kg”“增肌”“维持健康”)及期望周期 身体状态跟踪: 体重记录:定期录入体重数据,生成体重变化曲线(折线图) 身体指标:记录 BMI(自动计算)、体脂率(可选)、基础代谢率(根据身高体重估算) 健康状况:用户可填写特殊情况(如糖尿病、过敏食物、素食偏好),系统据此调整推荐 2. 膳食记录与食物数据库模块 食物数据库: 基础信息:包含常见食物(如米饭、鸡蛋、牛肉)的名称、类别(主食 / 肉类 / 蔬菜等)、每份重量 营养成分:记录每 100g 食物的热量(kcal)、蛋白质、脂肪、碳水化合物、维生素、矿物质含量 数据库维护:管理员可添加新食物、更新营养数据,支持按名称 / 类别检索 膳食记录功能: 快速记录:用户选择食物、输入食用量(克 / 份),系统自动计算摄入的营养成分 餐次分类:按早餐 / 午餐 / 晚餐 / 加餐分类记录,支持上传餐食照片(可选) 批量操作:提供常见套餐模板(如 “三明治 + 牛奶”),一键添加到记录 历史记录:按日期查看过往膳食记录,支持编辑 / 删除错误记录 3. 营养分析模块 每日营养摄入分析: 核心指标计算:统计当日摄入的总热量、蛋白质 / 脂肪 / 碳水化合物占比(按每日推荐量对比) 微量营养素分析:检查维生素(如维生素 C、钙、铁)的摄入是否达标 平衡评估:生成 “营养平衡度” 评分(0-100 分),指出摄入过剩或不足的营养素 趋势分析: 周 / 月营养趋势:用折线图展示近 7 天 / 30 天的热量、三大营养素摄入变化 对比分析:将实际摄入与推荐量对比(如 “蛋白质摄入仅达到推荐量的 70%”) 目标达成率:针对健
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值