# Commerce-Setup Forms

> A functional description of the forms an admin uses to set up the commercial side of the shop — customer segmentation & discounts, currencies, taxes, geograp…

Source: CBX documentation, version 3.x (released). Canonical page: https://docs.configbox.at/docs/functional/commerce_setup. Last updated 2026-08-01.

---
A **functional** description of the forms an admin uses to set up the commercial side of the shop —
customer segmentation & discounts, currencies, taxes, geography, shipping and payment. Usage-centric
(a behavior spec for the refactor), not implementation. For *how* these are stored/processed, see the
technical docs.

These forms define **who pays what, how, where it ships, and how it's taxed**. They feed the cart and
checkout: the customer's **group** drives pricing/discounts/tax-mode and feature access; their
**country** (→ zone) drives shipping and payment availability; the applicable **tax class** + their
**place** (country/state/county/city) drives the tax rate; the chosen **currency** converts all
amounts.

Forms covered:
1. Customer Groups
2. Currencies
3. Tax Classes
4. Geography — Countries, States, Counties, Cities
5. Zones
6. Shippers
7. Shipping Methods
8. Payment Methods
9. Salutations

---

## 1. Customer Groups

The central segmentation entity. A customer belongs to one group (the default group applies to
guests/ungrouped customers — set in Configuration). The group controls pricing mode, feature access
and volume discounts.

### General
- **Name** — the group's name.
- **Platform Group** (`joomla_user_group_id`) — the host CMS user group this maps to. Affects which
  logged-in users fall into this CBX group.
- **Tax display mode** (`b2b_mode`) — **B2C** (gross/tax-inclusive pricing) or **B2B** (net/ex-tax
  pricing). Affects how prices are shown and totalled throughout the configurator, cart and checkout.

### Permissions (feature access for this group)
- **Enable price display in configurator and cart** — whether this group sees prices at all (e.g. a
  "request quote only" group can hide them).
- **Enable checkout** — whether this group can place real orders.
- **Enable Save Order** — whether this group can save a cart for later.
- **Enable Quotation Request** — whether this group can request a quote (the RFQ flow) instead of
  buying.
- **Automated quotation download** — whether a requested quote is offered as an immediate PDF
  download.
- **Quote PDF attachment in notification** — whether the quote PDF is emailed with the notification.

Together these gate the buy-vs-quote experience per segment (e.g. consumers buy; trade customers
request quotes; some groups only browse).

### Discount Levels — Regular and Recurring (5 tiers each)
Two parallel sets of **five volume-discount tiers**, one for regular pricing and one for recurring
pricing. Each tier has:
- **For net order totals starting at** — the threshold (net total) at which the tier applies.
- **Discount Type** — **Percentage** or **Amount**.
- **Discount Amount** *or* **Discount Percentage** — the value (used per the chosen type).
- **Title** — a label shown for the discount.

Effect: automatic volume discounts applied in the cart based on the net order total for that group
(the highest qualifying tier applies). Regular and recurring carts are discounted independently.

---

## 2. Currencies

The currencies the shop offers.

- **Title** — the currency name.
- **Multiplicator** — the exchange factor relative to the **base** currency. Affects converted
  prices in every non-base currency.
- **Currency Symbol** / **Currency Code** — display symbol (e.g. €) and ISO code (e.g. EUR).
- **Default** — the currency shown to customers by default.
- **Base Currency** — the currency that prices are *entered* in (the reference for multiplicators).
- **Active** — whether customers can select it.
- **Actions:** *Make Default*, *Make Base* — promote a currency to default/base.

> **Base vs. Default:** *Base* is the authoring currency (all entered prices are in it; multiplicators
> convert from it); *Default* is the one a visitor sees first. A refactor should keep this distinction
> explicit.

How a displayed amount comes about:

```mermaid
flowchart LR
    E["Price entered in the base currency"] --> M["multiplied by the currency's multiplicator"] --> D["Amount shown in the customer's selected currency"]
```

---

## 3. Tax Classes

Named tax-rate buckets that products, shipping and payment surcharges reference.

