Skip to content

Settings

Pre-Order keeps its settings in OpenCart's own setting table, under the module_preorder group. You set them at Admin > Extensions > Extensions > Modules > Pre-Order.

Each key below carries where it applies. per store means a multi-store install can hold a different answer per storefront, and both are honoured: a read takes what that store holds, then what the default store holds, then the shipped default. install-wide means one thing serves every storefront, and the key's own description names that one thing.

Scope

Key Default What it does
module_preorder_status
install-wide
0 Whether the module is enabled. Set by the Status switch on this extension's own settings screen.

Merchandising

preorder — install-wide

Whether a product is sold ahead of stock and on what terms, set on that product's own Pre-Order tab. The combining rule is this ladder's own and is stated here rather than assumed, because the repository has two of them and they disagree — this one resolves by precedence and delivery_date's lead days combine by maximum. An option-value row overrides the product row; no row at all means the option value inherits it. Not overridden is the absence of a row, with both of its consequences: a product-level toggle that is off writes nothing, because no rows for a product is what "this is not a pre-order" is stored as, and an option value that must say "not a pre-order, even though the product is" gets a row of its own saying so rather than the column becoming a tri-state. Install-wide because one oc_product row and one oc_product_option_value row are shared between storefronts.

  • status — Whether this row is a pre-order. A 0 row is an option value saying it is not one while the product is. Starts at 1.
  • payment_mode — How the customer pays: defer takes the order without charging and emails a payment link once the stock lands, full charges at checkout through your own payment methods as any other product does. Deferring is the value a new row starts at, because the reverse would charge somebody in full for an item they are waiting on. Starts at defer.
  • date_expected — The date the stock is expected, shown to the customer. Empty is "no date announced", which is later than any known date when a line resolves several rows at once. Starts at empty.
Key Default What it does
module_preorder_payment_mode
install-wide
defer The payment mode a pre-order row on the product form starts at. A form default and nothing more: it is read when the tab is drawn and never at runtime, because what a line does is the mode frozen onto it at checkout. A store that sells one way round should not have to change the same select on every product.
module_preorder_end_on_stock
install-wide
0 Whether saving a product ends its pre-order once the stock has arrived. On, a product save that leaves every counter a live pre-order row of it watches holding at least one unit beyond everything owed, with no line still waiting, removes every pre-order row of that product — which is what the Pre-Order tab stores with the product switched off. At exactly enough stock it stays a pre-order, because there is no spare unit to sell as an ordinary product. A counter that does not subtract stock never ends one. The release pass runs first, so every waiting line the stock covers is marked ready and its order asked to pay before the rows go; lines already placed keep the date and payment mode the customer was told. Only a product save triggers it, the same as the release pass: an import or an API that writes the quantity without core's product save does not. Off by default, because it switches off something the merchant switched on.

Payment window

Key Default What it does
module_preorder_days_to_pay
install-wide
14 How long a payment request stays payable, in days. One number governs the link, the reminder at its midpoint and the abandonment at its end, because the customer's ability to pay and the merchant's willingness to wait are the same policy from two sides. 0 means never expire: no reminder, no auto-cancel, one choice rather than three.

Payment method

Key Default What it does
payment_preorder_status
install-wide
1 Whether the placeholder payment method is offered at checkout. Set at Extensions > Extensions > Payments > Pre-Order rather than on this module's own screen, because OpenCart gives a payment extension a setting code of its own. On, because the module's install writes this method rather than leaving a merchant to find it, and a pre-order cannot be taken without it — the module's own screen is what warns you when it is off. Unlike the module's own status this one is remembered across an update, because it is this extension that writes it either way and putting back the shipped 1 would be reversing your choice rather than declining to make one.
payment_preorder_sort_order
install-wide
1 Where the placeholder method sorts among your other payment methods at checkout. Read by core, exactly as it is for every payment extension, and stored under the method's own setting code.

What the customer is told

Key Default What it does
module_preorder_copy
install-wide
empty The merchant's own wording for the four sentences a shopper reads, per language code. Read whole to render one page and written whole by one form POST, so it is one setting key holding an array rather than a table. Empty for a language means the wording this extension ships, which is what the box shows in grey.

Advanced

Key Default What it does
module_preorder_sweep_secret
install-wide
empty The shared secret the payment-window sweep is compared against when it is called over the web, generated at install. It is what a merchant with no shell pastes into a host's cron panel or a third-party cron service, and it matters most on the OpenCart release whose own scheduler cannot run at all. Rotating it is its only control: there is no free-text edit, because a secret a merchant can type is a secret a merchant can shorten. An empty one refuses every call rather than admitting every call. It is remembered across an update on Rotate's own argument — rotating stops a cron line that was working until it is re-pasted, which is why that button confirms and says so, and a control that needs a confirm dialog is a control an update must not operate. An update is an uninstall followed by an install, so the memory that keeps it across an update also brings it back after an uninstall and a reinstall: uninstalling does not revoke it, and Rotate is the only thing that does.
module_preorder_diary_verbose_until
install-wide
0 When detailed logging stops, as a unix timestamp, and 0 is off. Turning Detailed logging on from this extension's settings form stores the moment two days from now; the writer compares that against the clock every time it is asked for a DEBUG line, so the window closes on its own with no scheduled task and nothing to clean up. While it is open this extension records what it did in far more detail, and the shared diary consequently holds less history.
module_preorder_api_enabled
install-wide
0 Whether the extension answers API requests at all. Off, every API route answers 404 api_disabled in the API's own JSON envelope, so an extension with its API off is shaped like one that has none. Read once for the whole installation from the default store rather than per store, because the one thing it serves is OpenCart's own API user, which has no store of its own. It is a separate switch from the extension's own Status, and the two are read independently: the API answers whether or not pre-orders are being taken, because what each customer is waiting for is the merchant's own record and a storefront switch should not hide it. The API only ever reads; no payment link is readable through it.

What you cannot change, and why

These are fixed on purpose. Each one is a decision with a reason beside it rather than a setting nobody got round to adding.

Merchandising

Inheritance is per row and not per field, and that is a limit rather than an oversight. If any option value the customer picked has a row of its own, only those rows speak and the product-level row is ignored entirely — so an option value that overrides the payment mode supplies its own expected date too, rather than borrowing the product's. The alternative breaks on the commonest shape there is: a product with a Size group you configured and a Colour group you never touched would have every Colour value inherit the product row, so every line resolves to a pre-order and per-option granularity is defeated by an option group that has nothing to do with the decision. Silence from an option value contributes nothing, never the default.

A pre-order row holds one of exactly two payment modes and there is deliberately no third meaning "inherit". The settings screen supplies the mode a newly created row starts at, which is a form default and is never consulted at runtime — what a line does is the mode frozen onto it when the order was placed, so a row that deferred to a setting could have its terms changed underneath a customer who has already been told them.

When the stock arrives, the pre-order ends for the whole product or not at all. A product with one option value still short keeps every value a pre-order until all of them are covered. Ending one option value alone would need two different writes, depending on whether the product-level row is itself a pre-order, and would leave a line that watches one ended counter and one live one.

Surfaces

Where the pre-order line is spliced into a product card, and the markup it looks for, are fixed. A template this extension cannot place the line in keeps core's own card untouched rather than losing it — so a theme that rewrote the price block loses the line, and the store keeps the page.

Rule Value
The price block, which both releases open this way <div class="price">
Its close, the first one after it </div>
The condition the block sits in /\G\s*\{%\s*endif\s*%\}/