View Issue Details

IDProjectCategoryView StatusLast Update
0007899OXID eShop (all versions)1.03. Basket, checkout processpublic2026-02-23 13:10
ReportereWorks GmbH Assigned To 
PrioritynormalSeveritymajorReproducibilityalways
Status newResolutionopen 
Product Version7.4.0 
Summary0007899: Multiple calls of Delivery->isForBasket() multiply shipping costs
DescriptionShipping cost rules with their calculation rules set to "For each product" result in their shipping costs multiplied everytime something calls their isForBasket() method because the Delivery->updateItemCount() is called inside. This method increases the Delivery->_iItemCnt parameter which is used in Delivery->getMultiplier() which itself is used in Delivery->getCostSum() to calculate its price.
Steps To Reproduce1. Create a shipping cost rule with its calculation rule set to "For each product" and a price > 0
2. Assign at least one article which can be bought
3. Assign the shipping cost rule to a shipping method which can be used
4. Tricky bit: Simulate multiple calls to isForBasket() by either ...
4.a) using the Paypal Checkout module which calls it inside its isVaultingAllowedForPayment() method via a call to getDeliverySetData()->hasDeliveries()->isForBasket()
4.b) or adding a few isForBasket() calls inside of DeliveryList->getDeliveryList() just above the "if ($oDelivery->isForBasket($oBasket)) {" condition
5. Put the in 2. added article in your basket and go through the order process up to step 4
6. The delivery costs are now multipled by x2 if you followed 4.a) or how many isForBasket() calls you added in 4.b)
Additional InformationWe fixed the bug for ourself by adding a memoization to the isForBasket() method via a module which looks like this. This fixed the issue. We're still probing for any related side effects but havn't noticed any yet.

----------

class Delivery extends Delivery_parent {

    private array $_aIsForBasketCache = [];

    /**
     * Fix OXID bug for deliveries calculated for each single article which results in its multiplier increased with
     * every call by remembering the first result
     */
    public function isForBasket($oBasket) {
        $sHash = md5(json_encode($oBasket->getContents()));

        if (in_array($sHash, $this->_aIsForBasketCache)) {
            return $this->_aIsForBasketCache[$sHash];
        }

        return $this->_aIsForBasketCache[$sHash] = parent::isForBasket($oBasket);
    }
}
TagsNo tags attached.
Attached Files
2026-02-23 Order overview.png (75,602 bytes)   
2026-02-23 Order overview.png (75,602 bytes)   
ThemeNot defined
BrowserNot defined
PHP VersionNot defined
Database VersionNot defined

Activities