Guide 08 · Developer docs

Commerce

A Core dna store is a set of records and an API that moves a purchase from cart to order: products described in every language and priced in every currency the store sells in, a cart, a checkout that becomes an order, invoices, payments, tax and shipping. The site builds the storefront on top: the cart and checkout pages, their scripts, and the customer emails.

L2–L3
Unit 07 · Selling to businesses

Group pricing and approval before ordering

Prices for a group of customers are a discount with a person-group condition. How to set one up, how it combines with a sale, how to show trade prices while browsing, and two patterns for an approver before a business customer orders.

Who this is for. Developers and solution architects building a store for trade or business customers. After this page you can give a group of customers their own prices, decide how those prices combine with other discounts, and choose the approval pattern that suits the client.

Prices for a group of customers

A product has one price per currency (Prices and currencies). Prices for a group of customers are a discount with a person-group condition: put the trade customers in a group, and give a discount a rule whose condition allows that group. The condition checks the groups of the signed-in member. A member in an allowed group gets the discount; everyone else, guests included, pays the catalogue price. A condition can also forbid a list of groups, to keep a discount away from them.

The discount's action sets the amount. An action covers all the items in the cart or chosen products, and takes off a percentage or a fixed amount:

AmountTakes offCurrencies
PercentageA share of the price, from 0 to 100Every currency: one action covers them all
Fixed amountA set amount of moneyThe action's own currency, or the site's default currency when it has none. A store that sells in several currencies gives the discount one fixed-amount action per currency.

For a customer with prices of its own, give that customer's people a group of their own and the group its own discount. A price agreed for one order goes on a quote instead: a quote is priced before discounts, and staff enter the agreed prices on it (The life of a quote).

How a group discount combines with others

Every discount whose rules match the order applies. Discounts are taken in position order, and two flags decide how they combine:

  • Final, on a discount or on one of its rules: a discount or rule marked final stops any discount after it from applying.
  • Waterfall, on each action, on by default: on, the action takes its amount from the price the discounts before it left; off, it works from the item's original price.

To keep a trade price from combining with a storewide sale, give the group discount a position before the sale and mark it final. Where the two should combine, set the trade action's waterfall on purpose: after a 20% sale, a 10% trade discount with waterfall on takes 10% of the sale price, 28% off in all; with waterfall off it takes 10% of the original price, 30% off in all. How discounts and codes show at checkout is on Discounts at checkout.

Showing trade prices while browsing

Product pages and listings show the catalogue price: a discount is worked out in the cart and the checkout, and a product's price stays as entered. To show trade customers their price while they browse, calculate it in the template from the same numbers, the catalogue price less the group discount's percentage, for a signed-in member of the trade group. When the discount changes, change the figure the template uses with it, so the product page and the cart show the same price.

A public page is cached and served to every visitor, so print the trade price in an uncached fragment, the way a cached page shows who is signed in (Show logged-in state on a cached page).

Test as three customers

Before launch, with a sale running, put the same items in the cart signed in as a member of the trade group, as a member outside it and as a guest, and compare the three totals with the prices the client agreed.

Approval before ordering

Two patterns put an approver between a buyer and an order. Choose by how the customer's organisation approves a purchase.

The quote as the approval step

For a small team, where "sales reviews it" is the whole process. The buyer requests a quote from the cart; your sales team reviews it in the admin and sets the prices and an expiry date; the buyer orders it from their quote page. Setting the expiry date is the approval: wrap the quote page's "Order at this price" form in the same test as its "Valid until" line, {if $quote->getExpiryDate()} (Twig {% if quote.getExpiryDate() %}), so the button appears once staff have priced the quote, and a quote with an expiry date that has not passed is an approved request (The member's quote screens). A job on the quote's Update record event tells the buyer it is ready (Telling people about a quote).

A custom entity for the purchase request

For an organisation with an approval chain: more than one approver, spending limits, or approval by someone other than the buyer. The request is a custom entity record with a status, the buyer, the approver and the limit it is checked against:

  1. The buyer's cart creates a purchase-request record from its contents (Custom entities over the API and MCP).
  2. Approvers, members of the right group, see the requests waiting for them on a member screen that queries the records (Querying records from a template), and approve them.
  3. A job on the record's Update record event turns an approved request into a quote or a checkout for the buyer (Entity events).

It takes more to build than the quote pattern, and it carries the rules the organisation has.

Which pattern suits which client

The quote as the approval stepA custom entity for the request
SuitsA small team: one buyer, and your sales team approvesAn organisation with several approvers, limits or steps
Who approvesYour staff, in the adminThe customer's own people, on the website
What to buildThe two quote screensA custom entity, screens for buyers and approvers, and a job

Other B2B requirements, from purchase-order numbers to company accounts, are on Building B2B features with custom entities and jobs.

Go deeper

Was this page helpful?

Your answer goes to the docs team.