Screens

Every screen below was generated from this object by OODS Foundry 0.10.1, in React and Vue, and shows the calls that made it and its content hash. Each runs as its generated app runs, in this site's brand, Aquex, in the theme you choose, with the sample records this object's own file carries. A value no record gives shows as a neutral one, such as an empty value or "Not recorded"; OODS Foundry invents none.

React app · sample recordsMaturity: betasha256:dde1d1ded91c…Open full size: Subscription detail screen generated by OODS Foundry in React

What design_compose reported for every screen here:

  • OODS-V121 Object 'Subscription' has maturity 'beta' — composed output may change.
  • OODS-V117 Subscription refines 11 fields its traits define, and its own definitions are used: lifecycle/Stateful (status); lifecycle/Cancellable (cancel_at_period_end, cancellation_reason, cancellation_requested_at); financial/Billable (amount, currency, billing_interval, current_period_start, current_period_end, current_period_progress, next_payment_due_at).
The calls that made the Subscription detail apps, in React and Vue
3 calls, as the pipeline sent them
design_compose {
  "object": "Subscription",
  "context": "detail",
  "preferences": {
    "brand": "Aquex",
    "theme": "light"
  }
}

code_generate {
  "schemaRef": "compose-1ab339c8",
  "framework": "react",
  "profile": "build",
  "options": {
    "output": "application",
    "brand": "Aquex",
    "theme": "light",
    "payloadMode": "file"
  }
}

code_generate {
  "schemaRef": "compose-1ab339c8",
  "framework": "vue",
  "profile": "build",
  "options": {
    "output": "application",
    "brand": "Aquex",
    "theme": "light",
    "payloadMode": "file"
  }
}

The React app's content hash: sha256:dde1d1ded91c3a9f489ea363826a798de88c849366ffc8cdc0c9ec38dbcabf21. Its src/ folder: App.tsx, GeneratedUI.tsx, app.css, charts/, main.tsx, oods-brand-aquex.css

The Vue app's content hash: sha256:5f818219f92bbe3a0267ea4a82d419b7b7ffc0e71f4940004d165adc3b77b33f. Its src/ folder: App.vue, GeneratedUI.vue, app.css, charts/, main.ts, oods-brand-aquex.css

Fields

FieldTypeDescription
statusrequired string (future, trialing, active, paused, pending_cancellation, past_due, unpaid, terminated) Current lifecycle status of the subscription.
state_history StateTransition[] Chronological log of state transitions.
More

Each entry records the before/after states, timestamp, and (when governance is enabled) the actor, reason, and transition metadata. Rendered by StatusTimeline in the detail and timeline views. Entry structure: - from: string (previous state) - to: string (new state) - timestamp: ISO 8601 datetime - actor_id: string (user/system who triggered the transition, optional) - reason: string (human-readable justification, required when requireTransitionReason is true) - transition_metadata: Record<string, unknown> (arbitrary context, optional)

allowed_transitions string[] Materialized list of valid next states from the current status, computed from the transitionRules parameter.
More

When transitionRules is null (open model), this contains all states except the current one. Used by StatusSelector to disable invalid options and by StatusBadge to indicate available paths.

cancel_at_period_endrequired boolean Whether the subscription will cancel at the natural billing period end.
cancellation_reason string Free-form explanation captured during cancellation workflows.
cancellation_reason_code string Structured reason code chosen from the allowedReasons parameter.
cancellation_requested_at datetime Timestamp when cancellation was initiated.
created_atrequired datetime Timestamp recording when the entity was first created.
updated_at datetime Timestamp for the most recent modification, when available.
last_eventrequired string Lifecycle event associated with the most recent timestamp mutation.
last_event_at datetime Timestamp for the lifecycle event captured in last_event.
amountrequired integer Recurring price expressed in minor units (e.g., cents).
currencyrequired string ISO 4217 currency code used for billing.
billing_interval string Recurrence cadence (monthly, yearly, quarterly, etc.).
payment_status string (pending, succeeded, failed, retrying, refunded) Outcome of the most recent collection attempt.
More

Distinct from subscription lifecycle status — a subscription can be "active" with payment_status "retrying".

payment_method_type string (card, ach, wire, invoice, other) Payment instrument category used for collection.
proration_amount integer Prorated credit or charge in minor currency units generated by a mid-cycle plan change.
More

Positive values are charges; negative values are credits. Only populated when the supportProration parameter is true.

