Calculating Flat Rate Based on Customer’s Shipping Address
(I used Shipping 7.x-2.x and Flat Rate 7.x-1.0 for this one. For now I’m going to assume that you have your Flat rate shipping method and flat rate service set up).
What we would like to do here is to tell Drupal Commerce to calculate a shipping service’s fee based on our customer’s shipping address. For example: If a customer would like her product shipped to Cooltown, the courier service will charge $15, if she’d like the product shipped to Supercooltown, the courier service will charge $5.
We will use Rules for this.
Step by step:
- Go to Store -> Configuration -> Shipping -> Calculation rules and add a new calculation rule.
-
Deciding if the commerce line item’s type is Shipping
- Add a new condition and select Data comparison.
- Data selector should be ‘commerce-line-item:type’
- The comparison operator will be ‘equals’
- Data value will be Shipping
-
Deciding if the shipping service is the one you want to change the rate for
- Add a new condition and select Data comparison.
- Data selector should be ‘commerce-line-item:commerce-shipping-service’
- The comparison operator will be ‘equals’
- For data value you have to select the shipping service you want to change the rate for
- Add a condition "Entity has field". The data selector should be commerce-line-item:order and the value should be the field that has your the shipping information you want. I think in most of the cases this will be commerce_customer_shipping field.
- Add on OR to the condition list. Rules, by default, assumes that there is an AND connection between your added conditions and between the upcoming conditions there needs to be OR.
- Now we need to decide what component of the shipping address will we use to decide the shipping rate. For my situation, using the postal code was the best decision, so I’ll continue with that in this tutorial, but you can use any other available address component.
- Add a new condition and select Order address component comparison
- Data selector should be ‘commerce-line-item:order’
- In the Address section choose Shipping information’s address
- In the Address component section select the component you want use to decide the shipping rate.
- Operator should be ‘equals’
- In the Value section, put the specific address component you want to apply this rule for. Example: If I want to use this rule for orders that will be shipped to Kaposvár, Hungary then I should give the value 7400 which is its postal code.
- Click Save
- Put this condition into the OR group and if you create new order address compontent conditions, put them into it as well.
-
We’ve finished with the conditions, now let’s go to the Actions section and create a new action which will set the shipping rate to a specific amount if the above conditions are met.
- Add action and select Set the unit price to a specific amount
- Data selector should be commerce_line_item
- Value should be the price wou want to charge when shipping to this location you described in the conditions
- Price compontent type should be your shipping service’s name.
- Set the price rounding mode as you wish and hit Save
That’s it! If everything goes well, the rule will change the our shipping service’s rate when it’s needed.
I attached a screenshot of my rule, in case it would be helpful to you to see what we just did.
If you have any questions or corrections to this tutorial feel free to let me know in the comments section below.
Comments
"commerce-line-item:commerce-shipping-service" data selector
Hi,
I used Shipping 7.x-2.0-beta1 and Flat Rate 7.x-1.0-beta1 to create shipping rates by country using your documentation but for step 3 ("Deciding if the shipping service is the one you want to change the rate for") I don't have the "commerce-line-item:commerce-shipping-service" data selector.
Do you have a solution for this problem ?
subscribing
subscribing
This does not work
Don't try to do this, because it won't work. Because when you click on next to review the order, the original amount of the flat rate service is applied again. Instead watch this video which was made by rfay (of Commerce Guys)
http://commerceguys.com/blog/introduction-commerce-shipping-screencast
Subscribing
Subscribing
Hi,
Hi,
Can you tell me if this method works by distance?
So that the postage rate depends on the distance the customer is from the seller?
EG 0 - 25 miles = free postage
25-100 miles = £10
I've been trying to find a solution to this for a long time - any help would be really appreciated.
Many thanks, Joe
NOT WORKING
as other people already commended above, i am experiencing these errors:
a) during data comparison with data selector ‘commerce-line-item:commerce-shipping-service’, i get an empty selection box for value selection. – as if it was not finding any services (while in fact there are four.)
b) albeit it's not stated in this guide, I want to avoid having two shipping fields in the formatted compontents table. if I select "Base Price", it shows the new total price on the shipping pages, but gets set back to the original base price on the review page. I can manually select a specific shipping service, then it works fine for this one, but really i want to use it for multiple shipping services and set it so it adds to the unit price of every shipping service.
I am getting seriously frustrated here..
> update
upon updating to the latest commerce kickstart bundle (atm version 7.x-2.15) the issue addressed in section "a)" in my previous comment has been fixed: i am no longer presented with an empty list, but with a proper selection list.
however, as of now, I'm still not aware of a pretty solution to dynamically add the price to the current shipping service. I have had to use a rather ugly solution using a PHP evaluation in the "Add an amount to the unit price" action:
- for the "price component type" data selector I picked "commerce-line-item:commerce-shipping-service"
- and in addition to that i had to add the following PHP evaluation:
<?php
return 'flat_rate_'.$value;
?>
this mimics the way the array keys for the shipping components are created. – it's everything but pretty solution, but at least it's working for now. still, a way to dynamically add to whatever is the current shipping service would be great.
works!
This *did* work for me, and gave me a way to start a complex calculation rule that I was stuck at. Thank you so much for posting this!
Best guide ever
This was so clearly explained, so thoroughly documented, and WORKS EXACTLY AS IT SAYS.
Three qualities that are very much lacking in 95% of all Drupal documentation, whether official docs or answers on forums like these.
Perfect blend of clear instructions and explanation of why the instructions are so.
This post should be used as an example of how to ACTUALLY help people.
Thank you so much.
I still have an empty
I still have an empty commerce_shipping_services value list. Does somebody knows what or which module is causing the trouble?