# Pricing Catalog Architecture

> **Documentation only.** No pricing engine, tax engine, or coupon service.  
> ADR: [ADR-023](../architecture/adr/ADR-023.md)  
> Contract version: `pricing-catalog.v1`

---

## 1. Purpose

The **Pricing Catalog** is the sole commercial source for sellable price definitions.  
**Business Bundles reference pricing; they never embed it.**

---

## 2. Supported commercial models (v1 documented)

| Model | `pricing_model` | Notes |
| --- | --- | --- |
| Monthly | `monthly` | Recurring calendar month |
| Yearly | `yearly` | Recurring year |
| Usage | `usage` | Metered; unit defined on item |
| Trial | `trial` | Time-boxed; converts via policy |
| Promotional | `promotional` | Time/window limited offer |
| Enterprise Quote | `enterprise_quote` | No public amount; sales-assisted |

---

## 3. Future-reserved (document fields only — no implementation)

| Concern | Reserved fields / notes |
| --- | --- |
| Regional pricing | `region_code`, `currency_override` |
| Taxes | `tax_class_code`, `tax_inclusive` |
| Coupons | `coupon_eligible`, external coupon service ref |
| Discounts | `discount_class_code` |
| Reseller pricing | `channel_code=reseller`, `partner_price_book_ref` |

Implementations MUST accept unknown additive fields.

---

## 4. Contracts

### 4.1 PricingCatalogItem

| Field | Type | Meaning |
| --- | --- | --- |
| `pricing_item_code` | string | Stable unique code |
| `display_name` | string | |
| `pricing_model` | enum | See §2 |
| `currency` | string | ISO-like code (e.g. `IRR`, `IRT`) — logical |
| `amount_minor` | int? | Null for `enterprise_quote` |
| `usage_unit` | string? | e.g. `sms`, `seat`, `order` |
| `trial_days` | int? | For `trial` |
| `promotional_window` | object? | `{ starts_at, ends_at }` |
| `region_code` | string? | Future |
| `tax_class_code` | string? | Future |
| `channel_code` | string? | `direct` \| `reseller` \| … (future) |
| `status` | enum | `draft` \| `active` \| `retired` |
| `ext` | object | Additive |

### 4.2 PricingCatalogVersion

Optional catalog publication version for admin change control (logical).

| Field | Meaning |
| --- | --- |
| `catalog_version` | e.g. `2026.07` |
| `item_codes[]` | Included items |
| `published_at` | |

### 4.3 PriceBook (future)

Logical grouping for reseller / enterprise — **reserved**, not implemented.

---

## 5. Invariants

1. Bundle definitions store **only** `pricing_item_code` references.
2. Subscription items bind to `pricing_item_code` at request time (snapshot policy is a future implementation concern).
3. Payment may charge using Payment contracts; **list price truth** remains Pricing Catalog.
4. No frontend hardcoding of amounts as source of truth.

---

## 6. Example codes (illustrative — not live billing)

| Code | Model | Intent |
| --- | --- | --- |
| `price.restaurant.starter.monthly` | monthly | Starter restaurant |
| `price.restaurant.starter.yearly` | yearly | |
| `price.clinic.starter.monthly` | monthly | |
| `price.platform.trial.14d` | trial | 14-day trial |
| `price.enterprise.custom` | enterprise_quote | Custom |

Canonical human matrix: [business-bundles.md](business-bundles.md).