proration_date integer Unix timestamp (epoch SECONDS) at which proration is calculated.
More

Pinned when an upcoming-invoice PREVIEW is requested and MUST be passed identically on commit so the committed charge equals the previewed amount. The preview is read-only and does NOT mutate the subscription. Stored as an integer (not a datetime) so the value round-trips byte-identically between preview and commit — an ISO string normalization could shift it and desync the previewed vs charged amount. Only populated when supportProration is true. Source: docs.stripe.com/billing/subscriptions/prorations.

last_payment_at datetime Timestamp of the most recent successful payment.
next_payment_due_at datetime Timestamp when the next payment attempt should occur.
current_period_startrequired datetime Start timestamp of the current billing cycle.
current_period_endrequired datetime End timestamp of the current billing cycle.
current_period_progress number Decimal progress (0-1) through the active billing cycle.
is_archivedrequired boolean Flag indicating whether the entity is currently archived (soft-deleted).
archived_at datetime? Timestamp for when the entity entered the archived state.
restored_at datetime? Timestamp for when the entity was most recently restored from an archived state.
archive_reason string Human-readable narrative describing why the entity was archived.
archived_by string User ID or system identifier of the actor who archived this entity.
More

Set to "system" for automated/policy-driven archival. Supports audit trail queries like "show all entities archived by user X" or "show all auto-archived entities".

archive_metadata object Structured metadata about the archival action for compliance and audit purposes.
More

Properties: - method: "manual" | "automated" | "policy" — how the archive was triggered - compliance_tags: string[] — regulatory labels (e.g., ["GDPR", "SOX", "HIPAA"]) - retention_policy_id: string — reference to the retention policy that triggered archival - original_status: string — the Stateful status before archival - related_entity_count: number — count of related entities also archived (cascade)

restoration_metadata object Metadata about the most recent restoration action.
More

Properties: - restored_by: string — user ID or "system" - restored_fields: string[] — when partial restore, which fields were restored - restoration_reason: string — why the entity was restored - restored_from_snapshot: boolean — whether restored from a point-in-time snapshot

subscription_idrequired string Primary identifier used across billing and lifecycle systems.
plan_namerequired string Human-readable plan label shown in headers.
plan_code string Internal plan code or price identifier.
plan_interval string Billing interval descriptor (monthly, yearly, etc.).
customer_name string Customer or account name associated with the subscription.
customer_email email Billing contact email address.
payment_history PaymentRecord[] Recorded payments, oldest first, each with its time and amount in minor units.
More

Drawn by the payment chart.

Traits

Each trait adds fields and behaviour. Every object with the trait gets the same.

Relationships

These arrows show declared relationships between object types. They don't join live records.

  • Plan, many-to-one, via plan_code
Relationships: Subscription2 object types and 3 declared associations. Arrows point from source to target. Labels state source-relative cardinality and the via field; they do not assert live referential integrity. Plan to Plan: Downgrade destinations, many-to-many, via downgrade_targets. Plan to Plan: Upgrade destinations, many-to-many, via upgrade_targets. Subscription to Plan: Plan code, many-to-one, via plan_code.Downgrade destinationsmany-to-manyvia downgrade_targetsUpgrade destinationsmany-to-manyvia upgrade_targetsPlan codemany-to-onevia plan_codeNormalized plan definition capturing pricing, packaging, and entitlement metadata.PlanTraits: SaaSBillingBillable,SaaSBillingMetered, OwnerableKey fields (6 of 33)plan_id: string *plan_name: string *downgrade_targets: string[]upgrade_targets: string[]product_family: string *status: string *Canonical subscription record composing lifecycle, billing, and cancellation semantics.SubscriptionTraits: Stateful, Cancellable,Timestampable, Billable, Archivable,MarkBarKey fields (6 of 37)subscription_id: string *plan_name: string *plan_code: stringamount: integer *cancel_at_period_end: boolean *currency: string *

The object file

The Subscription object definition in YAML: objects/core/Subscription.object.yaml
object:
  name: Subscription
  version: 2.0.0
  domain: core.billing
  description: Canonical subscription record composing lifecycle, billing, and cancellation semantics.
  tags:
    - billing
    - lifecycle
    - monetization

