[Traits](https://oods-foundry.com/traits) / SaaSBillingBillable

# SaaSBillingBillable

Normalizes recurring price configuration for SaaS plans including cadence, currency, and trial policy.

Generated from @oods/foundry 0.10.1

- Group

  domain

- Maturity

  beta

- Contexts

  card, list

NOTE (trait-split gap): this domain trait does NOT model proration — no supportProration/proration_amount/proration_date/prorationBehavior. A Subscription composing only SaaSBillingBillable silently cannot prorate. To enable proration, compose the CORE financial/Billable trait (which owns the proration semantics). See traits/financial/Billable.trait.yaml.

## Fields it adds

| Field | Type | Required | Description |
| - | - | - | - |
| `plan_code` | `string` | yes | Provider specific identifier for the plan or price. |
| `plan_name` | `string` | yes | Human readable plan label rendered in list and detail contexts. |
| `billing_interval` | `string` | yes | Billing cadence name selected from supportedIntervals. |
| `interval_count` | `integer` | no | Multiplier for interval (ex: 12 with monthly => yearly cadence). |
| `amount_minor` | `integer` | yes | Contract value expressed in minor currency units. |
| `currency` | `string` | yes | ISO 4217 currency for the plan price. |
| `trial_period_days` | `integer` | no | Length of introductory trial period in days. |
| `collection_method` | `string` | no | How billing is collected (charge_automatically, send_invoice). |
| `billing_anchor_day` | `integer` | no | Day of month used to anchor renewals when prorating. |
| `pricing_model` | `string` | no | Price strategy (flat, per_unit, tiered, package). |

## What it shows in each context

- [list](https://oods-foundry.com/contexts/list)

  `BillingSummaryBadge`

- [card](https://oods-foundry.com/contexts/card)

  `BillingCardMeta`

## Parameters

- `defaultCurrency` `string`

  ISO 4217 currency used when a plan omits currency.

- `supportedIntervals` `string[]`

  Allowed billing intervals that downstream plans may select.

- `decimalPrecision` `number`

  Minor unit precision (ex: cents = 2, yen = 0).

## Objects that use it

- [Plan](https://oods-foundry.com/objects/plan)

## The trait file

`domains/saas-billing/traits/billable.trait.yaml`

```
trait:
  name: SaaSBillingBillable
  version: 1.0.0
  description: >-
    Normalizes recurring price configuration for SaaS plans including cadence, currency,
    and trial policy. NOTE (trait-split gap): this domain trait does NOT model
    proration — no supportProration/proration_amount/proration_date/prorationBehavior. A
    Subscription composing only SaaSBillingBillable silently cannot prorate. To enable
    proration, compose the CORE financial/Billable trait (which owns the proration
    semantics). See traits/financial/Billable.trait.yaml.
  category: domain
  tags:
    - billing
    - pricing
    - domain

parameters:
  - name: defaultCurrency
    type: string
    required: false
    description: ISO 4217 currency used when a plan omits currency.
    default: usd
  - name: supportedIntervals
    type: string[]
    required: false
    description: Allowed billing intervals that downstream plans may select.
    default:
      - monthly
      - quarterly
      - annual
  - name: decimalPrecision
    type: number
    required: false
    description: "Minor unit precision (ex: cents = 2, yen = 0)."
    default: 2

schema:
  plan_code:
    type: string
    required: true
    description: Provider specific identifier for the plan or price.
  plan_name:
    type: string
    required: true
    description: Human readable plan label rendered in list and detail contexts.
  billing_interval:
    type: string
    required: true
    description: Billing cadence name selected from supportedIntervals.
    validation:
      enumFromParameter: supportedIntervals
  interval_count:
    type: integer
    required: false
    description: "Multiplier for interval (ex: 12 with monthly => yearly cadence)."
    default: 1
  amount_minor:
    type: integer
    required: true
    description: Contract value expressed in minor currency units.
  currency:
    type: string
    required: true
    description: ISO 4217 currency for the plan price.
    defaultFromParameter: defaultCurrency
  trial_period_days:
    type: integer
    required: false
    description: Length of introductory trial period in days.
  collection_method:
    type: string
    required: false
    description: How billing is collected (charge_automatically, send_invoice).
  billing_anchor_day:
    type: integer
    required: false
    description: Day of month used to anchor renewals when prorating.
    validation:
      minimum: 1
      maximum: 31
  pricing_model:
    type: string
    required: false
    description: Price strategy (flat, per_unit, tiered, package).
    default: flat

semantics:
  plan_code:
    semantic_type: billing.plan.code
    token_mapping: tokenMap(billing.plan.code)
  plan_name:
    semantic_type: billing.plan.name
    token_mapping: tokenMap(billing.plan.name)
  billing_interval:
    semantic_type: billing.plan.interval
    token_mapping: tokenMap(billing.plan.interval)
  interval_count:
    semantic_type: billing.plan.interval_count
    token_mapping: tokenMap(billing.plan.interval_count)
  amount_minor:
    semantic_type: billing.plan.amount_minor
    token_mapping: tokenMap(billing.plan.amount_minor)
    ui_hints:
      component: CurrencyAmount
      currencyField: currency
      minorUnits: 100
  currency:
    semantic_type: billing.plan.currency
    token_mapping: tokenMap(billing.plan.currency)
  trial_period_days:
    semantic_type: billing.plan.trial_period_days
    token_mapping: tokenMap(billing.plan.trial_period_days)
  collection_method:
    semantic_type: billing.plan.collection_method
    token_mapping: tokenMap(billing.plan.collection_method)
  billing_anchor_day:
    semantic_type: billing.plan.billing_anchor_day
    token_mapping: tokenMap(billing.plan.billing_anchor_day)
  pricing_model:
    semantic_type: billing.plan.pricing_model
    token_mapping: tokenMap(billing.plan.pricing_model)

view_extensions:
  # s222-m03 (#2502 ruling 13): a plan's row, page header and card show its price and interval, as a financial trait's recipes do.
  list:
    - component: BillingSummaryBadge
      position: after
      props:
        amountField: amount_minor
        currencyField: currency
        intervalField: billing_interval
        minorUnits: 100
  card:
    - component: BillingCardMeta
      position: after
      props:
        amountField: amount_minor
        currencyField: currency
        intervalField: billing_interval
        minorUnits: 100

tokens:
  billing.plan.name: "var(--cmp-text-strong)"
  billing.plan.amount_minor: "var(--cmp-text-body-strong)"
  billing.plan.currency: "var(--cmp-text-subtle)"
  billing.plan.interval: "var(--cmp-text-subtle)"
  billing.plan.collection_method: "var(--cmp-badge-text-info)"

metadata:
  owners:
    - billing@oods.systems
    - design@oods.systems
  maturity: beta
  regionsUsed:
    - list
    - card
  references:
    - R13.5 Canonical Model: Subscription and Invoice
    - R4.5 SaaS Enum-to-Token Mapping Schema
```
