Dynamic Priced Shipping Method causing a NRE when updating order
Which component is this issue related to?
Umbraco Commerce (Core)
Which Umbraco Commerce version are you using? (Please write the exact version, example: 10.1.0)
13.2.2
Bug summary
When selecting a Dynamic Shipping Method configured purely via the back office (no custom calculator code), checkout fails with a NullReferenceException. Flat-rate shipping methods work without issue — only dynamic shipping methods trigger the error.
Code being called:
_commerceApi.Uow.Execute(uow =>
{
var store = _settingsService.GetStore();
var order = _commerceApi.GetOrCreateCurrentOrder(store.Id)
.AsWritable(uow)
.SetShippingMethod(shippingMethodId);
_commerceApi.SaveOrder(order);
uow.Complete();
});
Specifics
- No custom shipping calculator implemented
- Dynamic rate created according to official documentation
- Order currency & shipping address present and valid
- ShippingMethodId is correctly assigned to the order on update
- Only difference between working and failing shipping methods: Dynamic vs Flat
Steps to reproduce
- Create a Dynamic Shipping Method via back office:
Add valid pricing rules/bands Save & publish
- Add product to cart and proceed to checkout
- Select the Dynamic Priced Shipping method and submit form/trigger update of order shipping method/continue with checkout flow
- NRE thrown during
_api.SaveOrder(order)
Expected result / actual result
Expected Result Order is updated with the correct shipping method and pricing, and no errors are thrown/checkout flow continues as expected
Actual Result A NullReferenceException is thrown when updating the shipping method
Dependencies
No response
Hi @Rian-BG ,
I've tried replicating this on our demo store, but the checkout process went through successfully. Could you share some details on your dynamic shipping method configuration, the defined ranges?
Thanks, Adrian
Hey @acoumb
Thanks for getting back to me so soon.
Please see below the rates set:
I also did test it with only a 1 - Unbound range, assuming that would act as a catch-all.
@Rian-BG could you provide the entire configuration (SKU, Countries) of the shipping method config, maybe also the controller action you use?
Apologies for the wait, busy busy.
Controller action:
public IActionResult UpdateOrderShippingMethod(UpdateOrderShippingMethodDto model)
{
try
{
_checkoutService.UpdateOrderShippingMethod(model.ShippingMethod);
}
catch (CommerceException)
{
ModelState.AddModelError("", "Failed to set order shipping method");
return CurrentUmbracoPage();
}
if (model.NextStep.HasValue)
return RedirectToUmbracoPage(model.NextStep.Value);
return RedirectToCurrentUmbracoPage();
}
Service method:
public void UpdateOrderShippingMethod(Guid? shippingMethodId)
{
if (shippingMethodId is null || shippingMethodId == Guid.Empty)
throw new ArgumentNullException(nameof(shippingMethodId));
try
{
//_commerceApi.Uow.Execute(uow =>
//{
// var store = _settingsService.GetStore();
// var order = _commerceApi.GetOrCreateCurrentOrder(store.Id)
// .AsWritable(uow)
// .SetShippingMethod(shippingMethodId);
// _commerceApi.SaveOrder(order);
// uow.Complete();
//});
_commerceApi.Uow.Execute(uow =>
{
var store = _settingsService.GetStore();
var order = _commerceApi.GetOrCreateCurrentOrder(store.Id)
.AsWritable(uow);
var selectedShippinOptionId =
shippingMethodId.HasValue &&
order.ShippingInfo.ShippingMethodId.HasValue &&
shippingMethodId == order.ShippingInfo.ShippingMethodId
? order.ShippingInfo.ShippingOption?.Id
: null;
if (!selectedShippinOptionId.IsNullOrWhiteSpace())
{
var shippingMethod = _commerceApi.GetShippingMethod((Guid)shippingMethodId);
var shippingRateAttempt = shippingMethod.TryCalculateRate(selectedShippinOptionId, order);
order.SetShippingMethod((Guid)shippingMethodId, shippingRateAttempt.Result.Option);
}
else
{
order.SetShippingMethod((Guid)shippingMethodId);
}
_commerceApi.SaveOrder(order);
uow.Complete();
});
}
catch (ValidationException ex)
{
_logger.LogError(ex, $"An error occurred during updating order shipping method.");
throw new CommerceException("Failed to update order shipping method.");
}
}
I attempted to use the Demo Store code, as it had more validation - the commented out version is our original code. However, on calling _commerceApi.SaveOrder(order); it still throws a NRE.
Screenshot of the whole shipping method: https://gyazo.com/7a9401446a7b3504c8b0becf982e1c94
Please let me know if you require anything else.
Please find below the objects that are passed in .SaveOrder(order) in the different cases.