Order
Changed on:
17 Oct 2023
Overview
The module is responsible for exporting orders to Fluent and receiving updates.
Key Features:
- Triggers customer export when an order is placed.
- Exports new orders to Fluent.
- Opens a webhook to receive Fluent order-related updates. Other extensions like fulfillment and consignment will leverage this webhook.
- Updates order status based on Fluent updates.
- Creates shipments for all order items based on an incoming order status update. Note that this will blindly mark all items as shipped regardless of how they have been consigned at Fluent.
- This is disabled by default in favour of the consignment module that creates shipments based on how items are actually consigned and shipped at Fluent.
Limitations:
- Does not sync old orders created before the extension is installed.
- If the order sync is temporarily disabled, it will not sync orders placed while it has been disabled once it is re-enabled.
Detailed Technical Description
Order Export
Adobe’s Commerce native message queue was used to export orders. Once an is saved the system triggers the `sales_order_save_after event`
, which is being observed by `FluentConnector\Order\Observer\PublishOrderToExportQueue`
. This observer uses the config class `FluentConnector\Order\Model\ConfigProvider`
to determine if export is enabled and if the has a proper status for exporting.

If there is a need to customize when an is considered ready to be sent to Fluent - ConfigProvider class should be rewritten in DI configuration. To validate has not been published before the extension tracks when orders are exported through extension attributes: order.extension_attributes.fluent.publish_status should be empty or equal to 0. When an is ready to be exported then it is added to the message queue with the topic name of fluentcommerce.order.publisher.
Adding to the export queue contains a few steps:
- Observing order after saving event.
- Running order validation - determining if the order can be exported to Fluent.
- Pushing order data to Adobe’s Message Queue.
- Updating order.extension_attributes.fluent.publish_status to 1(PUBLISHED)
The exporting flow :

Exporting logic:
- Read a message from the queue
- Retrieve order entity by order_id(stored in the message)
- Update order.extension_attributes.fluent.publish_status = 2(PROCESSING)
- Create customer
- Check if the customer exists
- Create customer if not present in relevant fluent retailer
- Build create order API request payload
- Send API request
- Authentication
- Sending POST API request itself
- Update order.extension_attributes.fluent.publish_status = 4(COMPLETE)
- Save received fluent_order_id into Adobe order using extension attributes.
Order Status Update
processing happens in 2 stages.
The first stage does the validation of the signature and checks the content has the required parameters. If all goes well, the request is added to the message queue to be processed asynchronously otherwise Adobe will return an error to Fluent to signal that it was unable to accept the request.

The second stage is the actual processing of the message. The message name is key to drive, how the message is going to be processed as these are mapped to internal handlers in Adobe.
`1 <type name="FluentConnector\General\Api\WebHook\HandlerFactoryInterface"> 2 <arguments> 3 <argument name="handlers" xsi:type="array"> 4 <item name="OrderStatusChanged" xsi:type="string">FluentConnector\Order\Handler\OrderStatusUpdateHandler</item> 5 </argument> 6 </arguments> 7 </type>`
Other modules utilize the same approach by adding their own handlers and enabling the processing of different messages that are specific to their modules.
All carry minimal information and required Adobe to fetch extra details from Fluent in to complete processing the message received. The diagram below represents the flow executed for an status update message. It is possible to override certain parts of the code and extend its functionality. For example, fetching more details from Fluent and either saving it in Adobe or using it to drive extra logic. There are some events that can be leveraged to achieve this but if the events aren’t enough Adobe’s Commerce dependency injection is the recommended way.

Order Events
Name | Description | Parameters |
fluent_order_push_before | before the is pushed to Fluent | of type OrderInterface |
fluent_order_push_after | after the is successfully pushed to Fluent | of type OrderInterface |
fluent_order_push_prepare_simple_payload_after | Allows customisation of an line containing a simple product | payload of type array |
fluent_order_push_prepare_configurable_payload_after | Allows customisation of an line containing a configurable product | payload of type array order_item of type OrderItemInterface |
fluent_order_push_prepare_fulfilment_choice_payload_after | Allows customisation of the fulfilment choice properties | fulfilment of type array request_data of type PushOrderDataRequestInterface |
fluent_order_push_prepare_order_payload_after | Allows customisation of level properties | of type OrderInterface payload of type PushOrderDataRequestInterface |
fluent_order_push_query_build_after | Allows customisation of mutation query | query of type string |