Problem
OroCommerce 5.1 overhauled the entity extension system ("Migration of Extended Entities"). Before 5.1, extended entities used a three-layer class hierarchy with generated intermediate proxy classes:
Entity → ExtendModel → Generated Proxy (Extend\Entity\EX_...)
The EntityGenerator would run registered AbstractEntityGeneratorExtension implementations during cache warmup. Mollie's MollieSurchargeAwareEntityGeneratorExtension used this to inject MollieSurchargeAwareInterface into the generated proxy class for entities with a mollie_surcharge_amount field.
In 5.1+, EntityGenerator::buildPhpClass() skips proxy class generation for all standard entities — it only generates proxies for enums and custom entities in the Extend\Entity namespace. Standard entities now use ExtendEntityInterface + ExtendEntityTrait for dynamic field access via magic methods.
This means MollieSurchargeAwareEntityGeneratorExtension never runs for Checkout or Order, and the interface is never added to their class hierarchy. All instanceof MollieSurchargeAwareInterface checks return false.
Affected locations
The plugin uses instanceof MollieSurchargeAwareInterface in three places:
CheckoutEntityListener::setSurcharge() — skips surcharge calculation because $checkout instanceof MollieSurchargeAwareInterface returns false
MollieSurchargeProvider::isSupported() — reports entity as unsupported
OrderMapperDecorator::map() — surcharge amount not copied from checkout to order
Since all three checks fail, surcharges are never calculated, never shown in the checkout subtotals, and never mapped to the order.
Reproduction
- Use OroCommerce 5.1+ with entity extensions enabled
- Configure a Mollie payment method with a surcharge
- Go to checkout and select the Mollie payment method
- Observe that the surcharge amount does not appear in the order totals
Suggested Fix
Replace instanceof MollieSurchargeAwareInterface with checks against the concrete classes, which is the standard OroCommerce 5.1+ pattern for extended entity capability checking:
CheckoutEntityListener::setSurcharge()
// Before
if (!$checkout instanceof MollieSurchargeAwareInterface) {
// After
if (!$checkout instanceof Checkout) {
MollieSurchargeProvider::isSupported()
// Before
return $entity instanceof MollieSurchargeAwareInterface;
// After
return $entity instanceof \Oro\Bundle\CheckoutBundle\Entity\Checkout
|| $entity instanceof \Oro\Bundle\OrderBundle\Entity\Order;
OrderMapperDecorator::map()
// Before
if ($checkout instanceof MollieSurchargeAwareInterface) {
// After
if ($checkout instanceof \Oro\Bundle\CheckoutBundle\Entity\Checkout
&& $order instanceof \Oro\Bundle\OrderBundle\Entity\Order) {
Background
Per the OroPlatform 5.1 CHANGELOG, the recommended migration path is:
- Replace
instanceof interface checks with concrete class checks
- Replace
AbstractEntityGeneratorExtension with EntityFieldExtensionInterface for runtime behavior
- Use
EntityPropertyInfo::propertyExists() / methodExists() for capability checking
Environment
- Affected versions: mollie/orocommerce 5.x (from 5.1+) and 6.x
- Not affected: mollie/orocommerce on OroCommerce 5.0 and earlier (proxy generation still active)
Problem
OroCommerce 5.1 overhauled the entity extension system ("Migration of Extended Entities"). Before 5.1, extended entities used a three-layer class hierarchy with generated intermediate proxy classes:
The
EntityGeneratorwould run registeredAbstractEntityGeneratorExtensionimplementations during cache warmup. Mollie'sMollieSurchargeAwareEntityGeneratorExtensionused this to injectMollieSurchargeAwareInterfaceinto the generated proxy class for entities with amollie_surcharge_amountfield.In 5.1+,
EntityGenerator::buildPhpClass()skips proxy class generation for all standard entities — it only generates proxies for enums and custom entities in theExtend\Entitynamespace. Standard entities now useExtendEntityInterface+ExtendEntityTraitfor dynamic field access via magic methods.This means
MollieSurchargeAwareEntityGeneratorExtensionnever runs forCheckoutorOrder, and the interface is never added to their class hierarchy. Allinstanceof MollieSurchargeAwareInterfacechecks returnfalse.Affected locations
The plugin uses
instanceof MollieSurchargeAwareInterfacein three places:CheckoutEntityListener::setSurcharge()— skips surcharge calculation because$checkout instanceof MollieSurchargeAwareInterfacereturnsfalseMollieSurchargeProvider::isSupported()— reports entity as unsupportedOrderMapperDecorator::map()— surcharge amount not copied from checkout to orderSince all three checks fail, surcharges are never calculated, never shown in the checkout subtotals, and never mapped to the order.
Reproduction
Suggested Fix
Replace
instanceof MollieSurchargeAwareInterfacewith checks against the concrete classes, which is the standard OroCommerce 5.1+ pattern for extended entity capability checking:CheckoutEntityListener::setSurcharge()MollieSurchargeProvider::isSupported()OrderMapperDecorator::map()Background
Per the OroPlatform 5.1 CHANGELOG, the recommended migration path is:
instanceofinterface checks with concrete class checksAbstractEntityGeneratorExtensionwithEntityFieldExtensionInterfacefor runtime behaviorEntityPropertyInfo::propertyExists()/methodExists()for capability checkingEnvironment