YS FluentCart Order Statuses
FluentCart × Custom order flow: Custom statuses such as sub-production and scheduled shipment are not overwritten after payment. Status changes are automatically sent by email; you can directly change the order status from More Action, including a process report and anti-blocking feature.
FluentCart’s built-in order statuses only include “Processing”, “Reserved”, “Completed”, and “Cancelled”; however, stores that offer drop shipping, custom production, or pre-order services need their own process, such as “Paid → In Production → Scheduled for Shipping → Shipped”. This add-on allows you to add your own custom order statuses and shipping statuses in the backend—names, colors, descriptions, and payment conditions can be set—the FluentCart order list (each custom status has a saved view), the “Change Shipping Status” dialog box (English interface is Change Shipping Status), and the customer’s order page all display directly. Advanced filtering in FluentCart Pro also includes custom order status filtering. It is completely independent of the FluentCart core and is achieved through public filters and REST.
Will not be overwritten by FluentCart after payment
FluentCart will change the order status to "Processing" when payment is received. This is the core feature, without any filters. The add-on will rewrite your custom status within the same payment flow and leave a note in the order activity log; each status can be selected in "Advanced" to "Keep this status" or "Pass to FluentCart for processing" (only "Unpaid orders" status is always passed to FluentCart). There is also a global toggle. Revenue reports are based on payment status, so custom order statuses have no impact on revenue figures.
Automatically send an email to the customer upon status change
Each custom status can trigger email notifications—one for the customer, one for the administrator—with separate switches. The notifications are directly registered in FluentCart’s “Email Notifications” settings page: using FluentCart’s switches, the subject field, preview function, and sender settings, the email box and header and footer are consistent with those in FluentCart itself; the title and body paragraphs can be filled directly in the same editor page, supported by {{order.invoice_no}},{{order.customer.full_name}} and other FluentCart shortcodes. All are disabled by default; they are only sent when enabled.
Change the order status from More Action
FluentCart’s backend does not have any controls for freely selecting order statuses—whether the order is paid or not; in More Action, there are only fixed buttons like “Marked as Completed,” “Processing Return,” and “Cancel Order” (tested with 1.6.0 and 1.6.3). Adding “Change Order Status” to the top of the same More Action menu opens the “Update Order Status” dialog box, which operates in the same way as FluentCart’s “Change Shipping Status” dialog box; only the order’s available status is displayed in order, however; shipping status remains the same in FluentCart’s “Change Shipping Status”; custom shipping statuses are listed directly within it. Writing to the FluentCart’s own order API, activity history, status change events, and item fulfillment are exactly the same as manually changing the status;
The Order workflow card: see where an order stands, move it on in one click
The Order workflow card on the order page simultaneously displays the order status and shipment status: the current status, the next step of the process, the reason for the change not being able to be made, and the Next step button for quick progress. Below, you are prompted with other status options to change to More Action. In case this page is unable to use the More Action to change the order status (for example, in a future FluentCart update), the card will automatically change to directly list the available order statuses; canceled orders have no “Change shipment status” option in FluentCart, and the card will also list the available shipment statuses directly.
Two process templates, create with one click
The 'Create Standard Process' page on the 'Order Status' page, and the 'Create Shipping Process (Shipping Status Axis)' page on the 'Tools' page, both allow you to create a 'Next Production → Scheduled Shipping → Shipped' workflow in one click. We recommend placing the workflow under the 'Shipping Status' section, because FluentCart will never automatically rewrite the shipping status, and the custom shipping status will appear directly in the 'Change Shipping Status' dialog box in FluentCart. The template will not change the name of the built-in status in FluentCart, nor overwrite the content you have already configured; applying it twice will not duplicate it. If needed, you can open 'Strict Process' on the 'Tools' page to make the order status advance or back only one step at a time (the 'Shipping Status' flow only applies to the order status; once you change it to 'Completed', 'Cancelled', or 'Reserved', it can be applied at any time).
Guard rails and records: no harm from a slip when changing settings or statuses
The status of orders in use cannot be removed during storage; the screen directly indicates which status it is in and how many orders there are; the stored status cannot be changed again; the status of orders in use will also be reminded if you try to change the code again. “Move Orders” will first check the number and destination, and will not send the order directly to the “Completed” or “Cancelled” end states; each move will leave a record. If an order is in an inactive state, a reminder will be displayed at the top of the settings page, and you can move it directly to the “Completed” or “Cancelled” end states. Before importing, the contents that will be changed will be listed, and you can still move them directly to the “Tools” tab after importing. Before importing, the previous imported data will be displayed in chronological order; the data that has been updated will be saved first, and you can “recover the last import”; if two people are editing the settings simultaneously, the data of the one who has already updated will be blocked and prompted to reload; the changes made by the other person will not be overwritten.
Workflow report and stalled-order list
The "Order Status Report" page breaks down the entire process: the number and amount of orders for each status (including paid/unpaid), the flow chart, the average and longest stay time for each step, and a list of orders that have exceeded N days in the same step. Each table can be downloaded as a CSV (Excel opens in Chinese without losing formatting). Daily summaries can be selected. The order list now includes a view of each custom status, the "Order History" on the order page combines the two axes on the same time axis, and the latest changes are displayed at the top.
Compatibility and Updates
FluentCart 1.6.0 is available (1.6.0 and 1.6.3 have both been tested and passed). PHP 7.4 or higher. It does not generate deprecation warnings on PHP 8.4 and 8.5. Exporting/importing JSON in one go is possible. Deleting plug-ins does not change any order data. The built-in YS Plugin Hub update mechanism allows you to receive new notifications directly from the WordPress plug-in page and update them with a single click after installation. The interface is available in both English and Traditional Chinese.
Features
Customized status and one-click workflow templates
Name, color, description, sorting, and payment terms can all be configured; one-click creation of "Next Production → Scheduled Shipment → Shipped" can be placed on the order status or shipment status.
Keep custom status after payment
When FluentCart processes a payment, it changes the status to "Processing," and the plugin automatically writes it back and leaves a note in the activity log.
Status change email notification
Each status can enable customer notifications and administrator copies, allowing you to directly edit the subject, title, and body text in the "Email Notifications" settings page of FluentCart.
More Action changes the order status
Order page More Action adds the option to change the order status; only this status is displayed; the "Order Process" tab in the side panel shows the current steps, with a one-click "Next" button.
Guard rails, records and undo
The usage status is not accidentally deleted; the move order is confirmed first and recorded; the import process checks for differences and is recoverable; two people can edit the order at the same time without overlapping each other.
Workflow report and stalled-order list
Order numbers and amounts for each state, funnel, dwell time, and stuck orders; each table can be downloaded as a CSV file; daily summary emails can be selected.
Screenshots
Changelog (Latest)
The *Order workflow* card on the order page stops repeating *More Action*: it shows
where the order stands and its next step, and an order status is chosen in one
No changes are made to the existing configuration or the emails.
The plugin is also quiet on PHP 8.4 and 8.5, and Move orders has been tested beyond its limits.
First batch.
For shop staff
- The Order workflow card is shorter. For the order status and the
shipping status it shows the status the order is on, which step of the
workflow that is, why nothing can be changed when nothing can (a canceled
order, an order with nothing to ship), and the Next step → button. The
The *Move to…* list and the *Change* button are gone from both lines, and each
The line says where they went: "Other statuses: More Action → Change Order"
Status" (or "… → Change Shipping Status").
- Any other status is chosen from More Action. *More Action → Change Order
Status* (added by this plugin in 0.6) for the order status, FluentCart's own
*More Action → Change Shipping Status* for the shipping status. FluentCart's
The shipping dialog lists every shipping status it displays, including the
order's current one and a custom one whose *Selectable in the admin* is off;
choosing either is refused by FluentCart and changes nothing.
- A canceled order keeps its shipping list on the card. FluentCart offers no
*Change Shipping Status* on a canceled order, although the shipping status can be changed later.
still change (for example to *Delivered* after a return), so there the card
lists the shipping moves on screen, under a sentence saying why.
- The card keeps a way back for the order status. Its order status list
comes back, under a sentence saying why, when the *Change Order Status* entry
cannot be used on the page: four seconds after the card appears there is no
More Action trigger the entry can be added through, or the page is not this
The order's own view; the More Action menu opens but the entry cannot be added
it; or the entry's dialog cannot load the order because of a network failure
or a server error — and then the dialog's message points to the list. When
the dialog is refused because the page has been open too long (its session
has expired), it says to reload the page instead, and shows no list that
The same would be denied. The rules are the same as before: *Completed*
and *Cancelled* ask first, *Completed* only on a paid order, and a cancel
returns the items to stock.
- After a card change, a page that stays where it is — FluentCart asks
"Leave site?" when the order has unsaved edits, and the answer was *Stay* —
brings the card up to date and lets its buttons be used again, instead of
leaving them grayed out.
- On a server running PHP 8.4 or newer that logs deprecation notices (for
For example, with `WP_DEBUG` turned on), the plugin no longer writes "Implicitly marking"
The lines "parameter … as nullable is deprecated" are added to the PHP error log.
Changed (technical)
- `OrderWidget::renderChanger()` — the widget's content and the `html` of
`GET orders/{id}/state` — draws, per axis, the head (badge, 'standing' note,
step), then either the lock sentence, "There is nowhere for this order to move
on this axis.", or the Next step button in its own
`<p class="ys-fct-changer-row">`, then `<p
data-ys-changer-hint=""> naming the More Action entry. When the order
axis has targets it also carries<div class="ys-fct-changer-fallback" data-ys-changer-fallback="order" hidden>`: a note, the
Select `data-ys-changer-select="order"` with the same options and
The `data-ys-confirm` flags remain as before, and the `data-ys-changer-go="order"` button.
The shipping axis has a select and a Change button only on a canceled order
(the order axis's `current` is `canceled`) with shipping targets: `<div class="ys-fct-changer-direct" data-ys-changer-direct="shipping">`, not hidden
and without a hint line, holding a note, `data-ys-changer-select="shipping"`
and `data-ys-changer-go="shipping"`. The widget's `subtitle` now describes the
The role of the card and where statuses are changed; FluentCart 1.6.0 and 1.6.3 handle it
to their card header, which does not display it.
- `assets/admin/order-changer.js` reveals the fallback (removes `hidden`, and
hides that axis's `data-ys-changer-hint` line) when the More Action entry is selected.
cannot be used: 4 s after the card appears (checked every 250 ms) the page is
not the card's own `#/orders//view` route or has no
`.fct-order-bulk-action-modal .fct-more-option-wrap [aria-controls]`; the
menu lookup after activity on the trigger runs out (21 tries, 50 ms apart),
or keeps throwing, while the trigger says `aria-expanded="true"`; or the
dialog's `GET orders/{id}/state` fails without an HTTP status (network), with
a `5xx`, or answers without an order axis. A card is noticed by one
`MutationObserver’ whose callback queues at most one `querySelectorAll’ each
100 ms. Once revealed for an order, the fallback is revealed at once on every
The card is rendered again for it until the page is left. The submit path remains unchanged —
`submit()` → `changeStatus()` → `POST orders/{id}/change` — and so are the
confirmation, `confirmed: true’ and the server’s rules.
- More activity on the More Action trigger while the menu lookup is running
restarts its count (it used to be ignored), so a click near the end of a
hover's lookup still finds a menu created late.
- `fetchState()` rejects with the HTTP `status` on the Error. The dialog's
`loadFailed` sentence names the list it has just revealed; when there is none
To reveal (an order with no move, or no card on the page), the dialog shows the
The reason for the server or the new `notLoaded` sentence. On a `401` or `403` it shows
the new `reloadPage` sentence ("%s Reload the page and try again.", %s"the
server's reason) and reveals nothing; on any other `4xx`, the server's reason.
- After a successful change, `afterChange()` no longer gives up when the page
has fired `beforeunload`: 1.5 s on, a page still marked as leaving is looked
at again after `STAY_WAIT` (5 s), and if it is still there the cards are
re-rendered from `GET orders/{id}/state`, `leaving` is cleared and the card's
The busy state (`busy`, `.is-busy`) is released; that second look never reloads
the page itself. A card rendered in place is released the same way.
Previously, both left the card's buttons inactive until a manual reload.
- `assets/admin/order-changer.css`: `.ys-fct-changer [hidden] { display: none
!important; }`, so the attribute holds whatever display rule FluentCart's page
brings, and spacing for the fallback, the canceled order's shipping list and
the hint line.
- Strings: new — the card's subtitle, the two "Other statuses: More Action → …"
lines, the fallback's note, the canceled order's shipping-list note,
`notLoaded`, `reloadPage`; changed — `loadFailed`; dropped — the old
subtitle. zh_TW updated and recompiled; FluentCart's *Change Shipping Status*
reads 「Change shipping status」 in every zh_TW string, as it already did on the settings
screen.
Fixed (technical)
- The 22 optional array parameters that default to `null’ now say so in their documentation.
type: `?array $settings = null` instead of `array $settings = null`, in
`Settings`, `Pipeline\Changer`, `Email\NotificationRegistry`,
The `Support\Labels` and `Reports\DailySummary` features have been deprecated in PHP 8.4.
Nullable types have existed since PHP 7.1, so the minimum remains PHP 7.4; no
caller, argument, or return value changes. Every shipped PHP file now lints
without a deprecation notice on PHP 8.5.
Tests
- The new unit group W (`tests/OrderCardTest.php`) renders the card from
Handwritten states: nothing to choose from on screen, one fallback, on the
order axis, rendered hidden, with exactly the targets in order and the
confirmation flags; the hint line on each open axis; on a canceled physical
order, the shipping list on screen with no hint and no fallback, and none on a
canceled the digital one; the next step on both; the no-next-step, nowhere-to-move, and
locked lines; the notes; escaping of labels in the list and in the Next step
The button's attributes. For the stylesheet and the script it matches only the source.
text: the `[hidden]` rule, and the lines that watch, reveal, handle the
dialog's statuses and release the card.
- What the script does is run in a browser by the new
`tests/order-changer-browser.py’ (Playwright and Chrome, 56 checks): a page
shaped like FluentCart's order view with the cards `OrderWidget` rendered,
Every REST response is scripted and the page's clock pauses. The fallback remains
hidden while More Action is working, also under a page rule setting `display` on
every `div`; it is shown after the wait with no trigger or on another route,
not before, and at once on a re-rendered card; an open menu that cannot take
the entry shows it, a hover does not, and a late menu still gets the entry;
The dialogs for 401, 403, 404, 500, network failure, and empty answer each give the following information:
the right sentence and reveal or not, a server reason holding `$&` included;
a page that stays after `beforeunload`, or refreshes in place, gets a
working card back; and a canceled order's shipping list posts the shipping
axis. Each of 15 mutations
of the script — the reveal is removed, a reveal at once, the re-render
path, the initial scan, the menu-open reveal, the 401/403 and 4xx branches,
the release, the stay check and others — fails it.
- The `changer-scenarios` C5 and S6, and the `guard-scenarios` A1 and N restate the card.
for 0.7 from real orders: no list or Change button on screen; the hint lines;
the order-axis list present, hidden, with the same targets and flags as the
dialog (no *Completed* on an unpaid order, *Canceled* and *Completed*
flagged); nothing on the shipping axis; Next step intact; the state route's
`html` byte by byte the widget of the order page; a canceled order's card with its
lock sentence, no fallback, and its shipping moves on screen — exactly the way it should be.
the ones the route accepts and the state route reports. S6's escaping probe is
now an order status, since an open order's card lists no shipping moves.
- `guard-scenarios` A4b puts 1001 orders on their own status and empties
it with `POST migrate`. It watches the statements the move sends — two full
batches of 500 and a partial third, each one `UPDATE` of the orders and one
history `INSERT` of the same size — then checks every order, not a sample:
the count the route reports, nothing left on the source, each order on the
Target with `updated_at` refreshed, exactly one `migrate` history row and
One activity line per order, and no mail. The orders are copies of one.
The fixture order's rows are removed again once the section passes. All
The suites run on FluentCart 1.6.0 and 1.6.3, on PHP 8.2 and 8.5.
FAQ
Will the FluentCart core be modified?
No. All the filters (order_statuses, editable_order_statuses, shipping_statuses, email_notifications, etc.) published by FluentCart are completed via REST; the “Change Order Status” option in More Action is also added by the add-on only when the menu is opened; updating FluentCart does not overwrite anything.
Why does the order status change to "Processing" after payment?
This is the core behavior of FluentCart (write-off, no filter). The add-on will write back the custom status in the same process; each status can be set to "Keep this status" or "Hand over to FluentCart for processing," while the "Only unpaid orders" status is always passed to FluentCart.
Where are the notification emails set up? Can the free version of FluentCart change the body text?
In FluentCart → Settings → Email Configuration → Notifications, you will find a new set of "Custom Order Status". The switch, subject, and preview are all native to FluentCart; the title and body are plugins added to the same editor page; the free version can also fill them in. The full block editor is still required with FluentCart Pro.
Why doesn't the native FluentCart backend allow me to directly select my custom order status?
FluentCart does not have any controls for freely selecting the order status by default (tests with 1.6.0 and 1.6.3); whether or not payment has been made, there are only fixed buttons like “Mark as completed”, “Processing return”, and “Cancel order” in More Action. Therefore, adding “Change order status” to the same menu item only lists the status that the order can be moved to. The shipping status is different: the custom shipping status is directly displayed in the FluentCart’s own “Change shipping status” dialog box.
Should the process be placed in the order status or the shipping status?
If the process starts only after the customer has paid (production, packaging, order placement, and shipment), it is recommended to set the shipment status to: FluentCart will never automatically modify it, and the built-in "change shipment status" can be used on every physical order that hasn't been canceled and needs to be shipped. The status truly belongs to the order itself, or you can set the shipment status when the customer wants to see it on the order status page.
Will disabling or removing the plugin affect orders?
Deactivating does not modify any order data, and settings and history will still be available after reactivating. Removing also preserves the settings and history tables unless YS_FCT_STATUS_REMOVE_DATA is defined in wp-config.php.
Also, if an order is in use, can it be removed directly?
No. It will be blocked during storage, and it will indicate which status it is in and how many orders are involved. Please first move the order using the "Moving Order" column on the status list and then remove it. The stored status cannot be changed; to change the code, add a new status and move the order again. If the status has already been removed and the order is still left, the top of the settings page will remind you that the "Tools" page can be moved directly.
After importing the settings, I found that they are incorrect. Is it possible to restore them?
Yes. The import only accepts files that have been exported using this add-on. Before writing, it lists what content will be added, removed, or changed; after importing, the Tools page will display "Restore Last Import," and the status, settings, and message text will return to what they were before the import.
