# `PhoenixKitBilling.Subscription`
[🔗](https://github.com/BeamLabEU/phoenix_kit_billing/blob/0.5.1/lib/phoenix_kit_billing/schemas/subscription.ex#L1)

Schema for subscriptions (master record).

Subscriptions are controlled internally by PhoenixKit, NOT by payment providers.
This allows using any payment provider (even those without subscription APIs)
and provides full control over subscription lifecycle.

## Status Lifecycle

```
trialing -> active -> [past_due -> active] -> cancelled
                   -> paused -> active
                   -> cancelled
```

- `trialing` - Free trial period active
- `active` - Subscription is active and paid
- `past_due` - Payment failed, in grace period
- `paused` - Subscription temporarily paused by user
- `cancelled` - Subscription ended

## Renewal Process

Renewals are handled by Oban workers:
1. `SubscriptionRenewalWorker` runs daily, checks subscriptions near period end
2. Creates invoice for the subscription
3. Charges saved payment method via provider
4. On success: extends `current_period_end`
5. On failure: sets status to `past_due`, increments `renewal_attempts`

## Grace Period (Dunning)

When payment fails:
1. Status changes to `past_due`
2. `grace_period_end` is set (configurable days)
3. `SubscriptionDunningWorker` retries payment
4. After max attempts or grace period end: subscription cancelled

# `activate_changeset`

Changeset for activating a subscription after successful payment.

# `active?`

Returns true if the subscription is currently active (can use service).

# `cancel_changeset`

Changeset for cancelling a subscription.

# `cancelled?`

Returns true if the subscription is cancelled.

# `cancelling?`

Returns true if the subscription will be cancelled at period end.

# `changeset`

Creates a changeset for creating a new subscription.

# `days_remaining`

Returns the number of days remaining in the current period.

# `grace_period_expired?`

Returns true if grace period has expired.

# `past_due?`

Returns true if the subscription is past due (payment failed).

# `past_due_changeset`

Changeset for marking subscription as past_due.

# `pause_changeset`

Changeset for pausing a subscription.

# `paused?`

Returns true if the subscription is paused.

# `renewal_due?`

Returns true if renewal is due (period end is near or past).

# `resume_changeset`

Changeset for resuming a paused subscription.

# `should_renew?`

Returns true if we should attempt renewal (within 24 hours of period end).

# `trial_changeset`

Changeset for starting a trial.

# `trialing?`

Returns true if the subscription is in trial period.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
