Skip to content

Surcharges not shown in checkout: instanceof MollieSurchargeAwareInterface fails for entity proxies #55

@powli

Description

@powli

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:

  1. CheckoutEntityListener::setSurcharge() — skips surcharge calculation because $checkout instanceof MollieSurchargeAwareInterface returns false
  2. MollieSurchargeProvider::isSupported() — reports entity as unsupported
  3. 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

  1. Use OroCommerce 5.1+ with entity extensions enabled
  2. Configure a Mollie payment method with a surcharge
  3. Go to checkout and select the Mollie payment method
  4. 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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions