Order and payment processing breaking changes
Breaking changes to the order system, workflow engine, discount infrastructure, and payment processing APIs in Commerce Connect 15.
This article covers breaking changes to the order system, payment processing pipeline, workflow engine, and discount infrastructure in Commerce Connect 15.
Workflow engine removal
The entire legacy workflow engine has been removed from Commerce 15. This is one of the largest breaking changes in this release. The following components are affected:
Mediachase.Commerce.Workflow project (removed)
The Mediachase.Commerce.Workflow project and assembly have been completely removed. This project contained all legacy workflow activity implementations:
- All
ActivityFlowimplementations (CartCheckoutActivityFlow,CartPrepareActivityFlow,CartValidateActivityFlow, etc.) - All
Activityimplementations (ProcessPaymentActivity,CalculateTotalsActivity,AdjustInventoryActivity, etc.) - The assembly
Mediachase.Commerce.Workflow.dllis no longer produced or distributed.
Any code that references this assembly will fail to compile. Remove all references and using statements for Mediachase.Commerce.Workflow namespaces.
ActivityFlow engine infrastructure (removed)
The following types in Mediachase.Commerce.Engine have been removed:
ActivityFlow(abstract base class)ActivityFlowRunnerActivityFlowContextActivityFlowContextPropertyAttributeActivityFlowConfigurationAttributeActivityFlowEventArgsExecutionManagerWorkflowResultsWorkflowStatusenumDuplicatedPropertyExceptionInternal.ActivityFlowModelMediachase.Commerce.Extensions.ActivityFlowExtensions
WorkflowCompatibility namespace (removed)
The entire Mediachase.Commerce.WorkflowCompatibility namespace has been removed:
Activity(abstract base class)ActivityExecutionContextActivityExecutionStatusenumConditionalEventArgsValidationErrorValidationErrorCollectionWorkflowValidationFailedException
OrderGroupWorkflowManager (removed)
Mediachase.Commerce.Orders.Managers.OrderGroupWorkflowManager has been entirely removed.
Workflow-dependent methods (removed)
The following methods that depend on the workflow infrastructure have been removed:
OrderStatusManager (all obsolete methods):
RecalculatePurchaseOrder(PurchaseOrder)(all overloads)CancelOrder(PurchaseOrder)andCancelOrder(PaymentPlan)HoldOrder(PurchaseOrder)andHoldOrder(PaymentPlan)ReleaseHoldOnOrder(PurchaseOrder)andReleaseHoldOnOrder(PaymentPlan)ReleaseOrderShipment(Shipment)CancelOrderShipment(Shipment)CompleteOrderShipment(Shipment)PickForPackingOrderShipment(Shipment)ReturnFromPackingOrderShipment(Shipment)ProcessOrder(PurchaseOrder)
ReturnExchangeManager:
RecalculateReturnOrderForm(OrderForm)ExecuteReturnFormWorkflow(string, OrderForm)
ReturnFormStatusManager:
CompleteReturn(OrderForm)(all overloads)CancelReturn(OrderForm)(all overloads)AcknowledgeReceiptItems(OrderForm)(all overloads)
OrderGroup:
RunWorkflow(string)(all 3 overloads)
OrderContext:
ExecutionManagerproperty
Migration path
Migrate all workflow-based order processing to the modern processor-based APIs:
For order calculations:
- Use
IOrderGroupCalculatorfor order totals calculation. - Use
ITaxCalculatorfor tax calculations. - Use
IShippingCalculatorfor shipping cost calculations.
For promotions:
- Use
IPromotionEnginefor applying promotions and discounts.
For order processing:
- Use
IPurchaseOrderProcessorfor purchase order operations (cancel, hold, release, process). - Use
IPaymentPlanProcessorfor payment plan operations. - Use
IShipmentProcessorfor shipment operations (release, cancel, complete, pick for packing).
For cart operations:
- Use
ICartServicefor cart management. - Use
IOrderRepositoryfor saving and loading orders. - Use
IOrderGroupExtensions.ValidateOrder()for cart validation. - Use
OrderGroupExtensions.CalculateTotals()for cart/order total calculations.
For inventory:
- Use
IInventoryProcessorfor inventory adjustments.
For payment processing:
- Use
IPaymentProcessorfor payment authorization and capture. - Implement custom payment gateways using
IPaymentPlugininterface.
For status management, use the non-obsolete methods in OrderStatusManager:
IsOrderCancellable(PurchaseOrder/PaymentPlan)IsOrderHoldable(PurchaseOrder/PaymentPlan)IsShipmentReleasable(Shipment)IsShipmentCancellable(Shipment)IsShipmentCompletable(Shipment)IsShipmentPackable(Shipment)GetPurchaseOrderStatus(PurchaseOrder/PaymentPlan)GetOrderShipmentStatus(Shipment)
For return form processing:
- Use
IReturnOrderService.CompleteReturnfor completing returns. - Use
IReturnOrderService.CancelReturnfor canceling returns.
Example migration:
// Before (Commerce 14) - Workflow-based
cart.RunWorkflow(OrderGroupWorkflowManager.CartCheckOutWorkflowName);
// After (Commerce 15) - Processor-based
var validationIssues = cart.ValidateOrder();
if (!validationIssues.Any())
{
var orderReference = _orderRepository.SaveAsPurchaseOrder(cart);
var purchaseOrder = _orderRepository.Load<IPurchaseOrder>(orderReference.OrderGroupId);
// Process payment
var processedPayments = purchaseOrder.GetFirstForm().Payments
.Where(p => _paymentProcessor.ProcessPayment(purchaseOrder, p, shipment));
// Calculate totals
var totals = _orderGroupCalculator.GetOrderGroupTotals(purchaseOrder);
// Adjust inventory
_inventoryProcessor.AdjustInventoryOrRemoveLineItem(
shipment, OrderStatus.InProgress, (item, issue) => { });
_orderRepository.Save(purchaseOrder);
}Discount infrastructure removal
The obsolete discount infrastructure has been removed. These classes were marked obsolete since August 2018 with guidance to use the promotion system in EPiServer.Commerce.Marketing instead.
Removed types
Mediachase.Commerce.Orders.Discount(abstract base class)Mediachase.Commerce.Orders.LineItemDiscountMediachase.Commerce.Orders.OrderFormDiscountMediachase.Commerce.Orders.ShipmentDiscountMediachase.Commerce.Orders.LineItemDiscountCollectionMediachase.Commerce.Orders.OrderFormDiscountCollectionMediachase.Commerce.Orders.ShipmentDiscountCollection
Removed discount collection properties
LineItem.Discounts, OrderForm.Discounts, and Shipment.Discounts collections have been removed, including all serialization support for these discount collections.
Migration path
Use the modern promotion engine:
- Use
EPiServer.Commerce.Marketing.IPromotionEnginefor applying promotions and discounts. - Create promotions using the built-in promotion types in
EPiServer.Business.Commerce.Marketing.Promotions. - Implement custom promotions by inheriting from
PromotionDataand creating custom promotion processors. - Use
IOrderGroupextension methods for retrieving applied discount information:GetDiscountTotal()– Get total discount amount on order/form/line item.GetShipmentDiscountPrice()– Get discount applied to shipment.
- Access discount details through
IOrderForm.PromotionsandILineItemextension methods.
IOrderGroup.Market property removal
The IOrderGroup.Market property has been removed. This property was marked obsolete since May 2019. It has been removed from:
EPiServer.Commerce.Order.IOrderGroupinterfaceMediachase.Commerce.Orders.OrderGroupclassEPiServer.Commerce.Order.Internal.InMemoryOrderGroupclassEPiServer.Commerce.Order.Internal.InMemoryPurchaseOrderclassEPiServer.Business.Commerce.Order.Internal.SerializableCartclass
Use IMarketService to get the market from the order's MarketId:
// Before (Commerce 14)
var market = orderGroup.Market;
// After (Commerce 15)
var market = _marketService.GetMarket(orderGroup.MarketId);ILineItemInventory removal
The ILineItemInventory interface in Mediachase.Commerce.Orders has been removed. This interface was obsoleted in 2018 with guidance to use IInventoryService instead. The interface implementation has been removed from LineItem and SerializableLineItem classes.
The properties that were part of ILineItemInventory (Code, AllowBackordersAndPreorders, InStockQuantity, BackorderQuantity, PreorderQuantity, InventoryStatus, MaxQuantity, MinQuantity) remain available directly on the LineItem class for backward compatibility, though inventory operations should use IInventoryService.
LineItem obsolete properties removal
The following obsolete properties have been removed from Mediachase.Commerce.Orders.LineItem:
| Removed Property | Replacement |
|---|---|
MinQuantity | Use content API to get minimum order quantity from entry content |
MaxQuantity | Use content API to get maximum order quantity from entry content |
ListPrice | Use IPriceService to get list prices |
ShippingAddressId | Not used |
ShippingMethodName | Use IShipment.ShippingMethodId to get shipping method information |
ShippingMethodId | Use IShipment.ShippingMethodId instead |
InStockQuantity | Use IInventoryService.Get() to get inventory information |
PreorderQuantity | Use IInventoryService.Get() to get preorder quantity from InventoryRecord |
BackorderQuantity | Use IInventoryService.Get() to get backorder quantity from InventoryRecord |
OrderSearchFilter.MarketId removal
The OrderSearchFilter.MarketId property has been removed. Use MarketIds (plural) instead for filtering by multiple markets. The MarketIds property accepts an IEnumerable<string> for specifying one or more market IDs:
// Before (Commerce 14)
var filter = new OrderSearchFilter { MarketId = "US" };
// After (Commerce 15)
var filter = new OrderSearchFilter { MarketIds = new[] { "US" } };OrderStatusManager.IsOrderPaid removal
OrderStatusManager.IsOrderPaid(PurchaseOrder) has been removed. Use the IPurchaseOrder.IsPaid() extension method from the EPiServer.Commerce.Order namespace instead.
OrderGroup.PopulateCollection removal
The OrderGroup.PopulateCollection<T> internal protected method has been removed. The Cart class now uses its own PopulateCartCollection method for loading cart collections from the database.
PurchaseOrderManager methods removal
All three overloads of PurchaseOrderManager.AddLineItemToShipmentDetectedByLineItemShipmentInfo have been removed. This functionality is no longer supported. Use the standard shipment and line item APIs to manage order shipments.
OrderCache.CreateCacheKey overload removal
The OrderCache.CreateCacheKey(CultureInfo, params string[]) overload has been removed. Use CreateCacheKey(params string[] keys) instead (without CultureInfo).
Tax API changes
TaxManager.GetTaxes(Guid siteId, ...)– The overload withsiteIdparameter has been removed. Site functionality is no longer supported. Use theGetTaxesoverload without thesiteIdparameter.TaxDto.TaxValueRow.SiteIdproperty and related members (IsSiteIdNull(),SetSiteIdNull()) have been removed. Tax values are now application-wide and not site-specific.- The
TaxValueDataTable.AddTaxValueRowmethod no longer accepts aSiteIdparameter.
OrderValidationService constructor change
The EPiServer.Business.Commerce.Order.OrderValidationService constructor without OrderOptions parameter has been removed. Use the constructor that includes the OrderOptions parameter.
Async order repository APIs
Commerce 15 introduces async versions of all IOrderRepository methods. While the synchronous methods remain available for backward compatibility, new implementations should use the async versions:
CreateAsync<TOrderGroup>(Guid customerId, string name, CancellationToken cancellationToken)LoadAsync(OrderReference orderLink, CancellationToken cancellationToken)LoadAsync<TOrderGroup>(int orderGroupId, CancellationToken cancellationToken)LoadAsync<TOrderGroup>(Guid customerId, string name, CancellationToken cancellationToken)SaveAsync(IOrderGroup order, CancellationToken cancellationToken)SaveAsPaymentPlanAsync(IOrderGroup cart, CancellationToken cancellationToken)SaveAsPurchaseOrderAsync(IOrderGroup cart, CancellationToken cancellationToken)DeleteAsync(OrderReference orderLink, CancellationToken cancellationToken)
The IPurchaseOrderRepository also adds:
LoadAsync(string trackingNumber, CancellationToken cancellationToken)
ReportingOrderEventListener behavior change
ReportingOrderEventListener now executes listeners synchronously and not in a background thread. This is a behavior change that may affect performance characteristics of order save operations in implementations that rely on asynchronous event processing.
Updated 2 months ago
