Function Description
Pipeline Initializer
The Pipeline Initializer of the Pacemaker Order Update will get all file patterns with the file pattern provider and search for matching files in the import directory.
By default, the import directory is var/pacemaker/import-order-update. This directory is dedicated to the Pacemaker Order Update component and is separate from the Pacemaker Product Import directory (var/pacemaker/import), which is scanned recursively by the product import and must not contain order update files.
If files were found, the corresponding file reader will be applied, which returns all created notification documents.
As soon as all documents were collected, the pipeline initializer removes all files from the import directory and invokes the Dispatcher.
File Pattern Provider
First, each instance (e.g. shipment, invoice, …) has to define a file pattern in the di.xml. This file pattern is used to find the file in the Pacemaker directory.
This declaration consists of the following parts:
-
The pattern instance with a file pattern and the import path for the xml and json format
The file pattern provider will return all declared file patterns.
The following virtual types are declared by default, one pair (JSON and XML) per supported document type. All of them use var/pacemaker/import-order-update as the default import path:
| Module | Virtual Type | Glob Pattern |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Every virtual type can get overridden per project via a custom |
<type name="TechDivision\OrderUpdateFileSystemObserver\Model\FilePatternProvider">
<arguments>
<argument name="configuration" xsi:type="array">
<item name="shipment" xsi:type="array">
<item name="disabled" xsi:type="boolean">false</item>
<item name="pattern_instance" xsi:type="object">TechDivision\OrderUpdateFileSystemObserver\Virtual\ShipmentFilePattern</item>
</item>
<item name="shipmentxml" xsi:type="array">
<item name="disabled" xsi:type="boolean">false</item>
<item name="pattern_instance" xsi:type="object">TechDivision\OrderUpdateFileSystemObserver\Virtual\ShipmentXmlFilePattern</item>
</item>
<item name="invoice" xsi:type="array">
<item name="disabled" xsi:type="boolean">false</item>
<item name="pattern_instance" xsi:type="object">TechDivision\OrderUpdateFileSystemObserver\Virtual\InvoiceFilePattern</item>
</item>
<item name="invoicexml" xsi:type="array">
<item name="disabled" xsi:type="boolean">false</item>
<item name="pattern_instance" xsi:type="object">TechDivision\OrderUpdateFileSystemObserver\Virtual\InvoiceXmlFilePattern</item>
</item>
<item name="cancellation" xsi:type="array">
<item name="disabled" xsi:type="boolean">false</item>
<item name="pattern_instance" xsi:type="object">TechDivision\OrderUpdateFileSystemObserver\Virtual\CancellationFilePattern</item>
</item>
<item name="cancellationxml" xsi:type="array">
<item name="disabled" xsi:type="boolean">false</item>
<item name="pattern_instance" xsi:type="object">TechDivision\OrderUpdateFileSystemObserver\Virtual\CancellationXmlFilePattern</item>
</item>
<item name="creditmemo" xsi:type="array">
<item name="disabled" xsi:type="boolean">false</item>
<item name="pattern_instance" xsi:type="object">TechDivision\OrderUpdateFileSystemObserver\Virtual\CreditmemoFilePattern</item>
</item>
<item name="creditmemoxml" xsi:type="array">
<item name="disabled" xsi:type="boolean">false</item>
<item name="pattern_instance" xsi:type="object">TechDivision\OrderUpdateFileSystemObserver\Virtual\CreditmemoXmlFilePattern</item>
</item>
</argument>
</arguments>
</type>
<virtualType name="TechDivision\OrderUpdateFileSystemObserver\Virtual\ShipmentFilePattern" type="TechDivision\OrderUpdateFileSystemObserver\Model\BaseFilePattern">
<arguments>
<argument name="globPattern" xsi:type="string">shipment*.json</argument>
<argument name="importPath" xsi:type="string">var/pacemaker/import-order-update</argument>
</arguments>
</virtualType>
<virtualType name="TechDivision\OrderUpdateFileSystemObserver\Virtual\ShipmentXmlFilePattern" type="TechDivision\OrderUpdateFileSystemObserver\Model\BaseFilePattern">
<arguments>
<argument name="globPattern" xsi:type="string">shipment*.xml</argument>
<argument name="importPath" xsi:type="string">var/pacemaker/import-order-update</argument>
</arguments>
</virtualType>
<virtualType name="TechDivision\OrderUpdateFileSystemObserver\Virtual\InvoiceFilePattern" type="TechDivision\OrderUpdateFileSystemObserver\Model\BaseFilePattern">
<arguments>
<argument name="globPattern" xsi:type="string">invoice*.json</argument>
<argument name="importPath" xsi:type="string">var/pacemaker/import-order-update</argument>
</arguments>
</virtualType>
<virtualType name="TechDivision\OrderUpdateFileSystemObserver\Virtual\InvoiceXmlFilePattern" type="TechDivision\OrderUpdateFileSystemObserver\Model\BaseFilePattern">
<arguments>
<argument name="globPattern" xsi:type="string">invoice*.xml</argument>
<argument name="importPath" xsi:type="string">var/pacemaker/import-order-update</argument>
</arguments>
</virtualType>
<virtualType name="TechDivision\OrderUpdateFileSystemObserver\Virtual\CancellationFilePattern" type="TechDivision\OrderUpdateFileSystemObserver\Model\BaseFilePattern">
<arguments>
<argument name="globPattern" xsi:type="string">cancellation*.json</argument>
<argument name="importPath" xsi:type="string">var/pacemaker/import-order-update</argument>
</arguments>
</virtualType>
<virtualType name="TechDivision\OrderUpdateFileSystemObserver\Virtual\CancellationXmlFilePattern" type="TechDivision\OrderUpdateFileSystemObserver\Model\BaseFilePattern">
<arguments>
<argument name="globPattern" xsi:type="string">cancellation*.xml</argument>
<argument name="importPath" xsi:type="string">var/pacemaker/import-order-update</argument>
</arguments>
</virtualType>
<virtualType name="TechDivision\OrderUpdateFileSystemObserver\Virtual\CreditmemoFilePattern" type="TechDivision\OrderUpdateFileSystemObserver\Model\BaseFilePattern">
<arguments>
<argument name="globPattern" xsi:type="string">creditmemo*.json</argument>
<argument name="importPath" xsi:type="string">var/pacemaker/import-order-update</argument>
</arguments>
</virtualType>
<virtualType name="TechDivision\OrderUpdateFileSystemObserver\Virtual\CreditmemoXmlFilePattern" type="TechDivision\OrderUpdateFileSystemObserver\Model\BaseFilePattern">
<arguments>
<argument name="globPattern" xsi:type="string">creditmemo*.xml</argument>
<argument name="importPath" xsi:type="string">var/pacemaker/import-order-update</argument>
</arguments>
</virtualType>
File Reader Provider
The file reader provider is another di configuration, which each instance has to declare. This definition is used to read the files for further processing.
Here you can also declare the reader for json and xml files. The Reader gets the content of the file and creates the notification document. Finally, it renames the file with a prefix.
<type name="TechDivision\OrderUpdateFileSystemObserver\Model\FileReaderProvider">
<arguments>
<argument name="configuration" xsi:type="array">
<item name="shipment" xsi:type="array">
<item name="disabled" xsi:type="boolean">false</item>
<item name="pattern_key" xsi:type="string">shipment</item>
<item name="reader_instance" xsi:type="object">TechDivision\OrderUpdateFileSystemObserverShipment\Model\ShipmentFileReader</item>
</item>
<item name="shipmentxml" xsi:type="array">
<item name="disabled" xsi:type="boolean">false</item>
<item name="pattern_key" xsi:type="string">shipmentxml</item>
<item name="reader_instance" xsi:type="object">TechDivision\OrderUpdateFileSystemObserverShipment\Virtual\ShipmentXmlFileReader</item>
</item>
</argument>
</arguments>
</type>
<type name="TechDivision\OrderUpdateFileSystemObserverShipment\Model\ShipmentFileReader">
<arguments>
<argument name="serializer" xsi:type="object">Magento\Framework\Serialize\Serializer\Json</argument>
</arguments>
</type>
<virtualType name="TechDivision\OrderUpdateFileSystemObserverShipment\Virtual\ShipmentXmlFileReader" type="TechDivision\OrderUpdateFileSystemObserverShipment\Model\ShipmentFileReader">
<arguments>
<argument name="shipmentResolver" xsi:type="object">TechDivision\OrderUpdateFileSystemObserverShipment\Model\Resolver\Virtual\ShipmentResolverChain</argument>
<argument name="serializer" xsi:type="object">TechDivision\OrderUpdateNotificationDispatcherApi\Model\Serializer\XmlSerialize</argument>
</arguments>
</virtualType>
Notification Dispatcher
This dispatcher receives all notification documents and filters and groups the given documents by order. After that, a pipeline will be spawned for each notification and the entry will be saved to the pacemaker_order_update_notification table.
The first step of the pipeline is received by the corresponding notification handler from each instance (e.g. shipment, invoice …). This is another Chain, which determines which step has to be initialized.
<type name="TechDivision\OrderUpdateNotificationDispatcherApi\Api\NotificationHandlerInterface">
<arguments>
<argument name="handlers" xsi:type="array">
<item name="order.update.invoice" xsi:type="object">TechDivision\OrderUpdateInvoice\Model\InvoiceHandler</item>
</argument>
</arguments>
</type>
In the end, the move files step will be added to the pipeline.
Rest Api
The module Pacemaker Order Update Api (TechDivision_PacemakerOrderUpdateApi) provides a REST endpoint that allows external systems such as ERP or WMS to deliver order update files directly into Magento over HTTP.
The API acts as a "Dumb Pipe": it accepts a filename and a Base64-encoded payload, validates the filename for security, decodes the payload, and writes the raw file to var/pacemaker/import-order-update/.
No business logic is executed during the API call itself — all further processing is handled asynchronously by the Pacemaker pipeline.
|
The target directory is controlled by the |
Endpoint
| Property | Value |
|---|---|
Method |
|
URL |
|
Content-Type |
|
ACL Resource |
|
Authentication & ACL
The endpoint requires a valid Magento Integration Token passed as a Bearer token in the Authorization header.
In addition, the integration must be granted the ACL resource Magento_Backend::pacemaker_order_update_api.
- The following steps are required to authorize an external system:
-
-
In the Magento Backend, navigate to
-
Create or edit an integration and assign the permission Pacemaker Order Update Api under Pacemaker - Enterprise Integration Platform > Order Update
-
Copy the generated access token and use it as a Bearer token in all API requests
-
|
Without the ACL permission, the API returns HTTP 403 Forbidden even if the token itself is valid. |
Request Format
The request body is a JSON object with a source wrapper containing two required fields.
The file content must be Base64-encoded before being sent.
| Field | Type | Required | Description |
|---|---|---|---|
|
|
Yes |
The name of the file to be stored. Must end with |
|
|
Yes |
The Base64-encoded content of the order update file. Strict Base64 validation is applied — invalid characters cause an immediate error. |
{
"source": {
"filename": "order-update-000000123.json",
"data": "ewoia2V5b25lIjogImtleW9uZSIsCiJrZXl0d28iOiAia2V5dHdvIgp9"
}
}
Filename Validation Rules
The API enforces strict security checks on the submitted filename to prevent injection attacks and directory traversal. All checks are applied in the listed order. The first failing check aborts the request with HTTP 400 Bad Request.
| Rule | Description |
|---|---|
Not empty |
The filename must not be an empty string. |
No null bytes |
The filename must not contain null byte characters ( |
No path traversal |
The filename must not contain |
No path separators |
The filename must not contain |
Allowed characters only |
Only alphanumeric characters, hyphens ( |
Max length 255 |
The filename must not exceed 255 characters. |
Allowed extension |
The filename must end with |
|
Filenames that do not pass all security checks are rejected immediately.
Examples of rejected filenames: |
Response Format
On success, the API returns HTTP 200 OK with a JSON array containing a confirmation message and the absolute path of the saved file. On failure, the API returns the corresponding HTTP error code with a descriptive error message.
| Index | Type | Description |
|---|---|---|
|
|
Confirmation message: |
|
|
Absolute filesystem path to the saved file. |
[
"Successfully saved import data",
"/var/www/html/var/pacemaker/import-order-update/order-update-000000123.json"
]
{
"message": "Invalid filename: only alphanumeric characters, dash, underscore and dot are allowed."
}
File Persistence
Accepted files are written to the Pacemaker order update import directory on the Magento server.
The target path is var/pacemaker/import-order-update/{filename}.
- The following applies to file storage:
-
-
The directory
var/pacemaker/import-order-update/is created automatically if it does not yet exist -
The Base64 payload is decoded in strict mode — the raw binary result is written verbatim to disk without any transformation
-
Magento’s internal
Filesystemabstraction is used for all write operations
-
|
Duplicate filenames are rejected. If a file with the same name already exists in |
|
After the file is persisted, no further action is taken by this API.
The Pipeline Initializer picks up files from |
Error Handling
| HTTP Status | Condition | Error Message |
|---|---|---|
|
Success |
— (see response format above) |
|
Filename is empty |
|
|
Null byte in filename |
|
|
Path traversal in filename ( |
|
|
Path separator in filename ( |
|
|
Disallowed characters in filename |
|
|
Filename exceeds 255 characters |
|
|
File extension missing |
|
|
File extension not |
|
|
Base64 decoding fails or produces empty output |
|
|
File with the same name already exists |
|
|
Missing or invalid Bearer token |
Magento standard authentication error |
|
Valid token but ACL permission not granted |
Magento standard ACL error |