Installation
Requirements
Magento 2.4.x — tested on 2.4.9, compatible with previous 2.4.* releases. PHP 8.1–8.5. Requires codingrow/module-core (installed automatically as a Composer dependency) for the shared Codingrow admin menu and license validation.
Setup steps
- Add the credentials you'll receive by email to
auth.jsonin your Magento project root:{ "http-basic": { "repo.codingrow.com": { "username": "...", "password": "..." } } } composer config repositories.codingrow composer https://repo.codingrow.comcomposer require codingrow/module-orderexportbin/magento module:enable Codingrow_OrderExportbin/magento setup:upgrade && bin/magento setup:di:compile && bin/magento cache:flush- Paste your license key into Admin → Stores → Configuration → Codingrow → Order Export → License → License Key, save, then
bin/magento cache:flush. - Under the same section's General group, set Enable module to "Yes" — the module ships enabled at the Magento level but functionally off, so it never exports anything until you explicitly turn it on.
- Create your first profile under Codingrow → Order Export → Export Profiles — see Profiles below.
The whole profile admin, mapping builder, log and every notification email are available in 7 languages, auto-selected per admin user locale:
Uninstallation
composer remove codingrow/module-orderexport then
bin/magento setup:upgrade && bin/magento setup:di:compile && bin/magento cache:flush.
Profiles and the export log (codingrow_orderexport_profile,
codingrow_orderexport_log) are never deleted automatically —
use Export profile first if you want to keep a copy
of your profile configuration.
User guide
Profiles
Everything in the module is organized around profiles, listed under Codingrow → Order Export → Export Profiles. Each profile is completely independent: its own name, its own enabled/disabled switch, its own trigger status(es), its own destination (channel + format), its own field mapping and its own row in the export log — you can run any number of profiles side by side (one per supplier, one per carrier, one for an internal ERP), and disabling or deleting one never affects the others.
A profile that is disabled (Profile enabled = "No") never exports anything, whether triggered automatically, from the manual action, or from the CLI command — this is independent from the module-wide Enable module switch under System Config, which acts as a single master off-switch for every profile at once.
Channels & formats
Every profile picks one channel (where the payload is delivered) and one format (how it's serialized) — the two choices are independent, so any format works with any channel.
| Channel | Typical use | Key settings |
|---|---|---|
| REST API | Sends the payload as an HTTP request to a webservice | Destination URL, HTTP method (GET/POST/PUT/PATCH), authentication (None, HTTP Basic, Bearer token), minimum seconds between requests (rate limiting, 1 second by default) |
| FTP / SFTP | Uploads the payload as a file to a remote server | Host, port (21 by default), username, password, remote path, optional FTPS (explicit TLS), passive mode |
| Local file | Writes the payload to a file under this store's
own pub/media/, for an external system to pick up over HTTP |
Subfolder — the file lands under
pub/media/codingrow_orderexport/<subfolder>/ (default subfolder:
"default") |
Formats: JSON, XML or CSV, chosen independently of the channel above — the same field mapping (see below) drives all three, the format only changes how it's serialized.
Field mapping
The Mapping tab is a table of rows, each connecting a target (the field
name in the output — a dot means one level of nesting, e.g. customer.email) to a
source path chosen from a dropdown of every available order/customer/item
field. Empty rows are ignored on save.
Rows are read top to bottom in the same shape as the output itself: an optional Header template first, then the order-level mapping rows, then any Repeat blocks (see below), and an optional Footer template last.
Transformations
Each mapping row can apply one transformation to the source value before it's written to the target field:
| Transform | What it does |
|---|---|
| None | Direct copy of the source path's value (falls back to "Default value" when the source is empty). |
| Static value | Ignores the source entirely, always writes the fixed text in "Value". |
| Strip HTML tags | Removes HTML markup from the source value — useful for a product name or description that carries residual formatting. |
| Text template | Free text with placeholders, e.g.
{order.shipping_address.firstname} {order.shipping_address.lastname}.
A function is also available inside a placeholder:
striphtml{path} (same as the Strip HTML tags transform, usable inline) and
substr{path,N} (drops the first N characters, e.g.
substr{order.some_code,3}). |
| Search and replace | Looks for the "Search" text inside the source value (case-insensitive) and replaces it with "Value" exactly as given. |
| Number | Serializes the value as a real JSON number instead
of a quoted string — use it when the destination validates the field's TYPE strictly
(a quantity sent as the database-raw string "1.0000" gets rejected by
some APIs, while 1.0 as a real number is accepted). This is
not the default for numeric-looking fields on purpose: turning it on
everywhere would silently strip leading zeros from things like a postcode or an article
code, so it's an opt-in choice per row, not an automatic behaviour. |
The same {path} / striphtml{} / substr{} syntax used
in Text template rows is also available in Repeat block rows and in the profile's optional
Header/Footer.
Repeat blocks
A repeat block builds a nested array in the output — the most common case is one entry per order item. Each block has a Block output key (where the array is written in the output) and a source collection (what it repeats over, e.g. the order's items), plus its own set of mapping rows underneath, evaluated once per element with "current" scoped to that element — so a row's source path inside a repeat block refers to fields of the current item, not the order as a whole.
items, source collection
"Order items", and two rows (sku ← current item SKU, qty ←
current item quantity) produces:
{
"items": [
{ "sku": "43241", "qty": 2 }
]
}
A profile can define any number of independent repeat blocks — for example one for the
item list and a separate one for a list of applied discounts.
Supplier item filter
Two General-tab settings decide which order rows are actually exported, on top of whatever a repeat block's own source collection includes:
- Only supplier items — when "Yes" (the default, matching the dropshipping case this module was built for), only order rows whose product has the attribute below populated are exported; when "No", every order row is included.
- Supplier SKU attribute — the product attribute checked by the setting
above, since not every catalog names it the same way (
supplier_skuis only the usual default).
When "Only supplier items" excludes rows from an order, the live preview shows an explicit warning naming how many rows were left out and why — so an empty or shorter-than-expected payload is never a silent surprise.
Live preview
The Preview button on the profile edit page builds a temporary, never-saved profile from whatever is currently in the form — including changes you haven't saved yet — and runs it against a real order you pick, through the exact same code path used for a genuine export. The result is the literal JSON/XML/CSV payload that order would produce, so you can correct the mapping before ever activating the profile, instead of finding out from a failed real export.
Trigger & deduplication
The Trigger status multiselect on the General tab lists which order status(es) start an automatic export for that profile (Ctrl/Cmd-click to select more than one) — checked only on the automatic, event-driven trigger; the manual grid action and the CLI command ignore it on purpose, since triggering by hand is itself the deliberate choice to export regardless of status.
Every successful and failed attempt is written to that profile's log (see below), and the log is also what prevents duplicates: the same order is never exported twice automatically by the same profile, whatever the order does afterwards (further edits, status changes back and forth). If a genuine resend is needed — after fixing a destination-side issue, for example — use Force resend, which explicitly bypasses this protection.
Export log & Force resend
Every profile has its own log tab: ID, order, outcome (Success/Error), what triggered the attempt, HTTP status, error message, date, and an expandable "Details" row showing the exact request payload sent and the response body received — the same information support asks for when troubleshooting a failed export.
A failed row's Force resend button re-runs the export for that exact order through that exact profile right now, ignoring the deduplication protection described above — a confirmation dialog spells this out before it runs, since it's a deliberate override, not the default behaviour.
Failure notification emails
Two General-tab settings control failure notifications, independent of the log (which always records every attempt regardless of these settings): Notification recipients (one or more email addresses, comma-separated — leave empty to send nothing) and Send email for (which events trigger a notification).
The email body includes the actual error returned by the destination, not just a generic
HTTP status line: when the response body is parseable JSON with a message field,
that message is appended verbatim (e.g. "Destination returned HTTP 422 - Minimum product
quantity is 1.0"); otherwise the raw response body is included, truncated to 500 characters —
so the real cause is visible straight from the inbox, without opening the log.
Import / Export profile
The Export profile button on a profile's edit page downloads its entire configuration — general settings, destination, mapping rows and repeat blocks — as a single JSON file, with destination credentials deliberately excluded so the file is safe to store, share with support, or commit alongside a deployment. The Import profile button on the Export Profiles grid re-creates a profile from such a file — the typical use is moving a profile from a staging/demo store to production, or keeping a backup of a mapping you're happy with before experimenting further. Credentials always have to be re-entered by hand after an import, since they were never in the file to begin with.
License
One license per domain, entered under Admin → Stores → Configuration → Codingrow → Order Export → License → License Key. Includes all updates for that domain. Need to move to a different domain (staging → production, or a site migration)? Your first domain change is free and instant from your account page — no waiting, no ticket needed. From the second change onward, a change is allowed once a year. You can also request a refund within 30 days of purchase, on your own, from the same account page.