- **Name** — the tax class name (e.g. "Standard", "Reduced").
- **Default Tax** (`default_tax_rate`) — the fallback rate used when no place-specific override exists.
- **External ID** — an identifier for integration with external systems.

> Tax classes carry only a **default** rate here; place-specific rates are overridden on the Geography
> forms (§4). The effective rate is resolved by the most specific matching place.

---

## 4. Geography — Countries, States, Counties, Cities

A four-level location hierarchy used for **address selection, shipping zones, and place-based tax
overrides**. Each level can override any tax class's rate for that place (the **Tax Override**
section, `tax_class_rates`), giving a resolution chain:

> **Tax rate resolution (most specific wins):** City → County → State → Country → the tax class's
> default rate.

```mermaid
flowchart TD
    S["Line's tax class + customer's place"] --> C1{"City override set?"}
    C1 -- "yes" --> R1["Use city rate"]
    C1 -- "no" --> C2{"County override set?"}
    C2 -- "yes" --> R2["Use county rate"]
    C2 -- "no" --> C3{"State override set?"}
    C3 -- "yes" --> R3["Use state rate"]
    C3 -- "no" --> C4{"Country override set?"}
    C4 -- "yes" --> R4["Use country rate"]
    C4 -- "no" --> R5["Use the tax class's default rate"]
```

### Country
- **Country Name**, **Country 2 Code** / **Country 3 Code** (ISO codes).
- **Zones** — which shipping zones this country belongs to (M:N). Affects shipping-method availability.
- **VAT free** — orders to this country are exempt from VAT. Affects tax calculation.
- **In EU VAT area** — marks the country as part of the EU VAT area. Affects EU VAT / VAT-ID (VIES)
  handling (e.g. reverse-charge for valid B2B VAT IDs).
- **Tax Override** — per-tax-class rate overrides for this country.
- **Custom Fields** (4 + 2 translatable), **Ordering**, **Active**.

### State
- **Name**, **State code** (ISO), **FIPS Number**, parent **Country**.
- **Tax Override** (per-tax-class rates at state level), **Custom Fields** (4), **Ordering**, **Active**.

### County
- **Name**, parent **State**, **Tax Override** (county-level rates), **Custom Fields** (4),
  **Ordering**, **Active**.

### City
- **Name**, parent **County**, **Tax Override** (city-level rates), **Custom Fields** (4),
  **Ordering**, **Active**.

The address form's country→state→county→city cascade is driven by these records; only the levels you
populate appear. Most shops only use Country (and maybe State).

---

## 5. Zones

Groupings of countries used to scope shipping methods.

- **Name** (`label`) — the zone name (e.g. "EU", "Domestic", "Rest of World").
- **Countries** — the member countries.

Effect: shipping methods are offered per zone, so a customer's country → its zone(s) → the matching
shipping methods.

---

## 6. Shippers

The carrier master list.

- **Title** — the carrier name (e.g. "DHL", "UPS").
- **Active** — whether it's available.

Shippers are referenced by shipping methods; functionally just a label/grouping for carriers.

---

## 7. Shipping Methods

Concrete delivery options, priced by weight within a zone.

- **Title** — the option name shown at checkout.
- **Shipper** — the carrier this method uses.
- **Zone** — the geographic zone it serves (via the customer's country).
- **Minimum Weight** / **Maximum Weight** — the cart-weight band this method applies to.
- **Delivery Time** — a delivery-time description shown to the customer.
- **Price** — the shipping cost.
- **Tax Class** — the tax applied to the shipping cost.
- **External ID** — integration identifier.
- **Active**, **Ordering**.

Effect at checkout: the customer's country resolves to zone(s), the cart's total weight selects the
weight band, and the matching method's price + delivery time are offered. (Shipping can be globally
disabled in Configuration.)

```mermaid
flowchart LR
    C["Customer's country"] --> Z["Zone"]
    W["Cart's total weight"] --> B["Weight band"]
    Z --> M["Eligible shipping methods"]
    B --> M
    M --> O["Chosen method's price + delivery time at checkout"]
```

---

## 8. Payment Methods

The ways customers can pay, with surcharges and availability rules.

