Add free shipping discount to shopping cart by Kentico API

Tomasz Czado asked on August 28, 2015 14:52

How can I apply free shipping discount to shopping cart, that I want?

For example:

  • I have defined discount (so I can get DiscountInfo by DiscountID)
  • I have overridden CalculateShippingInternal(ShoppingCartInfo cart) method in CustomShippingOptionInfoProvider
  • CalculateShippingDiscount is not overridden

Inside definition of above method I have implemented something like this:

double totalShippingCost;

DiscountInfo discountInfo = DiscountInfoProvider.GetDiscountInfo(12);
cart.Discounts.Add(discountInfo);
ShoppingCartInfoProvider.SetShoppingCartInfo(cart);

totalShippingCost -= CalculateShippingDiscount(cart, totalShippingCost);
totalShippingCost = cart.RoundTo(totalShippingCost);

return totalShippingCost;

But that doesn't work - it doesn't reduce shipping cost to $0 for free shipping. So what I need to do to use free shipping? How to apply it by API?

Recent Answers


Dawid Jachnik answered on August 28, 2015 16:02

Hello Tomasz, You can replace this code:

totalShippingCost -= CalculateShippingDiscount(cart, totalShippingCost);
totalShippingCost = cart.RoundTo(totalShippingCost);
return totalShippingCost;

with that:

return base.CalculateShippingInternal(cart) - CalculateShippingDiscount(cart, totalShippingCost);   

Hope it should work :)

Like on the sample:

    /// <summary>
/// Calculates shipping charge for the given shopping cart.
/// Shipping taxes are not included. Result is in site main currency.
/// </summary>
/// <param name="cart">Shopping cart data</param>
protected override double CalculateShippingInternal(ShoppingCartInfo cart)
{
    // ------------------------
    // Please note:         
    // You can customize this method to calculate shipping by a on-line shipping calculation service as well.
    // All the data which might be required for the calculation service is stored in the ShoppingCartInfo object, e.g.:
    // - use cart.ShoppingCartBillingAddress to get billing address info
    // - use cart.ShoppingCartShippingAddress to get shipping address info        
    // etc.
    // ------------------------

    // Calculates shipping based on customer's shipping address country
    if (cart != null)
    {
        // Get shipping address details, use billing address if shipping address is not entered
        IAddress address = cart.ShoppingCartShippingAddress ?? cart.ShoppingCartBillingAddress;

        if (address != null)
        {
            // Get shipping address country
            CountryInfo country = CountryInfoProvider.GetCountryInfo(address.AddressCountryID);
            if ((country != null) && (country.CountryName.ToLowerCSafe() != "usa"))
            {
                // Get extra shipping for non-usa customers from 'ShippingExtraCharge' custom setting 
                double extraCharge = SettingsKeyInfoProvider.GetDoubleValue("ShippingExtraCharge");

                // Add an extra charge to standard shipping price for non-usa customers
                return base.CalculateShippingInternal(cart) + extraCharge;
            }
        }
    }

    // Calculate shipping option without tax in default way
    return base.CalculateShippingInternal(cart);
}
2 votesVote for this answer Mark as a Correct answer

Tomasz Czado answered on August 28, 2015 16:57

Thank you for quick answer. Unfortunately it is not exactly, what I'm looking for. I wrote something like this:

DiscountInfo discountInfo = DiscountInfoProvider.GetDiscountInfo(12);
double discountValue = ECommerceHelper.GetDiscountValue(totalShippingCost, discountInfo.DiscountValue, true);

double shippingDiscount = CalculateShippingDiscount(cart, totalShippingCost);
totalShippingCost -= shippingDiscount;
totalShippingCost = cart.RoundTo(totalShippingCost);

return totalShippingCost;
0 votesVote for this answer Mark as a Correct answer

Virgil Carroll answered on August 31, 2015 15:18

Tomasz,

Can i ask have you looked at using the Order Discounts through the admin interface? Instead of doing custom code? You could easily setup free shipping parameters.

Just thought i would ask, but not sure if your business requirements require something special.

1 votesVote for this answer Mark as a Correct answer

Tomasz Czado answered on August 31, 2015 23:05

Yes, I did, but since I wanted to do it directly by API, I only used Free Shipping admin application to set discount. Than I wanted to apply shipping discount through API, but that wouldn't work for me.

I thought, that if I add discount by cart.Discounts.Add(discountInfo) and than recalculate discount by CalculateShippingDiscount() - it will work. But it will not probably because CalculateShippingDiscount() checks discounts conditions.

0 votesVote for this answer Mark as a Correct answer

Virgil Carroll answered on September 1, 2015 06:00

Ok so maybe i am misunderstanding. You set a discount in the admin interface, correct? Then you want to call that discount manually, through code, for every shopping cart, correct?

First you should always call the base of the overridden class (like in the sample code Dawid shared) this will make sure that any other discounts get call that you are not handling in code first and then yours would process.

Second though i have nit tried this i am pretty sure setting an additional discount object will not work because this class function is called after discounts are applied, so adding another wont add that to the group to process like you are showing.

If you want to do it this way, still get your discount then grab its currency value and return the final value like Dawid described above except do it like: base.CalculateShippingInternal(cart) - yourDiscount

You are on the right track but can accomplish this by being more direct in your code vs. trying to call more internal functions to apply it.

0 votesVote for this answer Mark as a Correct answer

   Please, sign in to be able to submit a new answer.