E-Commerce - Add Handling fee based on Payment Method

Aaron Fickes asked on September 13, 2016 00:24

Current site was upgraded from Kentico v7 to v9 and have replaced the old shopping cart web-part with the a checkout wizard.

Where can I add a handling fee during the checkout process based on the payment method.
For example, If the visitor pays by credit card, I wish to add a handling fee associated with it. It should act like a flat fee for the order and not based on products. We are currently using the AuthorizeNet payment gateway to process the credit card orders.

Since the site does not charge shipping as they are digital goods, I attempted to use the Custom Shipping provider, but I only have access to the Delivery. public decimal GetPrice(Delivery delivery, string currencyCode)

Is there a better way? Am I missing something in the API?

Correct Answer

Richard Sustek answered on September 13, 2016 07:20

You could try overriding the ShoppingCartInfoProvider.CalculateTotalPriceInternal method if you want to add some custom pricing to the order. You have whole shopping cart passed via parameter so you can pretty much calculate anything you want.

Example:

using CMS;
using CMS.Ecommerce;
using System;

[assembly: RegisterCustomProvider(typeof(CustomShoppingCartInfoProvider))]
public class CustomShoppingCartInfoProvider : ShoppingCartInfoProvider
{
    private double creditCardFee = 2; // $ - should be configurable from UI

    protected override double CalculateTotalPriceInternal(ShoppingCartInfo cart)
    {
        var totalPrice = base.CalculateTotalPriceInternal(cart);

        // check payment method
        if (cart.PaymentOption.PaymentOptionName.Equals("CreditCard", StringComparison.OrdinalIgnoreCase))
        {
            // add processing fee
            totalPrice += creditCardFee;
        }

        return totalPrice;
    }
}
1 votesVote for this answer Unmark Correct answer

Recent Answers


Aaron Fickes answered on September 14, 2016 22:10 (last edited on September 19, 2016 15:38)

Thanks for the sample - I used this code and modified it so the actual calculation is in a public class/method to calculate costs based on Payment Name / Fee from a Custom Table. I then created another webpart to display the fee as a separate line in the Checkout Order Summary (uses that public method above). The Fee now displays, but the cart total is unchanged. https://gyazo.com/ca10eff03d5069a1cd9b38c04a9fc1bc

How do I 'enable' the new CustomShoppingCartInfoProvider? I understand how to do this with a new CustomShippingProvider : ICarrierProvider because it is a new carrier which is configurable within the CMS. The Total is using the Shopping Cart Totals webpart.

Edit - This https://docs.kentico.com/display/K9/Registering+providers+using+assembly+attributes shows that it should 'just work' with the assembly decorations. I have a breakpoint on the new provider and it never fires.

Edit2- Not the most elegant code, but it's within App_Code as the bottom static class method fires for the webpart display.

using CMS;
using CMS.CustomTables;
using CMS.Ecommerce;
using System;
using System.Linq;

[assembly: RegisterCustomProvider(typeof(ShoppingCartFee))]
public class ShoppingCartFee : ShoppingCartInfoProvider
{
    protected override double CalculateTotalPriceInternal(ShoppingCartInfo cart)
    {
        var totalPrice = base.CalculateTotalPriceInternal(cart);
        totalPrice += CalculateShoppingCartFee.Calculate(cart.PaymentOption.PaymentOptionDisplayName);

        return totalPrice;
    }
}

public static class CalculateShoppingCartFee
{
    public static double Calculate(string PaymentName)
    {
        double totalFee = 0;

        CMS.DataEngine.ObjectQuery<CustomTableItem> cti = CustomTableItemProvider.GetItems("tcle.PaymentTypeFee");

        var fees = from f in cti.AsEnumerable()
                   select new
                   {
                       paymentName = f.GetValue<string>("PaymentName", ""),
                       fee = Convert.ToDouble(f.GetValue<float>("Fee", 0f))
                   };
        foreach (var f in fees)
        {
            if (PaymentName.ToLower() == f.paymentName.ToLower())
            {
                totalFee = f.fee;
                break;
            }
        }

        return totalFee;
    }
}

//snippet of webpart using similar code

var paymentName = ECommerceContext.CurrentShoppingCart.PaymentOption.PaymentOptionDisplayName;
double fee = CalculateShoppingCartFee.Calculate(paymentName);


Edit3 - The typeof in the decorator was changed to my class definition, not the overridden class. it now works as intended.
0 votesVote for this answer Mark as a Correct answer

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