# Subscription Contracts

> **Platform contracts only.** No backend subscription engine.  
> ADR: [ADR-023](../architecture/adr/ADR-023.md)  
> Related: [pricing-catalog.md](pricing-catalog.md), [license-entitlement-contracts.md](license-entitlement-contracts.md), [payment-contracts.md](payment-contracts.md)  
> Contract version: `subscription.v1`

---

## 1. Ownership

| Concern | Owner |
| --- | --- |
| Subscription commercial lifecycle | Core Platform |
| Pricing binding | Pricing Catalog refs |
| License issuance | Core (license contracts) |
| Payment collection / PSP capture | Payment (when activated) |
| Accounting AR / contract | Accounting (opaque refs) |

Payment’s reserved `payment.future.subscriptions` is a **billing shell**, not ownership of platform Subscription aggregates.

---

## 2. Contracts

### 2.1 SubscriptionPlan

| Field | Type | Meaning |
| --- | --- | --- |
| `plan_code` | string | Stable code |
| `display_name` | string | |
| `bundle_code` | string | Business bundle definition |
| `bundle_version_code` | string | Pinned commercial version |
| `default_pricing_item_code` | string | Primary Pricing Catalog ref |
| `status` | enum | `draft` \| `active` \| `retired` |

### 2.2 Subscription

| Field | Type | Meaning |
| --- | --- | --- |
| `subscription_id` | uuid | Logical id |
| `tenant_id` | uuid | |
| `plan_code` | string | |
| `status` | SubscriptionStatus | |
| `period` | SubscriptionPeriod | Current period |
| `renewal_policy` | RenewalPolicy | |
| `cancellation_policy` | CancellationPolicy | |
| `grace_period` | GracePeriod | |
| `pricing_item_code` | string | Bound list price |
| `started_at` / `ended_at` | datetime? | |
| `ext` | object | Additive |

### 2.3 SubscriptionItem

| Field | Type | Meaning |
| --- | --- | --- |
| `subscription_id` | uuid | |
| `item_code` | string | Line identity |
| `kind` | enum | `bundle` \| `addon` \| `usage` |
| `pricing_item_code` | string | |
| `quantity` | int | Default 1 |
| `service_identifier` | string? | When item maps to a service |

### 2.4 SubscriptionLicense

| Field | Type | Meaning |
| --- | --- | --- |
| `license_id` | uuid | |
| `subscription_id` | uuid | |
| `tenant_id` | uuid | |
| `bundle_code` | string | |
| `status` | enum | `requested` \| `active` \| `suspended` \| `revoked` \| `expired` |
| `entitlement_grant_refs[]` | string[] | Opaque refs to entitlement grants |
| `valid_from` / `valid_to` | datetime? | |

### 2.5 SubscriptionStatus

`requested` | `trialing` | `active` | `past_due` | `grace` | `cancelled` | `expired` | `suspended`

### 2.6 SubscriptionPeriod

| Field | Meaning |
| --- | --- |
| `period_start` | Inclusive |
| `period_end` | Exclusive or inclusive per future policy doc |
| `billing_anchor` | Day/time anchor |

### 2.7 RenewalPolicy

| Field | Meaning |
| --- | --- |
| `mode` | `auto` \| `manual` \| `none` |
| `notice_days` | Pre-renewal notice |

### 2.8 CancellationPolicy

| Field | Meaning |
| --- | --- |
| `mode` | `end_of_period` \| `immediate` \| `admin_only` |
| `refund_policy_ref` | Opaque; Payment refunds are separate (14.6+ **not** in this wave) |

### 2.9 GracePeriod

| Field | Meaning |
| --- | --- |
| `days` | Length after past_due before suspend |
| `entitlements_during_grace` | `full` \| `read_only` \| `none` |

---

## 3. Invariants

1. Creating a Subscription MUST NOT by itself mutate Payment or Accounting databases — only emit activation/request events (see activation flow).
2. License is derived from an accepted Subscription; entitlements are derived from License.
3. Amounts come from Pricing Catalog (or enterprise quote process), not from bundle JSON.
