Extension Point Framework Release Notes
Learn about Extension Point Framework releases.
1.4.0.2f2184880d
Released: August 2025
New in this release
Promotions Calculator extension point
A new extension point has been added can be used to externalize promotion calculations.
For more information, see Promotions Calculator extension point.
Notification Events extension point
A new extension point has been added that notifies an extension when notification events occur.
For more information, see Notification Events extension point.
Product Events extension point
A new extension point has been added that notifies an extension when products are created or updated.
For more information, see Product Events extension point.
Added new methods to XPF entity classes
Some new methods have been added to XPF entity classes to provide access to additional information:
String XPFStore#getUrl(): Provides access to the configured URL for the store.String XPFModifierGroup#getCode(): Provides access to the code of the modifier group.boolean XPFAttribute#isMultiValue(): Identifies if the attribute values for this attribute support multiple values.List<String> XPFAttributeValue#getStringMultiValues(): Provides access to multi-value string attribute values.Set<XPFAttribute> XPFProductType#getAttributes(): Provides access to the attributes for the product type.String XPFCustomer#getFirstName()andString XPFCustomer#getLastName(): These methods provide access to the first and last name of the customer. These convenience methods prevent extensions from needing to usegetAttributeValueByKey("CP_FIRST_NAME").map(XPFAttributeValue::getStringValue).orElse(null)andgetAttributeValueByKey("CP_LAST_NAME").map(XPFAttributeValue::getStringValue).orElse(null), respectively.XPFContainerPricing XPFShoppingCart#getPricing(): Returns the price calculator for the shopping cart.XPFLinePricing XPFShoppingItem#getPricing(): Returns the price calculator for the shopping cart line item.XPFContainerPricing XPFOrder#getPricing(): Returns the price calculator for the order.XPFContainerPricing XPFOrderShipment#getPricing(): Returns the price calculator for the order shipment.XPFLinePricing XPFOrderItem#getPricing(): Returns the price calculator for the order line item.XPFLinePricing XPFOrderItem#isInventoryAllocated(): Identifies if inventory has been allocated for the order line item.boolean XPFOrderReturn#isPhysicalReturn(): Identifies if the order return requires the customer to physically return the product(s).boolean XPFOrderShipment#isTaxInclusive(): Identifies if the order shipment uses inclusive taxes.XPFOrder XPFOrderHoldStrategyContext#getOrder(): Provides access to the order for the order hold strategy context. TheXPFOrderHoldStrategyContext#getPayments()method has also been deprecated since payments can be accessed throughgetOrder().getPayments().
Added Price Calculators support
Previously, these XPF entity classes contained special fields for accessing pricing information:
XPFOrderXPFOrderItemXPFOrderShipmentXPFShoppingCart(viaXPFShoppingCartPricing)XPFShoppingItem(viaXPFShoppingItemPricing)
These fields had multiple issues:
- The method naming was inconsistent between these classes.
- The method names were ambiguous. For example, the word “subtotal” sometimes represented a value with discounts but not taxes, or a value with discounts and shipping but not taxes, or a value without discounts or shipping. Additionally, the word “discount” doesn’t make it clear if we’re talking about a difference between the list and sale price, catalog promotion discounts, line item promotion discounts, or cart/order-level promotion discounts.
- Many pricing combinations could not be supported by the existing fields. For example,
XPFOrderItemhad no field for total, so this had to be calculated by consumers.
To address this, we've created three pricing calculator classes that can be used to calculate prices on various XPF entity classes:
XPFItemPricing: Returns pricing information for a product or product SKU.XPFLinePricing: Returns pricing information for a shopping cart line item or order line item.XPFContainerPricing: Returns pricing information for an order, order shipment, or shopping cart.
These pricing calculator classes use a builder pattern that allows developers to access complex price combinations such as:
- Subtotal before any discounts, shipping, or taxes
- Subtotal with discounts only
- The final total
- Any other combination of the values above
For more information, see Price Calculators.
Added convenience method for retrieving non-localized attribute values on XPF entities
XPF entities with attribute values contain this method:
Optional<XPFAttributeValue> getAttributeValueByKey(final String key, final Locale locale)
However, if retrieving non-localized attribute values, developers had to call it like this:
getAttributeValueByKey("CP_LAST_NAME", Locale.ROOT);
This wasn't obvious and could be confusing. To address this, we've added a new method to all XPF entities with attribute values:
Optional<XPFAttributeValue> getAttributeValueByKey(final String key)
This method returns the non-localized attribute value (if applicable) for the specified key. This method was added to the following XPF entities:
XPFCategoryXPFCustomerXPFProductXPFProductSku
Tax Calculator extensions no longer need to mutate XPFTaxableShoppingItem
Previously, Tax Calculator extensions implementing the calculate method needed to iterate across the context.getTaxableItems() list and call the setPriceBeforeDiscount method to set it to taxableItem.getPriceBeforeDiscount - taxAmount. This was problematic because it was easy to miss, and extensions shouldn't need to mutate XPF entity objects that are provided to them through the context object.
Tax Calculator extensions are no longer expected to set this value. The setPriceBeforeDiscount method has been deprecated and any value passed to it is now ignored.
Similarly, the setGuid method has been deprecated and any value passed to it will also be ignored.
Removed dependency on javax.servlet-api
Some changes have been made to the XPFHttpTagSetContext class used by the HTTP Request Tag Set Populator extension point to remove the dependency on javax.servlet-api. In most cases, these changes should be backwards compatible, but there are some edge cases where the changes may cause an issue.
The getHttpRequest() method still returns a javax.servlet.http.HttpServletRequest object, but it now returns a data transfer object implementation that is provided by the new ep-xpf-legacy-servlet dependency. The methods on this class should be backwards compatible with the original class, but a few are no longer provided, such as ServletInputStream getInputStream(). This method is also now deprecated.
This method exists to provide backwards compatibility, but wherever possible, developers should adjust their implementation to use the new XPFHttpServletRequest getHttpServletRequest() instead. Using this new method is more performant, and will be supported going forward.
Additional fixes
- Fixed issue where attributes with keys that match the regular expression for having a language tag are incorrectly treated as localized attributes when passed to XPF entities.
- Updated
getDisplayNamesmethod to lazy loaded in all XPF entities to address a potential performance issue when stores have a large number of locales enabled. - Added
XPFShipmentTypeEnumvalueSERVICEand deprecatedSERVICE_ORDINAL. - Fixed issue with event-based extension points not supporting multiple extensions on the same extension point.
- Modified
extensions.jsonrequirements so that just the identifier and enabled flag can be specified; all other fields are now optional.