ডকুমেন্টেশন আপাতত শুধুমাত্র ইংরেজি। সাইট বাকি আপনার ভাষা অনুসরণ করে.
Shop
The official Shop plugin: catalog, cart, checkout, orders, customers, Mollie payments, shipping with carrier labels and tracking, tax, discounts, invoices, subscriptions, reports, and backups.
24 মিনিট পড়া হয়েছে
Shop (justflows.shop) is the official e-commerce plugin, built and maintained by the Justflows team. It adds a catalog, a public /shop page, cart and checkout, orders, customers, payments, shipping, tax, discounts, invoices, subscriptions, downloadable products, reports, backups, and order emails. Products are ordinary CMS content of type product, so they get the block editor, translations, SEO, and search. Prices, stock, orders, and payments live in the plugin's own shop_* tables.
Before you take real orders
Shop is free and listed on the Marketplace. Set it up in Sandbox / test mode first, place a few test orders, and keep backups of your shop. See Known limits for what is not available yet.
| Detail | Value |
|---|---|
| Plugin id | justflows.shop |
| Version | 0.1.7 |
| License | GPL-2.0-or-later |
| Price | Free |
| Requires | Justflows 0.1.8 or later (below 1.0.0). Newer features need a newer host: invoices by email need 0.3.4, downloads need private file storage (0.3.4), backups and subscription limits need 0.3.5, the Shop sidebar needs widget areas (0.3.5), and table upgrades need 0.3.6. Older hosts keep working without them. |
| Admin languages | English, Dutch, German, French, and Spanish |
| Plugin permissions | admin:extend, network:outbound, content:read|create|publish|delete, users:read|manage, diagnostics:publish, mail:send, jobs:register, files:private, platform:tenancy |
Install and set up
- 1
Install and activate
Admin → Marketplace → Shop → Install, then Activate. You can also upload a Shop
.jfpkgfrom Admin → Plugins. - 2
Choose where commerce data lives
Activation opens the setup guide. Keep the current Justflows database (the default), or use a separate commerce database, which is tested before you can continue. This choice is permanent: changing it later is a migration, not a setting.
- 3
Enter store details
Store name, address, currency, and selling options are optional here. You can fill them in later.
- 4
Finish
Shop creates its tables, the Product and Shop content types, and the storefront pages: Shop, Product detail, Product category, Cart, Checkout, Order confirmation, Customer account, and Order tracking. The Commerce section appears in the admin sidebar.
Tip
Leave Sandbox / test mode on (Admin → Plugins → Shop → Settings) while you set up. Payments then use each provider's test environment and carriers use their test hosts.
Store settings
Admin → Plugins → Shop → Settings, also reachable from the Settings tab at the end of the Commerce menu.
| Setting | Default | What it does |
|---|---|---|
| Store name | (empty) | Shown on invoices, emails, and the storefront. Can differ per language. |
| Store mode | Open | Open sells. Catalog only, Paused, and Maintenance show a notice instead of Add to cart, and checkout takes no orders. Maintenance does not hide product pages. |
| Store time zone | Same as the site | Sale and discount start and end times use it. |
| Terms and privacy links | (empty) | When set, checkout asks shoppers to agree before placing an order. An optional, unticked marketing opt-in can be added. |
| Legal / business name, contact email, address, city, postal code, country | (empty) | Your business identity. The contact email also receives New order emails. The store country is used for tax until a customer address is known. |
| Base currency | EUR | ISO currency code. |
| Catalog prices | exclusive | Whether prices you enter exclude tax (added at checkout) or include it. |
| Weight unit / Dimension unit | kg / cm | Also lb / in. |
| Selling countries | (empty) | Comma-separated ISO codes. Empty allows every country. |
| Shipping countries | (empty) | Comma-separated ISO codes offered at checkout. |
| Allow guest checkout | On | Off requires an account to check out. |
| Sandbox / test mode | Off | Uses test payments and carrier sandboxes and skips live side effects. |
| Order number prefix, format, suffix, counter | JF + {YY}{MM}{DD}-{RANDOM_ALPHANUMERIC} | See Order numbers. |
| Delete shop data / pages when removed | On | See Uninstalling. |
Order numbers
Each new order number is prefix + format + suffix. The defaults give numbers like JF260929-A1B2. These tags work in all three parts:
| Tag | Inserts |
|---|---|
{COUNTER} | The order counter |
{ORDER_ID} | The first 8 characters of the internal order id |
{YYYY} / {YY} | Year, 2026 / 26 |
{MM} | Month, 09 |
{WW} | ISO week number, 40 |
{D} | Day of the week, Monday = 1 … Sunday = 7 |
{DD} | Day of the month, 29 |
{RANDOM_NUMBER} | Random digits (4) |
{RANDOM_LETTER} | A random capital letter (1) |
{RANDOM_ALPHANUMERIC} | Random capitals and digits (4) |
Random tags take a length, for example {RANDOM_NUMBER:6} (1 to 12). Dates, week numbers, and counter resets use UTC. The counter has a start number, a step, a zero-padded length, and a reset (never, daily, weekly, monthly, or yearly). You can also schedule a one-off reset (Reset counter on, for example 2027-01-01 00:00) or tick Reset counter now.
| Prefix | Format | Suffix | Counter | Result |
|---|---|---|---|---|
JF | (default) | JF260929-A1B2 | ||
SHOP- | {COUNTER} | -NL | start 1000 | SHOP-1000-NL |
{YYYY}- | {COUNTER} | length 5, yearly | 2026-00001 | |
INV | {YY}{WW}-{COUNTER} | start 10, step 10, weekly | INV2640-10, INV2640-20 | |
| (empty) | {RANDOM_NUMBER:8} | 48210937 |
Order numbers keep letters, digits, ., -, and _, and are at most 64 characters. If a number is already taken, the counter moves to the next free value; a format with no counter or random tag gets a random ending. Changes apply to new orders only.
Products
Commerce → Products → new. New products start from the Product detail layout. The content editor menu shows Images, Pricing, Inventory, Shipping, Attributes, Variations, Categories, and Tags as separate entries.
- Shared across languages: SKU, prices, stock, and variations belong to the product's translation group, so every translation sells the same item. Title, excerpt, and page content are per language. Shop → Products lists the default language only; switch languages in the content editor.
- Attributes (Commerce → Attributes): select, text, color, image, button, or number. A select attribute with several values generates variation combinations. Choosing an option on the product page updates the price, SKU, and stock.
- Categories and tags (Commerce → Categories / Tags): categories can be nested. Both are assigned in the product editor.
- Visibility: public and catalog-only products appear on
/shop; hidden and search-only products do not. Published products are included in site search. - Shipping class: the product's Shipping section offers a dropdown of the method names set up under Shop → Shipping zones (a name used in several zones appears once, with its zones listed). A product that already has a class not in the list keeps it.
Bulk edit products
Select products on Commerce → Products and choose Bulk edit to change up to 500 at once. Fields left on No change stay as they are. Preview changes lists what will change for each product before anything is saved. Needs the Update products capability.
| Field | Options |
|---|---|
| Regular price | Set, or raise or lower by an amount or a percentage |
| Sale price | Set, a percentage or amount off the regular price, or remove. A sale price at or above the regular price is refused for that product without stopping the rest. |
| Stock | Track inventory on or off; set, add, or subtract stock; backorders; one per order |
| Tax, shipping, and visibility | Tax class, shipping class (No shipping class, or one of your shipping methods), and visibility |
| Categories and tags | Add or remove |
Prices and stock also apply to every variation of a variable product.
Import products
Commerce → Products → Import takes CSV, JSON, or XML and detects the format. Run the preview first: it lists what will be created, updated (matched by SKU), or rejected, and writes nothing. A sample file ships as samples/products-sample.json.
title, slug, sku, price, stock, status, categories, tags, images, excerptProduct tags in layouts
Put these tags in any text of a product layout. They are filled from the catalog on the public page: {{title}}, {{excerpt}}, {{sku}}, {{barcode}}, {{price}}, {{regular_price}}, {{sale_price}}, {{currency}}, {{stock}}, {{type}}, {{visibility}}, {{tax_class}}, {{weight}}, {{length}}, {{width}}, {{height}}, {{dimensions}}, {{attributes}}, and {{options}}. {{price}} follows the catalog tax display (see Tax).
The shop page
Activating Shop publishes /shop, which lists published catalog products as a grid or a list. When inventory is set to hide out-of-stock products, those are left off too. A Shop page that already has its own blocks is left alone. Commerce → Shop page sets the product grid:
| Setting | Default |
|---|---|
| Default layout | Grid |
| Visitors can switch grid and list | On |
| Visitors can sort products | On |
Search and the category, tag, price, and sale filters are the Product filters widget in the Shop sidebar widget area, shown on the Shop page. Place it left, right, or above the products under Appearance → Widgets, and add other widgets next to it. Other plugins can add filter widgets that work with the catalog through the URL. Sites that upgraded keep their earlier filter choices as the area's starting widget.
Search and filters run in the browser on the products already loaded. Choosing a parent category includes its subcategories. The price filter compares the shown price, and both it and the "On sale" switch hide themselves when they cannot narrow anything. Active filters show as removable chips with Clear all. The filter state is kept in the address, so a filtered view can be shared:
/shop?category=<slug>&tag=<slug>&q=<text>&min=<n>&max=<n>&sale=1&sort=price-ascStorefront blocks and patterns
Shop registers these blocks in the page builder. Every field has a label and help text, and fields that do not apply to the current choice are hidden.
| Block | What it shows |
|---|---|
Product gallery (justflows.shop.gallery) | Product photos in several layouts, with an optional lightbox. |
Buy box (justflows.shop.buy-box) | Title, price, variation options, stock, and Add to cart. |
Product breadcrumbs (justflows.shop.breadcrumbs) | Shop › category › subcategory from the product's first category, each linking to the filtered shop. Or type links by hand. |
Product highlights (justflows.shop.highlights) | Short selling points. |
Product details accordion (justflows.shop.accordion) | Collapsible detail sections. |
Store policies (justflows.shop.policies) | Delivery, returns, and similar notes. |
Product reviews (justflows.shop.reviews) | Reviews with ratings. Reviews without an avatar use the site's avatar placeholder. |
Related products (justflows.shop.related) | Products from the catalog (see below). |
Product list (justflows.shop.product-list) | A product grid in one of many styles: inline price, CTA, swatches, tall images, overlay, simple, favorites, border grid, supporting text, hover CTA, and detail cards. |
Detail shots (justflows.shop.detail-shots) | Close-up images with captions. |
Product list and Related products take their products from: all products, products related to a product (most shared categories and tags first, then newest), products you pick (a searchable checklist, in the order you tick them), chosen categories (subcategories included), or chosen tags. Sort by newest, oldest, name, or price, and show up to 24. A product page never lists itself. Type rows by hand keeps manual rows.
Gallery, Buy box, Breadcrumbs, and Details accordion have a Product picker. Left empty, they follow the product page they are on. With a product picked, they show that product on any page, and Add to cart adds it.
Patterns: Product detail, Product mosaic, Product story, Product list, and Ecommerce storefront. Storefront styles (.jf-product-*) are added to /theme.css only while Shop is active. Products without a photo show the site's Product image placeholder, which you can replace under Settings → Placeholders.
Cart and checkout
- Cart (
/shop/cart) lists each product with its photo, options, unit price, and line total. Quantities can be changed or removed. The subtotal follows the catalog tax display, and checkout stays closed until every line can be sold. Product pages and the cart only show a stock count when 5 or fewer are left. - Checkout (
/shop/checkout) collects contact, shipping, and billing details, then prices delivery, tax, and discounts. Country lists follow the selling and shipping countries. Guest checkout closes when the shop requires an account. - Signed-in shoppers start with their account email, name, phone, and last billing and shipping addresses, all editable. Placing an order saves those details to the customer record linked to their account, and a first order gives them the Customer role.
- Placing an order stores it as Awaiting payment, reserves stock, and emails Order confirmed to the customer and New order to the store.
- Failed payments keep the cart. If a Mollie payment fails, is cancelled, or expires, the customer returns to checkout with their items, a message explaining why, and a different method preselected. Retrying updates the same order instead of creating a new one.
Cart and checkout routes are rate limited per IP: adding or updating a cart line allows 30 requests a minute, and checkout and the catalog allow 60.
- Create an account at checkout. Shoppers who are not signed in can choose a password with their order. It is required for a subscription and in shops without guest checkout. An email that already has an account is asked to sign in.
- Retry-safe. Each checkout submission carries a key, so submitting twice after a lost connection places one order.
- Clear errors. Required fields are marked, a refused value is explained under its field and read out by screen readers, and the cursor moves to the first field to fix.
- Free orders skip payment. When an order, and every renewal of a subscription in it, costs nothing, checkout hides the payment choices and the order is paid at once.
- VAT number. When invoices are on, business buyers can add a VAT number, printed on their invoice.
Inventory
Commerce → Inventory shows available, reserved, and committed stock for each product and holds the stock policy.
| Setting | Default |
|---|---|
| Low-stock threshold | 5 |
| Out-of-stock threshold | 0 |
| Notify on low / out of stock | On |
| Hold stock for unpaid orders | 60 minutes |
| Backorders | Disabled (or Allowed, or Allowed with notice) |
| Hide out-of-stock products | Off |
| Show stock on storefront | When low (or Always, or Never) |
| Track stock for new products | On |
Placing an order reserves tracked stock for the hold time: available goes down and reserved goes up. When the payment is captured, the quantity moves to committed. If the customer does not pay in time, it returns to available. A hold time of 0 commits stock only when the payment is captured. Opening Commerce → Inventory also commits stock for already-captured payments and releases expired holds.
Orders
Commerce → Orders lists each order with the customer, items, payment, shipping, and total, with status tabs and counts. Opening an order shows its addresses, lines, tax, payments, refunds, fulfillments, downloads, stock holds, timeline, and emails.
| Status | Meaning |
|---|---|
| Awaiting payment | Placed, not paid yet. |
| Authorized / Paid | The payment was authorized or captured. |
| Processing / On hold | You are preparing the order, or have paused it. |
| Shipped / Delivered | Records a fulfillment. Shipped can carry a tracking number and carrier. |
| Completed / Archived | Finished, or moved out of the way. |
| Awaiting return / Returned | A return is expected or received. Returned records a fulfillment. |
| Cancelled / Failed | The order will not be fulfilled. |
| Partially refunded / Refunded | Money was returned. |
| Disputed | The customer opened a dispute or chargeback. |
The Status and notes box on an order changes its status or adds a private note. Every change goes on the timeline with who made it. Moving to Shipped, Delivered, or Cancelled can email the customer with the matching template. Changing a status needs the Update orders capability.
Ship, refund, and print
- Ship items sends part of an order: choose how many of each item go in a shipment, with a tracking number and carrier, and optionally email the customer. The order is Partially shipped until everything is sent.
- Refund returns all or part of a payment from the order page. Choose items and leave the amount blank to refund what they were paid, tick Refund shipping to add the shipping, and restock chosen items once. A refund already made in Mollie's dashboard can be recorded without sending it again.
- Status moves follow the order. Paid, Refunded, Failed, and Disputed are set by payments and refunds only, and a paid order cannot be cancelled until it is refunded.
- Each order line stores what it was charged: price before tax, discount, tax per rate, and its share of shipping, adding up to the order total to the cent.
- Print a packing slip for the whole order or one shipment.
Customers
Activating Shop adds a Customer role with no admin access. It appears in New User Default Role, user invites, and the user editor, and disappears again when Shop is deactivated. A user can hold it as their main role or as an additional role (see Users and roles).
- Add (Commerce → Customers → Add customer): sign-in email, name, phone, company, tax ID, invoice address, and shipping address. A new email creates a user with the Customer role. An email that already signs in is linked and given the Customer role; their password and main role stay the same.
- Edit: open a customer to change their details. The sign-in address stays on the user account.
- Import (Commerce → Customers → Import): CSV, JSON, or XML, including addresses. New emails create users; matching emails update the shop record and leave the sign-in alone. A 20-row sample ships as
samples/customers-20.csv. - Anyone given the Customer role from Admin → Users, an invite, or sign-up also appears in Commerce → Customers.
Payments
Commerce → Payments opens each method on its own page. Switch it on, enter the sandbox and/or live API key, and save. Secrets are stored in encrypted plugin secrets and never sent back to the browser; the page only says whether one is set.
Mollie only, for now
Mollie is the only payment method for now: the one that is fully integrated and tested. Stripe, PayPal, Adyen, Square, bank transfer, cash on delivery, check, and gateways from other plugins are hidden until they are; they cannot be set up or offered at checkout, and their webhook addresses answer 404. Payments already recorded for them can still be managed.
Mollie
On the Mollie page, choose Mollie checkout (one choice that opens Mollie's payment page) or the methods active on your Mollie profile (each its own choice that sends the customer straight to that method). Checkout offers one or the other, not both. Show payment method logos at checkout turns the icons on or off. Each Mollie payment includes the order lines with tax, billing and shipping addresses, the visitor's language, a cancel link, and the Justflows user, customer, and order ids in its metadata. The order stays Awaiting payment until Mollie reports it paid. Apple Pay is offered only in browsers that support it.
When a Mollie payment fails, is cancelled, or expires, the customer gets one Payment failed email with a {{payment_url}} link. It opens a Finish your payment page for the same order, where they can pay another way. Paid, cancelled, or refunded orders cannot be paid again from that link.
Capture, cancel, and refund
The Payments list shows every payment attempt. From an attempt you can capture an authorization (fully or partly), cancel an open authorization, or refund a captured amount (fully or partly). Each action carries an idempotency key, so a retry never charges or refunds twice. An action Mollie did not clearly confirm shows as waiting and is sent again for up to 45 minutes; after that, staff check Mollie's dashboard and choose It went through or It did not go through. A background job every five minutes releases expired stock holds, retries failed payment notifications, and asks Mollie about payments whose webhook never arrived.
Payment webhooks
Mollie needs nothing registered: Shop sends its notification URL with each payment and looks every notification up at Mollie with your API key before applying it. Each notification is stored once, so a duplicate, or a notification arriving together with the shopper's return, marks the order paid once, with one email and one stock commit. A notification that cannot be applied is answered with an error so Mollie sends it again. The token in the URL is random and created the first time you save the method; treat the whole URL as a secret. Webhook routes skip the session CSRF token and are limited to 60 requests a minute per IP.
https://<your-site>/api/shop/payments/hooks/<method>/<token>Shipping
- 1
Origin
The address you ship from.
- 2
Zones
Match by country, postcode, or the rest of the world. When several zones match, the most specific wins (postcode beats country, country beats rest of the world); ties go to the zone's priority.
- 3
Methods
Per zone: flat rate, free shipping, local pickup, or a carrier service (DHL Express / Parcel / eCommerce, DPD, PostNL).
- 4
Carriers
Enter the API key (and secret where needed), then Test connection. DHL Express returns live rates, PostNL returns delivery options, and DPD signs in and lists pickup points. In sandbox mode the carriers' test hosts are used, and PostNL also creates and reads back a confirmed shipment on its shipping sandbox.
PostNL and DPD do not return contract prices, so for those two the rate you set on the zone method is what the customer pays. Carrier keys are stored in plugin secrets and never sent back to the browser.
Shipping rates and tax: under Shop → Shipping zones, choose whether method rates are entered including or excluding tax. Including: the customer pays the rate as entered and the tax is taken out of it. Excluding: tax is added on top. Cart and checkout apply the choice. The tax class for shipping is set under Tax.
Live rates, labels, and tracking
- Live carrier rates. A carrier method can charge the carrier's live rate for the parcel's weight, plus an optional handling fee, and checkout shows the delivery estimate. The rate is kept for 15 minutes, so the order is placed at the price the shopper saw. Without a rate, or when an item has no weight, the method charges its fixed rate if you turned on the fallback, and is hidden otherwise. DHL Express gives live rates; PostNL and DPD do not publish prices.
- Carrier labels. When shipping an order, Make a carrier label asks the carrier for a label and tracking number, records the shipment, and keeps the PDF on the order. Works with PostNL (the Netherlands and Belgium) and DHL Express (within the EU). Shipping → Settings asks for the street, phone, and email you ship from.
- Tracking. Every hour Shop checks parcels with a PostNL or DHL Express tracking number. When every parcel is delivered, the order becomes Delivered and can email the customer. Check tracking now checks one shipment straight away.
- Each method on a zone can be edited or switched off for checkout without deleting it.
Tax
- Commerce → Tax: turn tax on, choose whether prices are entered including or excluding tax, and how they are shown in the catalog and at checkout. Shop warns when the combination would confuse customers.
- Calculate tax from the shipping, billing, or store address.
- Add tax classes (for example Standard, Reduced, Zero) and rates per country, optionally narrowed to a state, postcode, or city. Rates can be compound and have a priority.
- Shipping tax follows the cart items, a fixed class, or none. Round per line or on the subtotal, show one tax total or itemize it, and add a price suffix such as "incl. VAT".
{price_including_tax}and{price_excluding_tax}insert those amounts in the suffix. - Product pages,
{{price}}, and related products use the catalog display. Before a customer address is known, the rate comes from the store address. When the catalog shows prices excluding tax, the product page shows the net price large and the including-tax price small beside it.
Discounts
| Type | Example |
|---|---|
| Percentage | 10% off the cart |
| Fixed cart | €5 off the order |
| Fixed product | €2 off each matching product |
| Free shipping | |
| Buy X get Y | Buy 2, get 1 at 50% |
| Quantity tiers | 5+ items 10%, 10+ items 15% |
| Gift card / Store credit | A balance for one customer |
A discount is a code (generated or your own) or automatic. Limit it by minimum or maximum spend, total uses, uses per customer, products, categories, brands, customer emails or email domains, countries, first order only, and a start and end date. Under settings, choose how discounts combine (priority, combine, or exclusive) and whether they apply before or after tax.
Emails
Commerce → Emails has an editable template per message and language (English, Dutch, German, French, and Spanish ship built in). Switch a message on or off and edit its subject and body. Emails go out through the site's outgoing mail, and each sent message is listed in the log on this page.
| Message | To | Sent when |
|---|---|---|
| Order confirmed | Customer | An order is placed |
| New order | Store contact email | An order is placed |
| Payment received | Customer | A payment is captured (with the invoice PDF when invoices are issued on payment) |
| Payment failed | Customer | A Mollie payment fails, is cancelled, or expires (once per order) |
| Refund issued | Customer | A refund is recorded |
| Order shipped / delivered / cancelled | Customer | You move the order to that status and choose to email |
| Invoice | Customer | You choose Email to customer on the order |
| Subscription renewal to pay / on hold / cancelled | Customer | A manual renewal is due, a renewal failed for good, or a subscription ends |
| Low stock / Out of stock | Store | Not sent yet |
{{store_name}} {{customer_name}} {{order_number}} {{order_total}} {{order_url}}
{{payment_url}} {{tracking_number}} {{tracking_url}} {{refund_amount}} {{reason}}
{{product_name}} {{sku}} {{stock}} {{threshold}}A message the mail server refuses is tried again after 5 minutes, 15 minutes, 1, 3, and 12 hours. Undelivered emails show under Not delivered on Commerce → Emails and on the order, with the error and Send again.
Invoices and credit notes
Commerce → Invoices issues invoices by hand from the order page or automatically when an order is fully paid (off by default). Invoices show the seller with VAT and company numbers, the buyer, every line with its tax rate, a tax summary per rate, shipping, and totals, in the order's language. Numbers come from a prefix with an optional year (INV-{YYYY}-00001) and run on without gaps. A refund on an invoiced order gets a credit note. Issued documents never change.
- Download invoices, credit notes, and packing slips as PDF from the order page, the customer's order page, and the preview.
- The design sets the logo, accent colour, font, paper size (A4 or Letter), which details show, and a note, with a live preview in any of the site's languages.
- Payment received carries the invoice PDF, Refund issued the credit note, and Email to customer sends the invoice on its own.
Reports
Commerce → Reports shows sales for any period up to a year: total charged, net sales, discounts, shipping, tax, refunds, average order, sales per day, top products, payment methods, and discount codes, in the store time zone. It also has:
- Tax per rate, which agrees with the invoices and credit notes, with Export tax (CSV).
- Inventory: stock value at cost and at regular price, units on hand, and low, out-of-stock, and dead-stock items, with Export inventory (CSV).
- Export orders (CSV), and on Commerce → Refunds every refund in a period split into goods, tax, and shipping, with Export refunds (CSV).
Subscriptions
Any product can be sold as a subscription. Its Subscription section sets how often it is billed, how many payments it runs for, a free trial, and a sign-up fee. Each renewal is an ordinary order at the price, tax, and shipping frozen at sign-up, with its own invoice and emails.
- Automatic renewals with Mollie. The first payment saves the customer's card, PayPal, or SEPA Direct Debit mandate, and renewals are charged without the customer. A failed charge is retried after 1, 3, and 5 days, then the subscription goes on hold and the customer gets a link to pay.
- Renewals paid by hand can be offered for methods that cannot be charged again: each renewal is emailed as a payment link.
- Commerce → Subscriptions lists subscriptions by status and can cancel, pause, resume, or give a plan without a checkout (complimentary, or paid from the next period).
- Plans. A plan group makes plans replace each other (starting Pro ends Free), and a default plan goes to every new customer, and on a platform to every new workspace.
- Resources and limits. A plan can give platform limits (users, storage, sites, feature switches), membership roles, custom limits, and a site: Create a site at checkout creates the customer's workspace and keeps it suspended until the first payment. They are taken back when the subscription ends.
- Customers see and manage their subscriptions on their account page, and get emails when a renewal is due, put on hold, or cancelled.
Downloadable products
A downloadable product's Downloads section takes files up to 512 MB each, with an optional download limit and link expiry. Files go to the site's private storage, never the public media library. A paid order gives the buyer one link per file on their order page. Links stop after their limit or expiry, on a refund or cancellation, or when the file is removed; resuming a download does not count again.
Customer account and order tracking
- Signed-in customers see their orders, invoices, downloads, and subscriptions on the site's account page and at
/shop/customer-account, and can change their name, phone, and addresses for the next checkout. /shop/order-trackingopens one order with its order number and email, limited to 10 look-ups a minute. Links in order emails open the order without signing in.
Backups
Shop Settings → Backups makes a backup of every Shop record of the site (orders, customers, payments, refunds, stock, coupons, invoices, subscriptions, and the rest) as one file in the site's private storage. Backups can be downloaded, uploaded again (up to 512 MB), checked against the shop table by table, and restored into an empty shop in one step, or nothing is kept. A backup made on PostgreSQL restores on MySQL or MariaDB and the other way round. Schedule makes one every day or week and keeps the newest (7 by default). Shop database moves Shop's records between the Justflows database and a separate PostgreSQL, MySQL, or MariaDB database, checking every table before it switches. Settings, credentials, and product pages are part of the site's own backup.
Staff access
Shop registers user capabilities in groups. Custom roles and per-user grants can hand out any of them (see Users and roles).
| Group | Capabilities | Editors by default |
|---|---|---|
| Shop | shop:settings, shop:reports | Reports |
| Products | products:read|create|update|delete|publish | All except delete |
| Inventory | inventory:read, inventory:adjust | Read |
| Orders | orders:read|create|update | Read, update |
| Payments | payments:read|capture|refund | Read |
| Fulfillments / Returns | fulfillments:read|manage, returns:read|manage | None |
| Customers | customers:read|manage | Read |
| Discounts / Tax / Shipping | discounts:read|manage, tax:read|manage, shipping:read|manage | Read |
| Subscriptions | subscriptions:read, subscriptions:manage | None |
Administrators have every capability. Deleting products, adjusting stock, capturing and refunding payments, and managing customers, discounts, tax, and shipping stay with administrators unless you grant them.
Static exports and diagnostics
- Static export: Shop lists its cart, checkout, order confirmation, customer account, and order tracking pages, in every active language, through the
staticExport.excludefilter. A static export skips them and the generated web-server config sends them to the live app. Catalog and product pages still export. - Diagnostics: Admin → System → Diagnostics shows whether Shop setup is complete and whether each enabled payment gateway has credentials for the current mode (names only, never values). A gateway the provider rejects shows on the overview. Errors Shop logs appear under Recent errors as
plugin:justflows.shop. - Theme and URLs: while active, Shop adds customizer layout widths and default permalink bases for Product (
/product) and Shop (/shop).
Extend Shop from another plugin
Another plugin can add payment gateways and shipping carriers with two filters. Register them in activate(); they disappear when that plugin is deactivated.
ctx.hooks.filter("justflows.shop.payments.gateways", (gateways) => [
...gateways,
{
id: "acme-pay",
name: "Acme Pay",
manual: false,
managed: false,
capabilities: ["intent", "capture", "refund", "webhooks", "sandbox"],
fields: [
{ id: "publicKey", label: "Public key", secret: false },
{ id: "secretKey", label: "Secret key", secret: true },
],
},
]);
ctx.hooks.filter("justflows.shop.shipping.carriers", (carriers) => [
...carriers,
{
id: "acme-post",
name: "Acme Post",
origins: ["NL", "BE"],
services: [{ id: "standard", label: "Acme Standard" }],
capabilities: ["rates", "tracking"],
},
]);| Field | Rules |
|---|---|
id | Lower-kebab (acme-pay). Duplicates are dropped. |
name | Required, up to 80 characters. |
manual (gateway) | true for offline methods such as bank transfer. Manual gateways may not have secret fields. |
managed (gateway) | true for a managed account from a companion plugin, such as Justflows Payments. |
capabilities (gateway) | Any of intent, confirm, authorize, capture, partial_capture, void, refund, partial_refund, webhooks, reconcile, tokenize, pending, disputes, fees, sandbox. |
fields (gateway) | Settings shown on the Payments page. secret: true values go to plugin secrets and are never sent to the browser. |
origins (carrier) | ISO country codes the carrier collects from. Empty means any origin. |
capabilities (carrier) | Any of rates, labels, tracking, pickup, returns, customs, address. |
Filter rules
Append, don't replace. The list you return replaces Shop's list, so dropping entries hides the built-in gateways or carriers. Invalid entries are dropped silently. Shop only calls the APIs of its built-in providers; calling your provider is your plugin's job.
Products are ordinary content, so core webhooks already notify other systems when a product is created, updated, published, unpublished, or deleted. Act only on events where data.type is product. Shop also sends its own versioned events through core webhooks, with HMAC signatures, retries, and delivery history: justflows.shop.order.created, .paid, .payment_failed, .cancelled, .refunded, .shipped, and .delivered; justflows.shop.subscription.started, .renewed, .payment_failed, .updated, and .ended; and justflows.shop.stock.low. Payload types are exported from justflows.shop/contracts.
More filters let other plugins add commerce features: justflows.shop.tax.providers (tax rates per address from an outside service; checkout stops instead of charging the wrong tax when it does not answer), justflows.shop.discounts.promotions (promotions applied like Shop's own discounts), and justflows.shop.catalog.product_types (types such as tickets or bookings, with an optional check before an item can be bought). Carrier adapters can supply rates, createLabel, and track, and justflows.shop.subscriptions.entitlements reports when a plan's resources are given or taken back.
HTTP routes
Shop's routes are under /api/shop/ (the older /ext/justflows.shop/ addresses keep working). Each checks the session and a Shop capability, except the public catalog and the payment webhooks. Shop API v1 at /api/shop/v1 adds explicit catalog, cart, checkout, customer, and staff operations with one JSON error format, cursor lists, and mutation keys; GET /api/shop/v1/openapi.json describes it in OpenAPI 3.1.
| Area | Routes |
|---|---|
| Setup | setup |
| Catalog | catalog, catalog/:contentId, attributes[/:id], categories[/:id], tags[/:id], products/import, products/bulk (POST) |
| Inventory | inventory, inventory/settings |
| Orders | orders, orders/:id, POST orders/:id/status |
| Customers | customers, customers/:id, customers/import |
| Emails | emails, emails/:key |
| Tax | tax, tax/settings, tax/classes[/:id], tax/rates[/:id] |
| Discounts | discounts, discounts/settings, discounts/:id |
| Shipping | shipping, shipping/origin, shipping/carriers/:id[/test], shipping/zones[/:id], shipping/zones/:id/methods, shipping/methods/:id |
| Payments | payments, payments/gateways/:id[/methods|/test], payments/attempts/:id/{capture,void,refund}, payments/hooks/:gateway/:token (public, signed) |
| Storefront | storefront (public catalog), storefront/settings, blocks/options/{products,categories,tags} |
Uninstalling
By default, removing Shop drops its shop_* tables (orders, customers, payments, and the rest) and deletes the Shop and Product content. To keep them, turn off Delete shop data when this plugin is removed and Delete shop pages and posts when this plugin is removed in Shop's settings before you remove the plugin. Deactivating alone deletes nothing.
Known limits
- Mollie is the only payment method. Other gateways are hidden until they are integrated and tested.
- Returns and exchanges (return requests and return labels) are not available.
- Low stock and Out of stock emails can be edited but are not sent yet.
- Subscriptions cannot be upgraded, downgraded, or prorated, a checkout holds one subscription and nothing else, and no reminder is sent before a renewal.
- Downloads have no per-variation files, and Reports have no customer or subscription figures.
- A database move leaves the old copy of the records in place.
- The admin screens are translated into English, Dutch, German, French, and Spanish only.
Tip
Found a bug or missing something you need? Open an issue on the Justflows GitHub and mention the Shop plugin and your Justflows version.