traits:
  - name: lifecycle/Stateful
    alias: SubscriptionLifecycle
    parameters:
      states:
        - future
        - trialing
        - active
        - paused
        - pending_cancellation
        - past_due
        - unpaid
        - terminated
      initialState: future
  - name: lifecycle/Cancellable
    alias: SubscriptionCancellation
    parameters:
      allowCancellationAfterStart: true
      requireReason: false
  - name: lifecycle/Timestampable
    alias: BillingCycleTimeline
    parameters:
      recordedEvents:
        - billing_cycle_started
        - billing_cycle_completed
        - payment_received
        - cancellation_requested
      timezone: UTC
  - name: financial/Billable
    alias: SubscriptionBilling
    parameters:
      defaultCurrency: usd
      billingIntervals:
        - monthly
        - yearly
      minorUnits: 100
      # A plan change mid-cycle is charged at once as a prorated payment (Northwind Traders' upgrade to Business).
      supportProration: true
      prorationBehavior: always_invoice
  - name: lifecycle/Archivable
    alias: SubscriptionArchive
    parameters:
      gracePeriodDays: 30
      retainHistory: true
      restoreWindowDays: 30

  # One bar per recorded payment (s220-m01, #2461): an area over a steady price filled its plot as one block.
  - name: viz/MarkBar
    parameters:
      title: Payment amounts
      description: Payments recorded for this subscription, in its currency.
      chart:
        chartType: bar
        source: payment-events
        dateFields: [last_payment_at, next_payment_due_at]
        amountField: amount
        minorUnits: 100
        currencyField: currency

schema:
  subscription_id:
    type: string
    required: true
    description: Primary identifier used across billing and lifecycle systems.
  plan_name:
    type: string
    required: true
    description: Human-readable plan label shown in headers.
  plan_code:
    type: string
    required: false
    description: Internal plan code or price identifier.
  plan_interval:
    type: string
    required: false
    description: Billing interval descriptor (monthly, yearly, etc.).
  customer_name:
    type: string
    required: false
    description: Customer or account name associated with the subscription.
  customer_email:
    type: email
    required: false
    description: Billing contact email address.
  status:
    type: string
    required: true
    description: Current lifecycle status of the subscription.
    validation:
      enum:
        - future
        - trialing
        - active
        - paused
        - pending_cancellation
        - past_due
        - unpaid
        - terminated
  cancel_at_period_end:
    type: boolean
    required: true
    description: Whether the subscription will cancel at the natural billing period end.
  cancellation_reason:
    type: string
    required: false
    description: Free-form explanation captured during cancellation workflows.
  cancellation_requested_at:
    type: datetime
    required: false
    description: Timestamp when cancellation was initiated.
  amount:
    type: integer
    required: true
    description: Recurring price expressed in minor units (e.g., cents).
  currency:
    type: string
    required: true
    description: ISO 4217 currency code used for billing.
  billing_interval:
    type: string
    required: false
    description: Recurrence cadence (monthly, yearly, quarterly, etc.).
  current_period_start:
    type: datetime
    required: true
    description: Start timestamp of the current billing cycle.
  current_period_end:
    type: datetime
    required: true
    description: End timestamp of the current billing cycle.
  current_period_progress:
    type: number
    required: false
    description: Decimal progress (0-1) through the active billing cycle.
  next_payment_due_at:
    type: datetime
    required: false
    description: Timestamp when the next payment attempt should occur.
  payment_history:
    type: PaymentRecord[]
    required: false
    description: Recorded payments, oldest first, each with its time and amount in minor units. Drawn by the payment chart.

