You could do this by customizing the code for your shipping on the confirm pages. It is a little custom but I think this would give you the correct result.
You can add two more conditions to the shipping. The first will be added to the high level check against the shipping setting in the globals file. If you are using UPS then on you confirm page the line currently looks like this:
if (($WAGLOBAL_Shipping_Enabled != "0")) {
//WA eCart (Copyright 2007, WebAssist)
//WA eCart UPS Shipping - UPS
You would first update this condition to be like this:
if (($WAGLOBAL_Shipping_Enabled != "0") && (WA_Store_Cart->TotalColumn('TotalWeight') > 0)) {
//WA eCart (Copyright 2007, WebAssist)
//WA eCart UPS Shipping - UPS
This will ensure that your cart has weight before calculating the shipping, if there is no weight there will be no shipping. The next thing to do is add another condition to the loop within this shipping quote server behavior, a little further down in the code look for this line:
if (WA_eCart_UPS_IsTrueValue("true")) {
Update it to be like this:
if (WA_eCart_UPS_IsTrueValue("true") && ($WA_Store_Cart->DisplayInfo("Weight") > 0)) {
This code is checking that the specific item in the cart has a weight, if not it will skip that item and move to the next. Give this a try and let us know if you get the result you are looking for. Remember to backup your confirm page first. Also, you would need to do the same thing on your pp_confirm page if you are using PayPal Express Checkout.