Skip to main content

Mage2Plenty v3.9 - Payment-Safe Order Export & Storage-Location Stock Cleanup

· 5 min read
Soft Commerce Team
Mage2Plenty Development Team

Mage2Plenty v3.9 makes the Magento → PlentyONE order export wait for asynchronous payments to settle before syncing, gives the order import control over Magento's new-order emails, and adds a CLI to clean up stock that gets double-counted across PlentyONE storage locations.

Order Export

Defer export until the payment has settled

Asynchronous gateways such as Mollie and Klarna finalise payment after the order is placed — the order exists in Magento for a few seconds before its payment is confirmed. Exporting immediately could push an order to PlentyONE that turns out never to be paid, creating an unpaid order in the ERP that has to be cleaned up by hand.

v3.9 adds an IsOrderSettled processor guard that holds any not-yet-exported order until a configurable settling period (measured against the order's created_at age) has elapsed. The guard:

  • defers the order (retries it on the next run) rather than skipping it, so nothing is lost;
  • bypasses forced exports and orders that have already been exported;
  • is controlled by a new "Export Settling Period" field on the export profile's schedule fieldset, via getExportSettlingPeriod() on the schedule config — default 60 seconds, set to 0 to disable.

Settling-period guard now actually engages

The settling-period feature shipped with a wiring bug worth calling out: OrderExportService was injecting the base ProfileSchedule schedule-config factory, so scheduleConfig() returned a base ScheduleConfig that has no getExportSettlingPeriod() and fails the extended-interface instanceof check. That made IsOrderSettled (and IsRetryEligible) bail out silently and never apply.

v3.9 injects the order-profile ScheduleConfigInterfaceFactory — consistent with the sibling orderConfig / apiConfig factories — so scheduleConfig() returns the extended config and the guard engages as intended.

Order Import

Optional gate for Magento's new-order email

When PlentyONE orders are mirrored into Magento, Magento would also fire its native new-order and invoice confirmation emails to the customer — duplicating communication for an order that originated and was confirmed in PlentyONE.

A new "Send New Order Email" toggle on the order-import action config (read through OrderConfig::isActiveOrderTransactionalEmail()) puts that under your control. When the toggle is off, the import processor stamps the quote with a suppression flag, and a new DisableNewOrderEmail observer on sales_model_service_quote_submit_before clears the CanSendNewEmailFlag — suppressing both the new-order and invoice confirmation emails for imported orders in one place.

Stock

plenty:stock:location:correct — drain orphaned storage-location stock

The stock export pushes corrections without a storageLocationId, so PlentyONE applies them to the warehouse's default location (id 0). If a warehouse also holds the same variation in a second, "Custom" storage location, PlentyONE sums both locations at warehouse level — so a Magento quantity of 7 can surface in PlentyONE as 14. Because PlentyONE will not let you delete a storage location that still holds stock, the orphaned location has to be zeroed instead.

v3.9 adds a dedicated maintenance command for exactly that. It sweeps the stock export queue, resolves each Magento product to its PlentyONE variation via catalog_product_entity.plenty_variation_id (the entity_id mapping — not SKU, which is not the source of truth when products are mapped on custom attributes), and sends an absolute stock correction with an explicit storageLocationId to set that location's quantity (default 0).

# Preview only — resolve and print the payload, send nothing
bin/magento plenty:stock:location:correct -w 1 -l 13 --dry-run

# Drain storage location 13 in warehouse 1 across the whole queue
bin/magento plenty:stock:location:correct -w 1 -l 13

Key options: -w/--warehouse-id, -l/--storage-location-id, --quantity (default 0), -r/--reason-id (default 301), -i/--variation-id (a comma-separated test slice that bypasses the queue), -b/--batch-size, --dry-run, and -f/--force. Corrections are sent in batches with a live progress bar and a buffered batch-error summary, so a large catalogue shows visible progress instead of appearing to hang.

This is an operational remediation tool, run on demand — variations that never had stock in the targeted location simply receive a harmless 0 → 0 no-op. Always start with --dry-run and a single-variation test slice, verify the warehouse total drops as expected, then run the full sweep.

Release Summary

ModuleVersionBumpKey Changes
module-plenty-order-profile2.6.0 → 2.7.0minorDefer export until payment settling period elapses; fix schedule-config factory so the guard engages; configurable new-order email gate for imports
module-plenty-stock-profile2.4.0 → 2.5.0minorNew plenty:stock:location:correct CLI to zero stock at a specific PlentyONE storage location

Metapackage: softcommerce/mage2plenty-os 3.8.0 → 3.9.0

Upgrade Guide

composer require softcommerce/mage2plenty-os:^3.9

bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento cache:flush

Two default-on-upgrade behaviours are worth noting:

  • Order export now waits 60 seconds after order creation before exporting (the default settling period). Set Export Settling Period to 0 on the export profile schedule to restore immediate export.
  • The new-order email gate defaults to off, so imported PlentyONE orders no longer trigger Magento's native new-order email unless you enable Send New Order Email on the import action config.

No schema changes ship in this release; all changes apply after compile and cache flush.

Resources


Questions about the upgrade? Reach out to us at support@byte8.io.