Plan Items and Add-ons
PlanItem is the structured way to attach priced, quantified add-ons to a plan. Use it whenever a feature has a price, an included quantity, or an overage behaviour — not just a boolean flag.
When to use PlanItem vs features JSON
| Use case | Use |
|---|---|
Boolean feature flag (exports: true) | Plan.features JSON column |
Simple integer limit (projects: 10) | PlanItem — migrate from features JSON for entitlement resolution via included_quantity |
| Priced add-on with overage billing | PlanItem with unit_price and cap_behavior |
| Metered usage charged at period end | PlanItem with pricing_rule = 'metered' |
features. Anything with a price or quantity goes in PlanItem.
Creating plan items
CapBehavior enum
| Value | Behaviour |
|---|---|
Block | Access denied when quantity exceeds included_quantity. No billing. |
Charge | Bill at unit_price per unit beyond included_quantity, with no ceiling. |
ChargeUntilCeiling | Bill at unit_price per unit up to ceiling. Hard block beyond ceiling. |
SubscriptionItem — per-subscriber state
When a subscriber has a plan withPlanItems, a SubscriptionItem record is created per item at subscription time. SubscriptionItem tracks:
quantity— how many units the subscriber is currently usingprice_override/price_override_expires_at— admin-set per-subscriber pricegateway_item_id— the gateway’s item ID for native gateways (Stripe)
Updating quantities
Entitlement checks
Entitlements resolves plan items automatically:
- Check
Plan.features[$key]— if a value is set here, use it. - Check
PlanItembykey— useincluded_quantityas the limit.
Price overrides
Apply a per-subscriber price override to anySubscriptionItem:
expires_at passes at renewal, RenewSubscription fires SubscriptionPriceOverrideReverted and reverts to price_snapshot.
Overage billing at renewal
At renewal,RenewSubscription automatically charges overages for items with CapBehavior::Charge or CapBehavior::ChargeUntilCeiling:
effective_unit_price is SubscriptionItem.price_override when active, otherwise PlanItem.unit_price.
For gateways with native subscription item support (Stripe), overage is reported via the gateway’s items API and included in the gateway’s renewal invoice. For other gateways, subscribd issues a separate charge() call.
Next steps
- Subscriptions — Creating subscriptions with plan items
- Entitlements — Checking limits and usage
- Multi-Currency — Currency on plan items
- Bulk Operations — Bulk price overrides