> ## Documentation Index
> Fetch the complete documentation index at: https://docs.subscribd.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Plans

> Define subscription plans in config and sync them to the database

# Plans

Plans are the foundation of Subscribd's billing model. They're defined in `config/subscribd.php` and synced to the `subscribd_plans` database table via `php artisan subscribd:install`. Version-controlling your plan definitions in config means plan changes are code-reviewed and deployable like any other application change.

## Defining a plan

```php theme={null}
// config/subscribd.php
'plans' => [
    'pro' => [
        'name'          => 'Pro',
        'description'   => 'Everything you need to grow.',
        'rule'          => 'flat',           // 'flat' | 'per_unit' | 'tiered' | 'metered'
        'amount'        => 4900,             // in minor units (cents)
        'interval'      => 'month',          // 'day' | 'week' | 'month' | 'year'
        'interval_count' => 1,
        'is_recurring'  => true,
        'trial_days'    => 14,
        'features' => [
            'projects'    => 10,
            'api_calls'   => 50000,
            'team_seats'  => 5,
            'exports'     => true,
        ],
    ],
],
```

### Required fields

| Field      | Type   | Description                                              |
| ---------- | ------ | -------------------------------------------------------- |
| `name`     | string | Display name shown in UI                                 |
| `rule`     | string | Pricing rule: `flat`, `per_unit`, `tiered`, or `metered` |
| `amount`   | int    | Price in minor currency units (e.g. cents for USD)       |
| `interval` | string | Billing cycle: `day`, `week`, `month`, or `year`         |

### Optional fields

| Field                           | Type   | Default        | Description                                                            |
| ------------------------------- | ------ | -------------- | ---------------------------------------------------------------------- |
| `description`                   | string | `null`         | Plan description for display                                           |
| `interval_count`                | int    | `1`            | Number of intervals per billing period                                 |
| `is_recurring`                  | bool   | `true`         | Set `false` for lifetime or one-time plans (excluded from MRR/ARR)     |
| `trial_days`                    | int    | `0`            | Free trial length in days                                              |
| `features`                      | array  | `[]`           | Feature keys and limits; `true` for boolean access, integer for limits |
| `trial_requires_payment_method` | bool   | `true`         | Set `false` to start trials without collecting a card                  |
| `cancel_policy`                 | string | config default | `at_period_end`, `immediately`, or `immediately_with_refund`           |

## Pricing rules

The `rule` field maps to a pricing class that controls how charges are calculated.

### Flat rate

A single recurring charge regardless of usage or quantity:

```php theme={null}
'starter' => [
    'rule'     => 'flat',
    'amount'   => 1900,
    'interval' => 'month',
],
```

### Per unit

Charge per seat, user, or any countable unit:

```php theme={null}
'team' => [
    'rule'     => 'per_unit',
    'amount'   => 500,       // per unit per month
    'interval' => 'month',
    'features' => ['seats' => null],  // null = no cap
],
```

### Tiered

Price changes at volume breakpoints:

```php theme={null}
'growth' => [
    'rule'     => 'tiered',
    'interval' => 'month',
    'tiers'    => [
        ['from' => 0,    'to' => 10,   'unit_price' => 500],
        ['from' => 11,   'to' => 50,   'unit_price' => 400],
        ['from' => 51,   'to' => null, 'unit_price' => 300],
    ],
],
```

### Metered

Charge based on actual usage reported at the end of each billing period:

```php theme={null}
'api' => [
    'rule'     => 'metered',
    'interval' => 'month',
    'amount'   => 0,         // base charge
    'features' => [
        'api_calls' => ['unit_price' => 1, 'included' => 10000],
    ],
],
```

## Plan items

PlanItems are composable add-ons that attach to a plan. Each item has a `key`, an `included_quantity`, and a `unit_price` for overages. They're defined in the database via the Filament admin panel or via the `plan:item` Artisan command, and sync to `subscribd_plan_items`.

When a subscription is created, Subscribd hydrates one `SubscriptionItem` record per active PlanItem on the plan. Customers can select per-item quantities at checkout via the `PlanPicker` Livewire component.

```php theme={null}
// Creating a subscription with PlanItem quantity overrides
$user->subscription()->create($proPlan, [
    'plan_items' => [
        'extra_projects' => 3,
        'api_add_on'     => 1,
    ],
]);
```

## Free plans

Set `amount` to `0` to create a free plan. Subscribd automatically routes zero-cost subscriptions through the `null` gateway — no payment method is required and no gateway API call is made:

```php theme={null}
'free' => [
    'name'     => 'Free',
    'rule'     => 'flat',
    'amount'   => 0,
    'interval' => 'month',
    'features' => ['projects' => 1, 'api_calls' => 1000],
],
```

## Lifetime plans

Set `is_recurring` to `false` for one-time charges that never renew. Lifetime plans are excluded from MRR and ARR calculations:

```php theme={null}
'lifetime' => [
    'name'         => 'Lifetime',
    'rule'         => 'flat',
    'amount'       => 39900,
    'interval'     => 'month',   // interval is required but ignored for one-time charges
    'is_recurring' => false,
],
```

## Syncing plans to the database

After modifying `config/subscribd.php`, run:

```bash theme={null}
php artisan subscribd:install
```

This upserts the `subscribd_plans` table from config. Existing subscriptions are unaffected — the plan record is updated in place, not replaced.

You can also manage plans directly in the Filament admin panel at `/subscribd/admin`.

## Next steps

* **[Creating Subscriptions](/subscriptions/creating)** — Subscribe a billable to a plan
* **[Billing Scenarios](/billing-scenarios/flat-rate)** — Deep dives for each pricing rule
* **[Components](/components/livewire)** — The PlanPicker and Checkout Livewire components
