Skip to content
  1. Extras
  2. MiniShop3
  3. System settings

System settings ​

MiniShop3 settings live under System → System Settings, namespace minishop3. Every name starts with the ms3_ prefix.

General settings ​

SettingDefaultDescription
ms3_services_config(not in transport)Path to ms3.services.php. Without this key ServiceRegistry looks for {core_path}config/ms3.services.php. The file returns [service_id => ClassName] and overrides default classes
ms3_services_addons_dir(not in transport)Folder with service registration fragments, {core_path}config/ms3.services.d/ by default. *.php files load in alphabetical order after the main config
ms3_assets_url(not in transport)Overrides the component assets URL. Default {assets_url}components/minishop3/
ms3_action_url(not in transport)Overrides the Web API base URL. Default {ms3_assets_url}api.php
ms3_core_path(not in transport)Overrides the component core path. Default {core_path}components/minishop3/
ms3_version(empty)Version of the installed package. Filled in automatically on install and upgrade, no need to edit it. Returned by /health and compared against the version of the files on disk
ms3_chunks_categoriesComma-separated category IDs for the chunk list. On install the MiniShop3 category is placed here
ms3_use_schedulerfalseUse Scheduler for background tasks

Version and files out of sync

When ms3_version is newer than the version of the files on disk, the Manager shows a warning: the files were not copied completely. This happens when an upgrade breaks halfway through. Reinstall the package to fix it.

Product category ​

SettingDefaultDescription
ms3_template_category_defaultDefault template for new categories
ms3_category_show_nested_productstrueShow nested products from subcategories
ms3_category_show_optionsfalseShow product options in the category table
ms3_category_id_as_aliasfalseUse category ID as URL alias
ms3_category_content_default(not in transport)Default content for new categories (snippet call). Read by the category panel JS on create. Add the key manually if you need auto-filled content
ms3_category_products_default_rows20 (code fallback)Rows per page in the category product table. Not in transport: until you create the key, 20 applies
mgr_tree_icon_mscategoryicon icon-barcodeCSS class for the category icon in the resource tree

Product ​

Main fields ​

SettingDefaultDescription
ms3_template_product_defaultDefault template for new products
ms3_product_main_fieldspagetitle,longtitle,description,introtext,contentMain fields on the product panel
ms3_product_extra_fieldsprice,old_price,article,weight,color,size,vendor_id,made_in,tags,new,popular,favoriteExtra product fields
ms3_product_show_in_tree_defaultfalseShow new products in the resource tree
ms3_product_id_as_aliasfalseUse product ID as URL alias
ms3_product_remember_tabstrueRemember the active product panel tab
mgr_tree_icon_msproducticon icon-tagCSS class for the product icon in the resource tree

Product tabs ​

SettingDefaultDescription
ms3_product_tab_extratrueShow the product properties tab
ms3_product_tab_optionstrueShow the options tab
ms3_product_tab_categoriestrueShow the categories tab
SettingDefaultDescription
ms3_product_source_default0Default media source ID for the gallery
ms3_product_thumbnail_default{assets_url}components/minishop3/img/mgr/ms3_small.pngPlaceholder image path
ms3_product_thumbnail_sizesmallDefault thumbnail size

Price and weight formatting ​

SettingDefaultDescription
ms3_price_format[2, ".", " "]Price format: [decimal places, decimal separator, thousands separator]
ms3_weight_format[3, ".", " "]Weight format: [decimal places, decimal separator, thousands separator]
ms3_price_format_no_zerostrueStrip trailing zeros in prices (15.00 → 15)
ms3_weight_format_no_zerostrueStrip trailing zeros in weight
ms3_price_snippetDeprecated. Any non-empty value turns on price recalculation when products are fetched. The value itself is never used
ms3_weight_snippetDeprecated. Same for weight
ms3_currency_symbol₽Currency symbol (₽, $, €, £, ₴, ¥, ₸)
ms3_currency_positionafterSymbol position: before ($ 100) or after (100 ₽)
ms3_weight_unitkgWeight unit (e.g. kg, г, lbs, oz). Used in *_formatted placeholders

Cart ​

SettingDefaultDescription
ms3_cart_contextfalseUse a single cart across all contexts
ms3_cart_max_count1000Maximum number of items in the cart
ms3_cart_page_id0Cart page ID. Used for “Go to cart” in the mini cart and JS redirects
ms3_order_page_id0Checkout page ID. Used for the “Checkout” link from the cart

Orders ​

General settings ​