- **Title** — the payment option name shown at checkout.
- **Payment service provider** (`connector_name`) — which PSP connector handles it (PayPal, Stripe,
  bank transfer, cash on delivery, etc.).
- **Params** — connector-specific configuration (credentials/options for the chosen PSP).
- **Active** — whether it's offered.
- **Static extra charge** + **Extra charge percentage** — the surcharge: a fixed amount plus a
  percentage of the order.
- **Minimum Extra Charge** / **Maximum Extra Charge** — clamp the computed surcharge to a range.
- **Tax Class** — tax applied to the surcharge.
- **Customer Groups** (`customer_group_ids`) — restrict the method to certain groups.
- **Countries** (`country_ids`) — restrict the method to certain countries.
- **Description**, **Ordering**.

Effect at checkout: only methods valid for the customer's group **and** country are offered; the
selected method's surcharge (clamped to min/max) is added and taxed per its tax class.

---

## 9. Salutations

The salutation options used in customer/address forms.

- **Title** — the salutation text (e.g. "Mr", "Mrs", "Dr").
- **Gender** — **Unspecified / Male / Female**, for gendered communications.

Whether the salutation field appears (and is required) per flow is controlled on the **Customer
Fields** screen (see the configuration doc).

---

## 10. How commerce setup combines (at the cart/checkout)

1. **Group** (from the logged-in user's platform group, or the default) sets **B2B/B2C** pricing
   mode, **feature access** (buy vs. quote, see-prices, save), and **volume discounts**.
2. **Currency** converts all displayed amounts from the base currency via its multiplicator.
3. **Tax** for each line is the line's **tax class** rate, resolved by the customer's **place**
   (city→county→state→country→default), with **VAT-free** / **EU VAT-area** rules applied.
4. **Shipping**: the customer's **country → zone(s)**, plus the cart's **weight**, select the eligible
   **shipping methods** (each tied to a **shipper**); the chosen one's price + tax apply (unless
   shipping is disabled globally).
5. **Payment**: methods valid for the customer's **group** and **country** are offered; the selected
   **PSP connector** processes payment and its **surcharge** (clamped, taxed) is added.

All five inputs at a glance:

```mermaid
flowchart TD
    CU["Customer"] --> G["Group"]
    CU --> CUR["Currency"]
    CU --> PL["Place"]
    CU --> CO["Country"]
    G --> P1["B2B/B2C mode, feature access, volume discounts"]
    CUR --> P2["Amounts converted from the base currency"]
    PL --> P3["Tax rate per line, most specific place wins"]
    CO --> Z["Zone"] --> P4["Eligible shipping methods, by cart weight"]
    G --> P5["Eligible payment methods"]
    CO --> P5
    P5 --> P6["Surcharge, clamped and taxed"]
```

---

## 11. Notes for the refactor (functional observations)

- **Group is the policy hub.** Tax mode, feature flags and discounts all hang off Customer Group;
  Configuration only picks the *default* group. A refactor should keep commerce policy group-scoped and
  model the "permissions" as explicit capability flags.
- **Five hard-coded discount tiers × regular/recurring** is a repeating-group smell. Functionally it's
  "volume discount tiers"; model it as a list of tiers, not 5×(threshold/type/amount/percentage/title)
  duplicated for recurring.
- **Place-based tax overrides form a 4-level hierarchy** (country→state→county→city) with
  most-specific-wins resolution, plus VAT-free / EU-VAT-area special cases. This is real tax logic to
  preserve; consider an explicit tax-resolution service.
- **Shipping is weight-band × zone**, payment is **surcharge + group/country availability**. Both are
  simple rule sets that a refactor could unify as "availability + pricing rules" rather than bespoke
  forms.
- **Currency base-vs-default** and **multiplicator-based conversion** are intentional; a refactor may
  want live FX rates but must preserve the base-authoring model.
- **Geography custom fields** (4 + translatable on country) mirror the custom-field pattern seen
  elsewhere — candidates for typed custom attributes.
- **PSP connectors are pluggable** (connector_name + params); the technical extension pattern is
  documented separately, but functionally the set of available providers is data-driven.
