Search code examples
shopwareshopware6

Changing product price in Shopware 6 dynamically


I would like to change the price of a product based on the customer's selection. For example, I'm trying to build a small PDP widget to make customers able to choose the number of candles on a cake or write text on cakes and update the price accordingly. The docs only cover how to change the price by overwriting the cart's collector/processor but I don't want to use this method because of other plugins potentially overwriting the same service. So, is there are any other methods of changing the price of the products by subscribing to an event?


Solution

  • There are a few things you will need to consider in this one. Firstly, you will need to save the user input data somewhere (amount of candles, text). Possibly a separate database table that has a OneToMany relationship on cart line items. See this article. Und ya, this is also the part where you will hook into the onLineItemAdd event & save your user input to that table. You may as well also subscribe to the onLineItemUpdate for the same saving logic. You could do the same when removing the item from the cart, although that may not be necessary if you use database's "CASCADE on delete" when implementing your DB table. Meaning once the line item gets removed by the customer (deleted in the DB), your database entry gets deleted as well.

    Afterwards, you can then use the extensions or otherwise called associations to pull this data on the cart page & the order pages. You can be a little more fancy here, if you look at all the frontend router calls, you will notice that Shopware sometimes passes "Criteria" class you can hook into.

        public static function getSubscribedEvents(): array
        {
            return [
                OrderRouteRequestEvent::class => 'alterCriteria',
                DocumentOrderCriteriaEvent::class => 'alterCriteria',
            ];
        }
    
        public function alterCriteria(Event $event): void
        {
            if (method_exists($event, 'getCriteria')) {
                $event->getCriteria()->addAssociation('lineItems.myExtension'); // check syntax, could be lineItem.
            }
        }
    

    Now you can extend the twig templates to show your candles or text in the order page, cart page, document (invoice) pages.

    Secondly, you will have to handle the price. This part will be easier now that you have data saved & being automatically pulled via criteria subscribers. If it's not possible to hook into those events all the time, you will still have an option to manually load your data.

    I do not recommend modifying the price itself, but maybe you could look into adding a surcharge instead. Maybe this article will be helpful to understand the price flow. You could also see if there are any other plugins out there that implement surcharge logic to see it in action.