Shopware 6: Choosing Between Flow Builder and a Custom Checkout Processor
Flow Builder suits marketing notifications after checkout, but ERP syncs need retries and queues. A practical guide to choosing between Shopware 6 Flow Builder and a custom order-placed processor.
30 Dec 2025, 21:46 UTC

The problem: post-order logic scattered across the codebase
When an order is placed, you need to notify Slack, tag the customer, and push the order to an ERP. It is tempting to stuff all of that into one event subscriber or controller. Six months later, marketing wants to change the Slack threshold, finance wants a different ERP endpoint, and every change requires a code review, deploy, and release. Shopware’s Flow Builder offers a no-code alternative, but it is not a replacement for every post-order task.
Thesis: use Flow Builder for marketing reactions, custom processors for system integrations
Flow Builder lets non-developers configure reactions to events such as “Checkout / Order / Placed” using conditions and actions through the Administration UI. A custom checkout processor (or event listener) is better when you need retries, error handling, transactional guarantees, or calls to external APIs that can fail. The decision comes down to who owns the logic and what happens when the external system is slow.
What Flow Builder handles well
Flow Builder is built around triggers, conditions, and actions. A typical setup uses the trigger “Checkout / Order / Placed”, a condition such as “Rule matches: High Value Order”, and an action such as “Send mail” or “Tag order”. Because conditions reuse Rule Builder, the same rule used for promotions can gate a flow. Changes take effect immediately without a deploy.
Good fit:
- Slack or email notifications based on order totals
- Tagging customers or orders with custom fields
- Simple post-checkout promotions
Where a custom processor is safer
Flow Builder actions run as part of the request flow. If an action calls an external ERP and that system is slow or down, there is no built-in retry queue or dead-letter handling in the core flow runner. For system-to-system integration, use a custom processor that pushes the order to Symfony Messenger (or a similar queue) and acknowledges the order immediately.
Worked example: Flow Builder for a high-value order alert
Assume you want to notify a channel when an order exceeds 1,000 EUR.
- In Administration, go to Settings → Flow Builder and create a new flow.
- Set the trigger to “Checkout / Order / Placed”.
- Add a condition “Rule matches” and select or create a rule: “Cart total > 1000 EUR”.
- Add the action “Send mail” (or a Slack action if your installed extensions provide one).
- Save and activate the flow.
To verify, place a test order above the threshold in the storefront and confirm the notification arrives. Place a second order below the threshold and confirm nothing fires. Because Flow Builder changes are live immediately, test in a staging environment first.
Worked example: custom processor for ERP sync
For ERP synchronization, create an event listener for the order-placed event in your Shopware 6 version. Instead of calling the ERP directly, dispatch a message to a queue:
// src/MessageHandler/ErpOrderSyncSubscriber.php
namespace App\MessageHandler;
use Shopware\Core\Checkout\Order\Order\OrderPlacedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Messenger\MessageBusInterface;
class ErpOrderSyncSubscriber implements EventSubscriberInterface
{
private MessageBusInterface $bus;
public function __construct(MessageBusInterface $bus)
{
$this->bus = $bus;
}
public static function getSubscribedEvents(): array
{
return [
OrderPlacedEvent::class => 'onOrderPlaced',
];
}
public function onOrderPlaced(OrderPlacedEvent $event): void
{
$order = $event->getOrder();
$this->bus->dispatch(new SyncOrderToErpMessage($order->getId()));
}
}
Run bin/console cache:clear from the project root after registering the subscriber in services.xml or config/services.yaml. You need shell access to the application container; clearing cache in production temporarily increases load, so do it during a low-traffic window.
App\MessageHandler\ErpOrderSyncSubscriber:
tags:
- { name: kernel.event_subscriber }
The ERP sync now happens asynchronously. If the ERP is unreachable, the message can retry according to your transport configuration instead of delaying the checkout response. Class names may differ between minor versions; check your installed src/Core directory for the exact event class.
Trade-off: observability and rollout risk
Flow Builder has no versioning or staging in the Administration UI. A change is live as soon as you save it, so a misconfigured condition can affect real orders immediately. Custom code goes through your normal CI/CD pipeline, but it requires a deploy for every threshold change.
Practical check: after enabling a flow, open Administration → Flow Builder → Flow listing and confirm the flow state is “active”. For a custom subscriber, check var/log/dev.log (or your configured Monolog channel) after a test order to confirm the message was dispatched.
Limitation: no guaranteed evaluation order
When multiple flows or rules apply to the same order, execution order is not guaranteed by rule ID. Use priority fields where available, or consolidate dependent logic into a single processor rather than chaining several flows.
Actionable next step
List every action that runs after an order is placed. If marketing owns the condition and the action is a notification, build it in Flow Builder. If the action writes to another system and must survive outages, move it to a custom subscriber with a queue. Start with one high-value order alert in Flow Builder this week, then migrate one ERP sync call to the queue next sprint.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.