SettingDefaultDescription
ms3_order_format_numymOrder number format (date() format)
ms3_order_format_num_separator/Separator in the order number
ms3_date_formatd.m.y H:MDate format in the Manager
ms3_order_user_groupsGroups for customer registration (comma-separated)
ms3_order_show_draftsfalseShow drafts in the Manager order list
ms3_order_redirect_thanks_id1ID of the “Thank you for your order” page
ms3_order_success_page_id0ID of the successful payment page
ms3_order_register_user_on_submitfalseCreate modUser on checkout
ms3_email_managerManager email addresses for notifications (comma-separated)
ms3_delete_drafts_afterDelete old drafts (strtotime format: -1 year, -2 weeks)
ms3_order_log_actionsstatus,products,field,addressLogged order actions
ms3_payment_on_failed_status0Order status ID for a failed or cancelled payment. 0 — leave the status unchanged
ms3_payment_on_refunded_status5Order status ID for a full refund. 0 — leave the status unchanged. A partial refund never changes the status

Failed payment and the stock reservation

ms3_payment_on_failed_status set to 0 keeps the order in its current status so the customer can retry the payment. With inventory enabled, however, the stock reservation stays with that order until it is cancelled. Set a cancellation status ID here if you want the stock released automatically.

Before 1.14 the default was 5. On upgrade it becomes 0 only for those who never touched the setting: a manually edited value is left alone by the migration.

Manager fields ​

Order, address, and product table fields

These used to be configured via ms3_order_grid_fields, ms3_order_address_fields, ms3_order_product_fields, and ms3_order_product_options. They are now managed in Utilities → Model fields (tables ms3_model_fields and ms3_model_field_sections, models msOrder / msOrderAddress) and Utilities → Grid settings (ms3_grid_fields). The old system settings are no longer read.

Order statuses ​

SettingDefaultDescription
ms3_status_draft1ID of the “Draft” status
ms3_status_new2ID of the new order status after checkout
ms3_status_paid3ID of the paid order status
ms3_status_sent4ID of the “Sent” status. A shipment moves the order here when it becomes “shipped”
ms3_status_canceled5ID of the canceled order status
ms3_status_for_stat2,3Status IDs for completed order statistics
ms3_order_status_transitions(empty)Allowed transitions between statuses. Empty — transitions are limited only by the “final” and “fixed” flags on the statuses themselves

Statuses after install

The seed_order_statuses migration creates five rows in ms3_order_statuses (ids 1–5: draft, new, paid, sent, canceled) and updates ms3_status_new, ms3_status_paid, and ms3_status_canceled to match. If you changed or deleted statuses manually, verify ids under Settings → Statuses against these keys.

The migration does not update ms3_status_sent — it stays at 4. If the “Sent” status got a different id, set it here yourself.

Allowed transitions ​

By default an order can move to any status except in two cases: it cannot leave a status flagged “final”, and it cannot move back down the order from a status flagged “fixed”.

ms3_order_status_transitions defines the exact route on top of those rules. The format is from:to pairs separated by commas:

2:3,3:4,2:5

From status 2 the order may go to 3 or 5, from 3 only to 4. Anything not on the list is forbidden. The same list is accepted as JSON: [[2,3],[3,4],[2,5]].

A malformed value forbids every transition

Parsing does not tolerate typos. If the value cannot be parsed, no order changes status at all, and the response reports a disallowed transition — not a broken setting. Check the format right after editing it.

Inventory ​

SettingDefaultDescription
ms3_inventory_enabledfalseTake stock into account when placing an order

While the setting is off, the cart and checkout ignore stock entirely. Once enabled, stock is reserved when the order moves to “New”, committed on “Paid” and released on “Canceled” if the order had not been paid.

Fill in stock before enabling

An empty stock value (NULL in the stock column) reads as zero, and the decrement runs on a “stock is at least the requested amount” condition. Enabling inventory on an unfilled warehouse makes every such product impossible to order.

Stock is per product. Order lines with the same product, including variants with different options, draw from one shared amount.

Shipments ​

SettingDefaultDescription
ms3_shipment_enabledfalseMove the order status along with the shipment state
ms3_shipment_on_delivered_status0Order status ID for the “delivered” state. 0 — leave unchanged
ms3_shipment_on_in_transit_status0Order status ID for the “in transit” state. 0 — leave unchanged

A shipment holds the tracking number and the delivery state. Creating one and setting a tracking number works with the setting off as well — only the automatic order status change is disabled.

A shipment has seven states, and the order does not react to all of them:

Shipment stateWhat happens to the order
ShippedMoves to ms3_status_sent
Cancelled, FailedMove to ms3_status_canceled
In transit, DeliveredTake the status from their own setting; 0 leaves it unchanged
Preparing, ReturnedLeave the status alone: the package ships no settings for them

Why “delivered” changes nothing by default

The shipped status is flagged final in the default set, and an order cannot leave a final status. A value other than 0 only makes sense if you made “Sent” non-final or use a status of your own.

Customers ​

Customer account settings. How it looks on the frontend: Login and registration.

