Prices and Discounts
Hyvä POS is in closed beta
Hyvä POS is currently in a closed beta (pilot phase) with a small group of merchants. It is not yet generally available: the App Store release follows the pilot, and features and configuration may still change, possibly in backwards-incompatible ways, before the general release. Want to take part? Sign up at hyva.io/pos.
A customer puts three vases on the counter, mentions a code from the newsletter, and hands over a wholesale account card. Online, Magento prices that cart in one pass: the catalog price, the special price, the tier price for three, the wholesale group's price, the catalog promotion, then the coupon. The register applies the same layers on the device, from the same Magento data, so the price at the counter matches the price in the webshop.
This page explains how a line gets its price at the register and how discounts are calculated and booked. It is written for merchants and store managers. The page on what the register supports lists every Magento rule setting and condition and states which ones apply at the counter.
The register does not create a Magento cart to price a sale. It reads prices, tier prices and promotion rules from Magento and evaluates them on the device. This keeps the counter responsive, allows PRO registers to price offline, and avoids abandoned carts in Magento that were never real shopping carts. Line items in the synchronised order follow Magento's conventions and match the receipt line for line, which also means your Magento reporting stays correct.
How a Line Gets Its Price
When a product is added to the cart, the register takes the lowest applicable price from the following sources, which is how Magento prices a product:
- The catalog price: the product's regular price in the store view the register sells in. Base currency is a website setting in Magento, so a register on a second website with its own currency sells in that currency. See Store Views and Currency.
- The special price: applied when today falls in its date window. The date is checked when the line is added, and the line keeps that price while the cart is open, even if the window closes in the meantime. A quantity change re-checks the date.
- Tier prices: quantity breaks per customer group, from the product's tier prices. At six units the six-unit price applies. A walk-in sale uses the walk-in group's tiers and the tiers for all groups: NOT LOGGED IN, or on PRO the group set under Walk-in Customer Defaults; a sale with a customer attached uses that customer's group. Percentage tiers and fixed tiers both work. Tier prices are part of the catalog the register holds locally, so they apply offline too.
- Customer group prices: when a customer is attached, every line is re-priced for that customer's group. No POS-specific configuration is needed; the Magento customer groups used online apply at the register.
- Customer-specific prices (PRO): contract prices, negotiated rates, an ERP price list. A pricing resolver in Magento returns the prices this customer pays for a set of SKUs, and the register shows the catalog price struck through with the customer price beside it. The source of the prices is up to your integration; see customer pricing resolvers in the developer docs. Stores → Configuration → Hyvä POS → Terminal Defaults → Customer Prices decides when the register requests them: when a product is added to the cart, or while browsing, so that the product tiles already show the customer's prices. The browsing option sends one request per catalog page the cashier views; if the resolver calls an external system such as an ERP, this might negatively impact performance. Customer-specific prices require a connection. The receipt names the source of the price.
- Catalog price rules: an active catalog price rule is applied when the line is added. The register requests the product's current price from Magento and applies the rule's reduction, so a 20% catalog rule on a 75.00 product gives 60.00, in either tax display mode.
The lowest of these is the line price. A fixed product tax is not part of the line price. It is a fee per unit that Magento adds beside the goods, and no coupon, cart price rule or cashier discount reduces it. The regular catalog price is stored with the line: the receipt shows the original and the discounted price, and the Magento order carries the original price per line.
Catalog price rules at the register
The product tiles show the catalog price until the product is added; the rule price appears on the cart line. The live price request is made for a walk-in customer, so a catalog rule limited to one customer group applies for an attached customer on PRO when Customer Prices fetching is on (see Known Differences); the free tier prices as for a visitor. A PRO register with a walk-in customer group set prices a walk-in sale under that group from its cached catalog rule prices. Offline, a PRO register prices from its cached catalog, which holds the catalog price, the special price, the tier prices and the day's catalog rule prices.
Prices in an open cart are re-checked against the catalog when they are older than five minutes, and whenever a parked cart is recalled, so a price change in Magento reaches carts that stay open for longer.
Cart Price Rules
Magento's cart price rules are the promotions that act on the whole cart: a coupon code, an automatic "10% off from 100.00", a buy-five-get-one-free. The register reads the rules from the store and evaluates them against the cart with the same logic as Magento.
Coupons
The cashier types the code, or taps Browse to see the coupons that apply to this cart: the active ones for this store view, valid today, open to the attached customer's group (or to walk-in customers), whose conditions the cart meets.
When a code is applied, the register checks what Magento checks:
- the rule is active and today is inside its date window, on your store's calendar;
- the rule covers this website and the customer group on the sale;
- the code has not been used more often than its "Uses per Coupon" allows, and on PRO, with a customer attached, not more often than its "Uses per Customer" allows;
- the cart meets the rule's conditions, and at least one line matches the rule's actions.
A code that fails one of these checks is refused with the reason: "Cart does not meet the conditions for this coupon", "This coupon has already been used the maximum number of times", "This coupon is not available to this customer group". A code expires with its rule's end date, the same as in Magento.
An applied coupon stays on the cart and is recalculated on every change, offline as well on PRO. When the qualifying line is removed, the coupon is removed too.
Automatic rules
A rule without a code applies automatically in the webshop. At the register it is suggested rather than applied automatically: the Discounts panel shows the qualifying rule and its discount, and the cashier confirms it. This keeps every discount on a receipt explainable at the counter. Once confirmed, the rule stays on the cart and is recalculated on every change, like a coupon.
How the discount is calculated
Rules are applied in the order Magento applies them, each on the amount the earlier rules left:
- Priority. Rules apply in their priority order, the coupon and the confirmed automatic rules together in one pass. A percentage rule after a fixed amount takes its percentage of the remainder.
- Discard subsequent rules. A rule with that flag ends the pass for the lines it applied to. A 10% rule marked this way that covers one product leaves nothing for a 20% coupon on that product; the coupon still applies to the other lines.
- Maximum Qty Discount is Applied To. Caps the units each rule discounts on a line: 10% capped at two units on a line of three discounts two.
- The four actions work as in Magento: a percentage of the line, a fixed amount per unit (never more than the line), a fixed amount on the cart spread over the matching lines, and buy X get Y counted per line: every full group of X+Y units on a line frees Y of that line's units, so three different products at one unit each earn nothing from "buy 2 get 1".
- A line's discounts never exceed its row.
- The tax basis follows your store. Discounts are computed on prices including tax or excluding tax as your Apply Discount On Prices tax setting says, then applied the way Magento's tax calculation applies them: on a catalog with prices including tax the amount comes off the price including tax and the tax it contained is booked as discount tax compensation; on a catalog with prices excluding tax it comes off the price excluding tax. This is why, on a tax-inclusive catalog with Apply Discount On Prices set to Excluding Tax, a 10% discount on a €121.00 line is €10.00 (10% of the €100.00 net) and the customer pays €111.00, as in the webshop. Magento recommends Including Tax for tax-inclusive catalogs, where the same discount is €12.10 and the customer pays €108.90. Apply Customer Tax before or after the discount is followed as well. Totals and promotion reports match the webshop under each combination.
Where the numbers land
Every discount is booked on the Magento order per line, as Magento books it: the discount amount, the discount tax compensation, the coupon code, the ids of the rules that applied and their labels for the store view (or the rule's name when it has no label). Promotion reports, the coupon report and accounting exports treat a register sale like a webshop sale. The receipt itemises the same figures.
What the register cannot check
Some conditions are about things the counter does not know when the cart is built: the payment method, an Adobe Commerce customer segment, or a condition and discount type an extension adds to Magento. Conditions on the shipping method and the shipping address are read from the shipment when a sale ships, and a take-home sale does not meet them. Free shipping and a discount on the shipping charge apply to a sale that ships the way Magento's carriers apply them, and the cart's weight is read from the product cache on PRO. Each rule is checked once against what the register can evaluate, and a rule it cannot evaluate is reported as such:
- a coupon of that kind is refused with the reason and the note that it can be used online: "This coupon uses a condition on the payment method. It can be used online.";
- Browse lists such coupons under Online only, with the reason;
- an automatic rule of that kind appears in the Discounts panel as Not available at the register, with the reason.
A rule that applies but carries a setting the register does not check is applied, and the setting is listed under the coupon: a limit on uses per customer on the free tier (PRO reads the customer's usage from your store), or a product attribute this register has not cached. The full list is on what the register supports.
Cashier Discounts
- Line discounts: a fixed amount or a percentage on one line, for example for a damaged box.
- Cart discounts: a fixed amount or a percentage on the whole sale, with a required description that appears in the register report. This also covers one-off cases such as a paper voucher: enter the amount and a description.
A line with a cashier discount is left out of coupons and automatic rules: one discount per line. Both discounts are booked on the Magento order as discount amounts, per line. A cart discount, fixed or percentage, follows the same tax basis as a rule: where your store applies discounts to prices including tax, 10% off a €2,800.00 line is €280.00 and the total is €2,520.00, as a 10% cart price rule would give online.
PRO
With staff and roles, discount permissions are per role, so cashiers can be limited or excluded while managers discount freely.
Who Wins When They Overlap
Pricing is applied in this order: the effective unit price first (catalog, special, tier, group, customer-specific or catalog rule, whichever is lowest), then the cart price rules in their priority order, then the cashier's discounts. The receipt and the order itemise each layer. A cashier's cart discount takes only what the lines still have after the rules: where a rule has already discounted a line to its value, the cart discount books less than was entered, a fixed amount moves the rest to lines that still have room, and the register says so under the discount row. What a line still has is measured where the discount lands, which is the line's own price basis: on a line priced excluding tax the discounts come off the net, on a line priced including tax off the gross. A store that prices excluding tax but applies discounts to prices including tax therefore sees a 100.00 line with an 80.00 coupon take at most 20.00 more, not the 41.00 left of its 121.00 gross. A line can also come to zero on its own: a special price of 0, a tier row of 0, a customer-specific price of 0 or a catalog price rule that takes the whole amount off makes the product free, and the register sells it as a sale, with no tender to pick and an order with a grand total of 0 and its invoice in Magento. A price the register could not read is not a zero: when a figure is missing or unreadable the line keeps the price it already has.
Known Differences
Where the register's figures or behaviour differ from the webshop:
- Splitting a fixed cart amount over several lines. Both engines spread the amount in proportion to the lines, but Magento carries rounding remainders from line to line differently. Totals match; a single line's discount can differ by 0.01.
- Catalog rules per customer group apply for an attached customer on PRO only when Customer Prices fetching is on: the customer-price resolver returns the group's rule price. On the free tier, and on PRO with the fetching off, the register prices as for a visitor.
- Extensions. Conditions, actions and pricing that a third-party module adds to Magento (Amasty, Mageworx and others) are not evaluated by the register, because they are not part of Magento's rule model. Loyalty programmes, store credit and gift cards are the exception: they work through bridges, and a promotion extension can be connected the same way.