Skip to main content

Mage2Plenty v3.13 - Order Identity, Sales Channels & Deferred Imports

· 7 min read
Soft Commerce Team
Mage2Plenty Development Team

Mage2Plenty v3.13 is an order-sync correctness release. Every PlentyONE order now keeps a durable external identity - the original marketplace/manual order reference is preserved in its own column, surfaced in the admin grid, and used as an idempotency key that puts an end to duplicate PlentyONE orders on export retries. Sales channels are now told straight end-to-end: channel 0 (manual entry) survives import, grid rendering and the export filter, and Magento-origin orders get stamped with the real referrer once exported. Order import learns to wait: invoices and shipments blocked by a transient Magento state (payment review, on-hold) are deferred and retried instead of being silently lost. Rounding it out: stock-drift detection stops alarming on SKUs you deliberately don't sync, the item-mapping integrity check stops crying wolf, and the admin menu completes the Byte8 rebrand.

Order identity, made durable

When an order is imported, the mirror table's increment_id is overwritten with the Magento increment - which used to destroy the only copy of the original PlentyONE reference (the marketplace order number, a manual-entry reference, or our own increment for exported orders). v3.13 gives that reference a permanent home:

  • New plenty_order_entity.external_order_id column (indexed) captures the PlentyONE externalOrderId at collection time. A re-collect never nulls it, and the admin order listing gains a filterable External ID column.
  • Export stops clobbering PlentyONE's externalOrderId. Our increment id is only stamped onto a PlentyONE order that carries no external reference yet - marketplace and manual references are preserved on the Plenty side, and the identity key used to detect existing orders no longer drifts.
  • increment_id is pinned once linked. Order collect no longer flips a linked row's increment_id back to Plenty's external reference, and the import create path now actually persists increment_id alongside order_id (it previously skipped it for newly-created orders).

No more duplicate PlentyONE orders on retry

An empty or lost response to an order-create call meant PlentyONE had created the order server-side while Magento never captured its plenty_order_id - and the ERROR-status retry then created it again. The export now runs an external-id idempotency search on retries and forced exports: it looks the order up in PlentyONE by external order id (the Magento increment), adopts the existing order, and continues as an update instead of a blind create. Brand-new orders skip the extra lookup, so the happy path costs nothing.

Sales channels, told straight

PlentyONE's referrer 0 is a real channel - Manuelle Eingabe (manual entry) - but PHP's falsy-zero semantics had it collapsing to "no channel" at several points. v3.13 fixes the whole path:

  • Order::getReferrerId() returns a literal 0 for manual entry instead of collapsing it to null; generators that key on a genuinely absent referrer keep working.
  • The export channel filter no longer treats channel 0 as empty: it matches via the allowed list like any other channel, and -2 (PlentyONE-origin orders) is always allowed to sync back. Previously, manual-entry orders were skipped even when 0 was explicitly configured.
  • Order import preserves the literal referrer, including 0, instead of demoting it to the -2 sentinel.
  • Channel flip on export: once a Magento-origin order is created in PlentyONE, the -1 Magento placeholder in sales_order.plenty_sales_channel is replaced with the real exported referrer - preferring the referrer PlentyONE recorded on the created order, falling back to the profile's store mapping. Guarded so PlentyONE-origin orders re-exported for status updates keep their channel.
  • The sales order grid renders channel 0 and gains a hover tooltip describing each channel (origin icons for the placeholders, referrer id + name for real channels).

Order import that waits instead of losing documents

When a PlentyONE order arrives with an invoice or shipment but the Magento order is transiently un-actionable - payment review (common with PSPs like Mollie) or on-hold - the import used to finalise the order as COMPLETE and the document was silently lost. Now it defers:

  • A new DEFERRED status parks the client order instead of erroring or completing it, with retry metadata (attempt count, first/last deferral timestamps) stored in a new metadata column.
  • A per-attempt cooldown avoids hammering blocked orders; DEFERRED orders are re-fetched alongside PENDING when retry on failure is enabled.
  • A 14-day give-up window marks the order as skipped and raises a one-time critical-alert email if the blocker never clears, so nothing lingers unnoticed.

Stock drift: only the SKUs you actually sync

The drift report, hourly auto-fix, weekly email and export reconciler compared Magento vs PlentyONE stock for every SKU - including those the stock sync deliberately skips (Manage Stock = No), producing false positives that could never self-heal. v3.13 introduces a shared IsStockManaged resolver as the single source of truth for that decision, gates the entire drift path on it, and reuses it in the import-side validation. Unmanaged SKUs are no longer alarmed on or enqueued; a new --include-unmanaged flag on plenty:stock:drift:report keeps them reachable for diagnostics.

Integrity check stops crying wolf

The item-mapping integrity check treated plenty_variation_entity.external_id as the authoritative Magento product id - but merchants who don't maintain externalId in PlentyONE (or use it for their own references) carry NULL/0 there, which fired recurring false-positive critical alerts demanding product_id = 0. The check now only compares against a populated external id, so genuine conflicts still surface and empty ones stay quiet.

Byte8 rebrand

The admin menu title and system-configuration tab are now labelled Byte8, completing the Soft Commerce → Byte8 rename in the Magento admin.

Release Summary

ModuleVersionBumpKey Changes
module-core2.5.1 → 2.6.0minorNew DEFERRED status for the order-import deferral flow; Byte8 admin menu/tab rebrand
module-plenty-order2.3.0 → 2.4.0minorexternal_order_id column + External ID grid column; channel tooltip; 0-safe getReferrerId(); metadata column for deferred-retry sync
module-plenty-order-profile2.9.0 → 2.10.0minorDeferred import documents; duplicate-order idempotency search; channel-0/-1/-2 export & import fixes; increment_id pinning
module-plenty-item-profile3.6.0 → 3.6.1patchSkip empty external_id in the mapping integrity check
module-plenty-stock-profile2.6.1 → 2.6.2patchDrift detection & reconciliation gated on Manage Stock

Metapackage: softcommerce/mage2plenty-os 3.12.0 → 3.13.0

Upgrade Guide

composer require softcommerce/mage2plenty-os:^3.13

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

This release ships schema changes: plenty_order_entity gains the external_order_id column (with index) and a metadata column - setup:upgrade is required.

Behaviours worth noting on upgrade:

  • Manual-entry orders start exporting. Channel 0 was previously skipped even when allowed; once 0 is in your allowed-channel list, those orders now sync. Review the list if you relied on the old (buggy) behaviour.
  • Deferral engages with retry-on-failure. With it enabled, transiently blocked orders sit as DEFERRED (up to 14 days) instead of completing without documents; the give-up path emails once, then skips.
  • Drift reports shrink. Unmanaged SKUs disappear from drift output and weekly emails - that's signal, not data loss; use --include-unmanaged to see them.
  • external_order_id backfills gradually as orders are re-collected; it is not retro-populated in one pass.

Resources


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