ms3_customer_login_page_id and ms3_customer_register_page_id only set the URLs used in links. The forms themselves are rendered by msCustomer through unauthorizedTpl; the package has no separate login-only chunk.

Customer account pages ​

SettingDefaultDescription
ms3_customer_login_page_id0Login page ID
ms3_customer_register_page_id0Registration page ID
ms3_customer_profile_page_id0Profile page ID
ms3_customer_addresses_page_id0Addresses page ID
ms3_customer_orders_page_id0Order history page ID
ms3_customer_redirect_after_login0Page ID to redirect to after login (0 — stay)

Authentication and registration ​

With ms3_customer_auto_register_on_order and ms3_customer_auto_login_on_order enabled, a guest becomes an msCustomer during checkout, without the account form. Turn them off if you create accounts only manually.

ms3_customer_require_email_verification sends an email with a link to GET /api/v1/customer/email/verify. Until the address is confirmed, some account flows may require a resend.

SettingDefaultDescription
ms3_customer_auto_register_on_ordertrueAutomatically register the customer on checkout
ms3_customer_auto_login_on_ordertrueAutomatically log in after checkout
ms3_customer_auto_login_after_registertrueAutomatically log in after registration
ms3_customer_require_email_verificationfalseRequire email verification
ms3_customer_send_welcome_emailtrueSend welcome email

Order cancellation ​

SettingDefaultDescription
ms3_customer_cancel_allowed_statuses2,3Status IDs where the customer can cancel an order (comma-separated). Default: new and paid

Order cancellation settings

The customer sees the “Cancel order” button only for orders with a status from this list. On cancel, the order moves to ms3_status_canceled.

To disable customer cancellation, set the value to 0.

An empty value does not disable cancellation

Clearing the setting does not turn cancellation off — it falls back to the statuses from ms3_status_new and ms3_status_paid, that is, the same “New” and “Paid”. Customers will still be able to cancel a paid order.

modUser sync ​

Off by default: the account runs on msCustomer and the MS3 token. Enable sync if you need MODX groups, ACL, or shared sessions with other components.

SettingDefaultDescription
ms3_customer_sync_enabledfalseEnable msCustomer ↔ modUser sync
ms3_customer_sync_create_moduserfalseCreate modUser when msCustomer registers
ms3_customer_sync_delete_with_userfalse (not in transport)Delete msCustomer when modUser is deleted. Read by the minishop3.php plugin; create the key manually if needed
ms3_customer_sync_user_group0Group ID for new modUser accounts
ms3_customer_duplicate_fields["email", "phone"]JSON array of fields for duplicate checks

Security ​

Tokens ​

SettingDefaultDescription
ms3_customer_token_ttl86400Customer token lifetime (seconds, 24 hours)
ms3_customer_api_token_ttl86400API token lifetime (seconds, 24 hours)
ms3_password_reset_token_ttl3600Password reset token lifetime (seconds, 1 hour)
ms3_email_verification_token_ttl86400Email verification token lifetime (seconds, 24 hours)
ms3_email_verification_urlYour own URL for the verification email. If empty, the link points to Web API api.php?route=…/email/verify&token=…&html=1
ms3_email_verification_success_urlURL to redirect to after successful email verification. If empty, returns to the site with ?ms3_email_verified=1
ms3_snippet_token_secret(auto-generated)Secret key for snippet tokens
ms3_snippet_cache_ttl3600Snippet parameter cache lifetime (seconds)
ms3_payment_secretSecret key for payment notifications

Brute-force protection ​

SettingDefaultDescription
ms3_customer_max_login_attempts5Maximum failed login attempts
ms3_customer_block_duration300Block duration (seconds, 5 minutes)

Password requirements ​

SettingDefaultDescription
ms3_password_min_length8Minimum password length
ms3_password_require_uppercasefalseRequire uppercase letters
ms3_password_require_numberfalseRequire numbers
ms3_password_require_specialfalseRequire special characters

API ​

Web API (api.php) settings. Method list: REST API.

ms3_cors_allowed_origins is empty by default: requests are accepted only from the same domain. Value * allows any origin, but without credentials; for a cookie token from another domain, list the exact origins comma-separated.

