You don't actually need to hard code the values in GetServices, however, that routine is used in the UI to configure available shipping services. The available shipping services are created as ShippingOptionInfo objects. So, some how, you would need to create all the possible ShippingInfoObjects. As I mentioned, this could be done by a periodic Scheduled Task that will connect to the UPS service and pull down all available shipping services and merge them with the existing ShippingOptionInfo objects.
Personally I feel that it is better to have the GetServices routine return all available shipping services and have a store admin enable the ones they wish to offer. This is simple in the current design and pseudo code would look like:
public class UPSCarrier : ICarrierProvider
{
public bool CanDeliver(Delivery delivery)
{
//check if we have selected a shipping option
if (delivery.ShippingOption != null)
{
// look up if shipping option is available for the currently selected
// shipping option using delivery.ShippingOption.ShippingOptionCarrierServiceName
// delivery.ShippingOption.ShippingOptionCarrierServiceName should be the unique name
// returned in the GetServices routine (perhaps a UPS ServiceID?)
}
}
public decimal GetPrice(Delivery delivery, string currencyCode)
{
//check if we have selected a shipping option
if (delivery.ShippingOption != null)
{
// look up the price for shipping through the UPS API
// shipping option using delivery.ShippingOption.ShippingOptionCarrierServiceName
// delivery.ShippingOption.ShippingOptionCarrierServiceName should be the unique name
// returned in the GetServices routine (perhaps a UPS ServiceID?)
}
}
public List<KeyValuePair<string, string>> GetServices()
{
// get a list of UPS shipping services and add them to a list
// the Key should be unique and will be used to identify the different services
// offered by UPS.
var services = new SortedDictionary<string, string>
{
{SOME_UNIQUE_SERVICE_NAME, DESCRIPTION},
{SOME_UNIQUE_SERVICE_NAME, DESCRIPTION}
};
return services.ToList();
}
public string CarrierProviderName
{
get { return "UPS Shipping Provider"; }
}
public Guid GetServiceConfigurationUIElementGUID(string serviceName)
{
return Guid.Empty;;
}
public Guid GetConfigurationUIElementGUID()
{
return Guid.Empty;
}
}
On a side note here, having tried to find out a bit more detail about the UPS API I noticed that you do need a Key. You can do this by creating a Configuration UI and returning the GUID of that in GetConfigurationUIElementGUID() function.
The key thing behind implementing this as a Carrier is that module becomes portable. Kentico allows for it to be packaged using Nuget which can then be imported into another instance. It provides some protection for your module as it cannot be customized once installed. It's a great way for developers to create their own modules that can be imported as and when needed.