semantics:
  subscription_id:
    semantic_type: billing.subscription.id
    token_mapping: tokenMap(billing.subscription.id)
  plan_name:
    semantic_type: billing.plan.name
    token_mapping: tokenMap(billing.plan.name)
  plan_code:
    semantic_type: billing.plan.code
    token_mapping: tokenMap(billing.plan.code)
  plan_interval:
    semantic_type: billing.plan.interval
    token_mapping: tokenMap(billing.plan.interval)
  # The one-line summary under the plan's name in lists: whose subscription it is.
  customer_name:
    semantic_type: text.summary
    token_mapping: tokenMap(customer.account.name)
  customer_email:
    semantic_type: customer.account.email
    token_mapping: tokenMap(customer.account.email)
  status:
    semantic_type: billing.subscription.status
    token_mapping: tokenMap(billing.subscription.status.*)
  cancel_at_period_end:
    semantic_type: billing.subscription.cancel_at_period_end
    token_mapping: tokenMap(billing.subscription.cancel_at_period_end)
  cancellation_reason:
    semantic_type: billing.subscription.cancellation_reason
    token_mapping: tokenMap(billing.subscription.cancellation_reason)
  cancellation_requested_at:
    semantic_type: billing.subscription.cancellation_requested_at
    token_mapping: tokenMap(billing.subscription.cancellation_requested_at)
  amount:
    semantic_type: billing.plan.amount
    token_mapping: tokenMap(billing.plan.amount)
    ui_hints:
      component: CurrencyAmount
      currencyField: currency
      minorUnitsParameter: minorUnits
  currency:
    semantic_type: billing.plan.currency
    token_mapping: tokenMap(billing.plan.currency)
  billing_interval:
    semantic_type: billing.subscription.interval
    token_mapping: tokenMap(billing.subscription.interval)
  current_period_start:
    semantic_type: billing.subscription.current_period_start
    token_mapping: tokenMap(billing.subscription.current_period_start)
  current_period_end:
    semantic_type: billing.subscription.current_period_end
    token_mapping: tokenMap(billing.subscription.current_period_end)
  current_period_progress:
    semantic_type: billing.subscription.current_period_progress
    token_mapping: tokenMap(billing.subscription.current_period_progress)
  last_payment_at:
    semantic_type: billing.subscription.last_payment_at
    token_mapping: tokenMap(billing.subscription.last_payment_at)
  next_payment_due_at:
    semantic_type: billing.subscription.next_payment_due_at
    token_mapping: tokenMap(billing.subscription.next_payment_due_at)

tokens:
  billing.subscription.status.future: "var(--semantic-info)"
  billing.subscription.status.trialing: "var(--semantic-info)"
  billing.subscription.status.active: "var(--semantic-success)"
  billing.subscription.status.paused: "var(--semantic-warning)"
  billing.subscription.status.pending_cancellation: "var(--semantic-info)"
  billing.subscription.status.past_due: "var(--semantic-danger)"
  billing.subscription.status.unpaid: "var(--semantic-danger)"
  billing.subscription.status.terminated: "var(--semantic-neutral)"
  billing.subscription.interval.monthly: "var(--text-subtle)"
  billing.plan.amount: "var(--text-strong)"

metadata:
  owners:
    - billing@oods.systems
    - lifecycle@oods.systems
  steward: design@oods.systems
  maturity: beta
  changelog:
    - version: 2.0.0
      date: "2026-06-24"
      description: >-
        Converge status onto the canonical Stripe-literal extend-8 state set.
        Replace the consolidated `delinquent` with `past_due` (retries ongoing →
        grace access) + `unpaid` (retries exhausted → access revoked). BREAKING:
        `delinquent` is removed from the status enum. Source: docs.stripe.com/api/subscriptions/object.
    - version: 1.0.0
      date: "2025-10-21"
      description: Initial subscription composition integrating State, Cancellation, Billing, and Timeline traits.

# Authored type associations; no record join or referential-integrity claim.
relationships:
  - target: Plan
    via: plan_code
    cardinality: many-to-one
    label: Plan code