The rate limit applies to all /api/v1/*. On a single server the file counter store is enough.

SettingDefaultDescription
ms3_api_debugfalseAPI debug mode (extended logging)
ms3_cors_allowed_origins-Allowed CORS origins: empty = same domain only, * = any (without credentials), or comma-separated list
ms3_rate_limit_max_attempts60Maximum requests per period
ms3_rate_limit_decay_seconds60Rate limit period (seconds)
ms3_rate_limit_storefileCounter store: file, redis, memcached
ms3_rate_limit_storage_path-Directory for file (empty = system temp)
ms3_rate_limit_redis_dsn-Redis DSN (overrides host/port when set)
ms3_rate_limit_redis_host127.0.0.1Redis host
ms3_rate_limit_redis_port6379Redis port
ms3_rate_limit_redis_password-Redis password
ms3_rate_limit_redis_database0Redis DB index
ms3_rate_limit_memcached_servers127.0.0.1:11211Memcached server list
ms3_web_catalog_respect_resource_groupstrueHide products and categories closed by MODX resource groups from the catalog
ms3_public_seo_tv_map(empty)Override SEO block values with your own TVs. JSON such as {"title":"tv.seo_title"}

Restricted catalog sections ​

ms3_web_catalog_respect_resource_groups is on by default: products and categories from a closed MODX resource group are hidden from outsiders in the Web API, in the snippets and in the cart. A signed-in customer whose customer group is linked to a MODX user group sees the restricted section.

Works only together with the MODX system setting access_resource_group_enabled.

A restricted catalog does not work on a cached page

MODX serves the finished HTML before the snippets run. The first guest writes their reduced list into the cache, and a signed-in customer sees exactly that. Call the snippets uncached: [[!ms3_products]], [[!ms3_gallery]].

Overriding SEO with your own TVs ​

The format of ms3_public_seo_tv_map is JSON: the key on the left comes from a fixed set (title, description, canonical, robots, og.title, og.description, og.image, og.type), the right side is a TV name prefixed with tv.:

json
{"title": "tv.seo_title", "robots": "tv.robots"}

Applies to the product and category cards, and to lists and trees when include_seo=1.

Malformed JSON is ignored silently

A formatting error produces no message: the setting is simply skipped and the SEO block returns its default values. If the override did not work, check the JSON first.

Frontend ​

SettingDefaultDescription
ms3_token_namems3_tokenToken name for visitor identification
ms3_register_global_configtrueRegister ms3Config in the DOM
ms3_frontend_assetsJSON arrayCSS and JS loaded on the frontend (hooks.js, CartAPI.js, CartUI.js, ms3.js, etc.)

order-addresses.js is not in the default list. Include it separately if checkout needs the saved-address block.

Placeholders in ms3_frontend_assets ​

  • [[+assetsUrl]] — assets/components/minishop3/
  • [[+jsUrl]] — assets/components/minishop3/js/
  • [[+cssUrl]] — assets/components/minishop3/css/

Import ​

SettingDefaultDescription
ms3_utility_import_fieldspagetitle,parent,price,articleFields for import
ms3_utility_import_fields_delimiter;CSV column delimiter
ms3_import_sync_limit300Synchronous import limit (rows)
ms3_import_preview_rows5Preview row count
ms3_import_upload_pathassets/import/Upload path for import files

Notifications ​

Email ​

SettingDefaultDescription
ms3_email_managerManager email addresses for notifications (comma-separated)

Telegram ​

SettingDefaultDescription
ms3_telegram_bot_tokenTelegram bot token (get from @BotFather)
ms3_telegram_managerCSV manager chat IDs for status-change notifications. OrderStatusService reads it alongside Utilities → Notifications

Telegram bot setup

  1. Create a bot via @BotFather and get the token
  2. Set the token in ms3_telegram_bot_token
  3. Configure recipients either way:
    • Utilities → Notifications — Telegram channel, recipient_value = chat ID (recommended since 1.11+)
    • ms3_telegram_manager — CSV chat IDs for the older status-change delivery

Get your chat ID from @userinfobot.

Usage examples ​

Getting a setting in PHP ​

php
$priceFormat = $modx->getOption('ms3_price_format');
$currencySymbol = $modx->getOption('ms3_currency_symbol');

Getting a setting in Fenom ​

fenom
{* Currency symbol *}
{'ms3_currency_symbol' | option}

{* Customer profile page ID *}
{'ms3_customer_profile_page_id' | option}

Price format ​

ms3_price_format accepts a JSON array of three values — decimal places, decimal separator, thousands separator:

json
[2, ".", " "]

Result: 1 234.56

Changing price and weight ​

Price and weight are modified by plugins on the msOnGetProductPrice and msOnGetProductWeight events. Attaching a plugin to the event is enough — nothing has to be enabled in the settings.

php
<?php
// Plugin on the msOnGetProductPrice event
// Read the price from eventData: a previous plugin may have changed it
$price = $modx->eventData['msOnGetProductPrice']['price'] ?? $scriptProperties['price'];
$data = $scriptProperties['data'];

// 10% discount for products in category 5
if ((int) ($data['parent'] ?? 0) === 5) {
    $price = $price * 0.9;
}

// Return through eventData so the next plugin receives the changed price
$modx->eventData['msOnGetProductPrice']['price'] = $price;

Event parameters and their call order are described in Product events.