# Eight authored sample subscriptions, one coherent record each: plan, price, billing period, payments, payment status,
# events, history and cancellation agree, and each customer is a sample Organization. Payments vary: Northwind Traders
# upgrades from Team to Business with a prorated charge, Lindqvist Bakery is refunded a duplicate charge, and
# Tidewater Co-op pays a yearly price by bank transfer. Progress is authored so a period's position does not depend on
# the day a screen is opened. The state history starts in the lifecycle's initial state (future) and follows the
# subscription transitions.
samples:
  - subscription_id: sub_northwind_business
    plan_name: Business
    plan_code: business-monthly
    plan_interval: monthly
    billing_interval: monthly
    customer_name: Northwind Traders
    customer_email: billing@northwind.example
    status: active
    state_history:
      - { title: Trial started, from: future, to: trialing, at: '2026-02-16T15:00:00Z', reason: Started a 14-day Team trial }
      - { title: Trial converted, from: trialing, to: active, at: '2026-03-02T15:00:00Z', reason: First Team payment collected }
    amount: 14900
    currency: USD
    payment_history:
      - { at: '2026-03-02T15:00:00Z', amount: 4900 }
      - { at: '2026-04-02T15:00:00Z', amount: 4900 }
      - { at: '2026-05-02T15:00:00Z', amount: 4900 }
      - { at: '2026-06-02T15:00:00Z', amount: 4900 }
      - { at: '2026-06-16T15:00:00Z', amount: 5333 }
      - { at: '2026-07-02T15:00:00Z', amount: 14900 }
      - { at: '2026-08-02T15:00:00Z', amount: 14900 }
      - { at: '2026-09-02T15:00:00Z', amount: 14900 }
    proration_amount: 5333
    payment_status: succeeded
    payment_method_type: card
    last_payment_at: '2026-09-02T15:00:00Z'
    next_payment_due_at: '2026-10-02T15:00:00Z'
    current_period_start: '2026-09-02T15:00:00Z'
    current_period_end: '2026-10-02T15:00:00Z'
    current_period_progress: 0.93
    cancel_at_period_end: false
    cancellation_reason: null
    cancellation_requested_at: null
    created_at: '2026-02-16T15:00:00Z'
    updated_at: '2026-09-02T15:00:00Z'
    last_event: payment_received
    last_event_at: '2026-09-02T15:00:00Z'
  - subscription_id: sub_northwind_analytics
    plan_name: Analytics add-on
    plan_code: analytics-addon-monthly
    plan_interval: monthly
    billing_interval: monthly
    customer_name: Northwind Traders
    customer_email: billing@northwind.example
    status: paused
    state_history:
      - { title: Started, from: future, to: active, at: '2026-04-10T15:00:00Z', reason: Analytics add-on purchased }
      - { title: Paused, from: active, to: paused, at: '2026-08-20T14:00:00Z', reason: Paused during the ERP migration }
    amount: 3900
    currency: USD
    payment_history:
      - { at: '2026-04-10T15:00:00Z', amount: 3900 }
      - { at: '2026-05-10T15:00:00Z', amount: 3900 }
      - { at: '2026-06-10T15:00:00Z', amount: 3900 }
      - { at: '2026-07-10T15:00:00Z', amount: 3900 }
      - { at: '2026-08-10T15:00:00Z', amount: 3900 }
    payment_status: succeeded
    payment_method_type: card
    last_payment_at: '2026-08-10T15:00:00Z'
    next_payment_due_at: null
    current_period_start: '2026-08-10T15:00:00Z'
    current_period_end: '2026-09-10T15:00:00Z'
    current_period_progress: 1
    cancel_at_period_end: false
    cancellation_reason: null
    cancellation_requested_at: null
    created_at: '2026-04-10T15:00:00Z'
    updated_at: '2026-09-10T15:00:00Z'
    last_event: billing_cycle_completed
    last_event_at: '2026-09-10T15:00:00Z'
  - subscription_id: sub_lindqvist_starter
    plan_name: Starter
    plan_code: starter-monthly
    plan_interval: monthly
    billing_interval: monthly
    customer_name: Lindqvist Bakery
    customer_email: finance@lindqvist.example
    status: active
    state_history:
      - { title: Started, from: future, to: active, at: '2026-01-15T08:00:00Z', reason: Subscribed to the Starter plan }
      - { title: Payment failed, from: active, to: past_due, at: '2026-05-15T08:00:00Z', reason: Card expired; retrying }
      - { title: Recovered, from: past_due, to: active, at: '2026-05-17T08:00:00Z', reason: New card charged }
    amount: 1900
    currency: EUR
    payment_history:
      - { at: '2026-01-15T08:00:00Z', amount: 1900 }
      - { at: '2026-02-15T08:00:00Z', amount: 1900 }
      - { at: '2026-03-15T08:00:00Z', amount: 1900 }
      - { at: '2026-04-15T08:00:00Z', amount: 1900 }
      - { at: '2026-05-17T08:00:00Z', amount: 1900 }
      - { at: '2026-06-15T08:00:00Z', amount: 1900 }
      - { at: '2026-07-15T08:00:00Z', amount: 1900 }
      - { at: '2026-08-15T08:00:00Z', amount: 1900 }
      - { at: '2026-08-16T08:00:00Z', amount: 1900 }
      - { at: '2026-08-19T11:30:00Z', amount: -1900 }
      - { at: '2026-09-15T08:00:00Z', amount: 1900 }
    payment_status: succeeded
    payment_method_type: card
    last_payment_at: '2026-09-15T08:00:00Z'
    next_payment_due_at: '2026-10-15T08:00:00Z'
    current_period_start: '2026-09-15T08:00:00Z'
    current_period_end: '2026-10-15T08:00:00Z'
    current_period_progress: 0.5
    cancel_at_period_end: false
    cancellation_reason: null
    cancellation_requested_at: null
    created_at: '2026-01-15T08:00:00Z'
    updated_at: '2026-09-15T08:00:00Z'
    last_event: payment_received
    last_event_at: '2026-09-15T08:00:00Z'
  - subscription_id: sub_blueharbor_team
    plan_name: Team
    plan_code: team-monthly
    plan_interval: monthly
    billing_interval: monthly
    customer_name: Blue Harbor Studio
    customer_email: accounts@blueharbor.example
    status: trialing
    state_history:
      - { title: Scheduled, from: null, to: future, at: '2026-09-19T10:00:00Z', reason: Trial starts once a card is verified }
      - { title: Trial started, from: future, to: trialing, at: '2026-09-21T09:00:00Z', reason: Card verified; 14-day trial started }
    amount: 4900
    currency: USD
    payment_history: []
    payment_status: pending
    payment_method_type: card
    last_payment_at: null
    next_payment_due_at: '2026-10-05T09:00:00Z'
    current_period_start: '2026-09-21T09:00:00Z'
    current_period_end: '2026-10-05T09:00:00Z'
    current_period_progress: 0.64
    cancel_at_period_end: false
    cancellation_reason: null
    cancellation_requested_at: null
    created_at: '2026-09-19T10:00:00Z'
    updated_at: '2026-09-21T09:00:00Z'
    last_event: billing_cycle_started
    last_event_at: '2026-09-21T09:00:00Z'
  - subscription_id: sub_kestrel_team
    plan_name: Team
    plan_code: team-monthly
    plan_interval: monthly
    billing_interval: monthly
    customer_name: Kestrel Print Co.
    customer_email: hello@kestrelprint.example
    status: past_due
    state_history:
      - { title: Trial started, from: future, to: trialing, at: '2026-01-20T10:30:00Z', reason: Started a 14-day Team trial }
      - { title: Trial converted, from: trialing, to: active, at: '2026-02-03T10:00:00Z', reason: First payment collected }
      - { title: Payment failed, from: active, to: past_due, at: '2026-09-03T10:00:00Z', reason: Card declined; retrying }
    amount: 4900
    currency: GBP
    payment_history:
      - { at: '2026-02-03T10:00:00Z', amount: 4900 }
      - { at: '2026-03-03T10:00:00Z', amount: 4900 }
      - { at: '2026-04-03T10:00:00Z', amount: 4900 }
      - { at: '2026-05-03T10:00:00Z', amount: 4900 }
      - { at: '2026-06-03T10:00:00Z', amount: 4900 }
      - { at: '2026-07-03T10:00:00Z', amount: 4900 }
      - { at: '2026-08-03T10:00:00Z', amount: 4900 }
    payment_status: retrying
    payment_method_type: card
    last_payment_at: '2026-08-03T10:00:00Z'
    next_payment_due_at: '2026-10-01T10:00:00Z'
    current_period_start: '2026-09-03T10:00:00Z'
    current_period_end: '2026-10-03T10:00:00Z'
    current_period_progress: 0.9
    cancel_at_period_end: false
    cancellation_reason: null
    cancellation_requested_at: null
    created_at: '2026-01-20T10:30:00Z'
    updated_at: '2026-09-03T10:00:00Z'
    last_event: billing_cycle_started
    last_event_at: '2026-09-03T10:00:00Z'
  - subscription_id: sub_tidewater_enterprise
    plan_name: Enterprise
    plan_code: enterprise-annual
    plan_interval: yearly
    billing_interval: yearly
    customer_name: Tidewater Co-op
    customer_email: treasurer@tidewater.example
    status: active
    state_history:
      - { title: Started, from: future, to: active, at: '2024-10-30T14:00:00Z', reason: Annual Enterprise agreement signed }
      - { title: Invoice overdue, from: active, to: past_due, at: '2025-11-14T14:00:00Z', reason: Renewal invoice unpaid after 15 days }
      - { title: Recovered, from: past_due, to: active, at: '2025-11-20T02:00:00Z', reason: Paid by bank transfer }
    amount: 1200000
    currency: USD
    payment_history:
      - { at: '2024-10-30T14:00:00Z', amount: 1200000 }
      - { at: '2025-11-20T02:00:00Z', amount: 1200000 }
    payment_status: succeeded
    payment_method_type: wire
    last_payment_at: '2025-11-20T02:00:00Z'
    next_payment_due_at: '2026-10-30T14:00:00Z'
    current_period_start: '2025-10-30T14:00:00Z'
    current_period_end: '2026-10-30T14:00:00Z'
    current_period_progress: 0.92
    cancel_at_period_end: false
    cancellation_reason: null
    cancellation_requested_at: null
    created_at: '2024-10-30T14:00:00Z'
    updated_at: '2025-11-20T02:00:00Z'
    last_event: payment_received
    last_event_at: '2025-11-20T02:00:00Z'
  - subscription_id: sub_marlow_starter
    plan_name: Starter
    plan_code: starter-monthly
    plan_interval: monthly
    billing_interval: monthly
    customer_name: Marlow Yoga
    customer_email: studio@marlowyoga.example
    status: terminated
    state_history:
      - { title: Started, from: future, to: active, at: '2026-01-09T10:15:00Z', reason: Subscribed to the Starter plan }
      - { title: Cancellation requested, from: active, to: pending_cancellation, at: '2026-06-20T09:00:00Z', reason: Closing the studio in July }
      - { title: Ended, from: pending_cancellation, to: terminated, at: '2026-07-09T10:15:00Z', reason: Cancelled at the end of the billing period }
    amount: 1900
    currency: USD
    payment_history:
      - { at: '2026-01-09T10:15:00Z', amount: 1900 }
      - { at: '2026-02-09T10:15:00Z', amount: 1900 }
      - { at: '2026-03-09T10:15:00Z', amount: 1900 }
      - { at: '2026-04-09T10:15:00Z', amount: 1900 }
      - { at: '2026-05-09T10:15:00Z', amount: 1900 }
      - { at: '2026-06-09T10:15:00Z', amount: 1900 }
    payment_status: succeeded
    payment_method_type: card
    last_payment_at: '2026-06-09T10:15:00Z'
    next_payment_due_at: null
    current_period_start: '2026-06-09T10:15:00Z'
    current_period_end: '2026-07-09T10:15:00Z'
    current_period_progress: 1
    cancel_at_period_end: true
    cancellation_reason: Closing the studio in July
    cancellation_requested_at: '2026-06-20T09:00:00Z'
    created_at: '2026-01-09T10:15:00Z'
    updated_at: '2026-07-09T10:15:00Z'
    last_event: billing_cycle_completed
    last_event_at: '2026-07-09T10:15:00Z'
  - subscription_id: sub_summit_business
    plan_name: Business
    plan_code: business-monthly
    plan_interval: monthly
    billing_interval: monthly
    customer_name: Summit Outfitters
    customer_email: ap@summit.example
    status: pending_cancellation
    state_history:
      - { title: Trial started, from: future, to: trialing, at: '2026-04-23T12:30:00Z', reason: Started a 14-day Business trial }
      - { title: Trial converted, from: trialing, to: active, at: '2026-05-07T12:00:00Z', reason: First payment collected }
      - { title: Cancellation requested, from: active, to: pending_cancellation, at: '2026-09-21T16:40:00Z', reason: Moving to an annual contract elsewhere }
    amount: 14900
    currency: USD
    payment_history:
      - { at: '2026-05-07T12:00:00Z', amount: 14900 }
      - { at: '2026-06-07T12:00:00Z', amount: 14900 }
      - { at: '2026-07-07T12:00:00Z', amount: 14900 }
      - { at: '2026-08-07T12:00:00Z', amount: 14900 }
      - { at: '2026-09-07T12:00:00Z', amount: 14900 }
    payment_status: succeeded
    payment_method_type: card
    last_payment_at: '2026-09-07T12:00:00Z'
    next_payment_due_at: null
    current_period_start: '2026-09-07T12:00:00Z'
    current_period_end: '2026-10-07T12:00:00Z'
    current_period_progress: 0.77
    cancel_at_period_end: true
    cancellation_reason: Moving to an annual contract elsewhere
    cancellation_requested_at: '2026-09-21T16:40:00Z'
    created_at: '2026-04-23T12:30:00Z'
    updated_at: '2026-09-21T16:40:00Z'
    last_event: cancellation_requested
    last_event_at: '2026-09-21T16:40:00Z'