# Plans, pricing models, and subscriptions

A plan describes how a subscription is priced and renewed. Alunta supports fixed prices, unit- or usage-based prices, and tiered prices. Amounts are stored in the currency's minor unit.

## Intervals and currencies

A plan can have prices for one or more renewal intervals and currencies. Tiered plans store prices on each tier instead of regular renewal intervals. A concrete price lookup must therefore account for pricing type, interval, and currency.

## Moving between tiers

On a tiered subscription, an administrator can choose **Change tier** and move the subscription to any tier allowed by its latest reported parameters. This includes a free tier. Every plan parameter must have been reported before a downgrade, and the selected tier must have a price for the subscription's current and already scheduled intervals.

An immediate upgrade takes effect at once and may create a prorated adjustment for the rest of the period. Other upgrades and all downgrades are scheduled for the first future billing period that is not already locked by an invoice or payment. The subscription continues in the meantime; it is not cancelled. Selecting the current tier cancels a replaceable scheduled tier change.

A prorated adjustment that is not invoiced or charged straight away waits for the subscription's next invoice. When the subscription is paid automatically by saved card, the next renewal charge collects the adjustment together with the new period, so the invoice that charge settles is paid in full. An adjustment created after that charge waits for the following one. A credit larger than the charge also waits for a later invoice instead of reducing a payment already taken.

A normal tier selection does not lock the subscription. Automatic tier evaluation therefore continues afterwards and can upgrade it again if reported values require that. The plan's downgrade setting still decides whether future decreases happen automatically at the next period or must be selected manually.

**Override tier** is a separate administrative exception. It can force a tier and locks automatic evaluation until the override is cleared from the dashboard. API calls may still report parameters for a locked subscription, but they cannot change its tier or clear the lock.

Integrations can read the tier, lock, and any scheduled change with `GET /subscriptions/{uuid}/tier`, and select an allowed tier with `PUT /subscriptions/{uuid}/tier`. A scheduled change returns both its effective date and a snapshot of the tier name. If the plan configuration later becomes inconsistent, `target_tier` can be `null` while `scheduled_tier_change` remains visible.

## Decreases in licensed quantity

On a license-based plan the **Decrease in quantity** setting decides what happens when a lower quantity is reported part-way through a period.

A reported quantity is a snapshot of what the customer has, so it is applied to the subscription immediately whatever the setting is. What the setting governs is the **billing**.

**From next renewal, without credit** is the default for license plans created after the setting was introduced. The period already running keeps the quantity and price it was agreed at, no credit and no negative adjustment is created, and the lower price applies from the next renewal.

**Immediately, with prorated credit** is the original behaviour and applies to every license plan that existed before the setting was introduced. The customer is credited for the remaining days of the period.

An **increase** reported without a future date takes effect immediately, whatever the setting is. If it increases the price, it can create a prorated charge. On a plan that defers the billing, the charge is measured from the count the period actually bills - never from a lower reported one - so a customer is never charged again for licences they never stopped paying for.

The subscription therefore carries two numbers: `quantity` is what the customer has now, and `current_period_quantity` is what the running period charges for. They differ until the renewal.

A count reported without a future date simply replaces the previous one. The setting is enforced everywhere a quantity is reported: in the app, through `PUT /subscriptions/{uuid}/quantity`, and from usage reports on a gauge parameter.

Two things are worth knowing. MRR follows the subscription's quantity, so a decrease shows up in MRR on the day it is reported even though it is only billed at the renewal. And if the next period has already been invoiced in advance it cannot be re-priced, so the decrease takes effect from the period after that.

## The plan catalogue and the concrete agreement

The plan is the catalogue of possible prices and intervals. An existing subscription is the concrete agreement and keeps its selected terms even if the plan is later hidden or an unused catalogue price is edited. A plan can be sold in checkout only when it is visible, has a price for the selected currency and interval, and has the payment setup required by the purchase.

An unused regular interval/currency price can be edited from the plan pricing table. A price used by subscriptions or active payment links should not be changed to rewrite old agreements; create an alternative price or change the concrete agreement through the subscription change flow. Tiered and usage prices have separate editors.

## License and usage

A regular license plan multiplies the unit price by the subscription quantity. A license plan can also include a base price with included licenses: the period price is `base_price + max(0, quantity - included_quantity) × unit_price`. Quantity is the total license count and must be at least one; unused included licenses do not reduce the base price. An increase can create a prorated adjustment, while a decrease follows the plan's selected billing rule. `quantity` is the current amount, while `current_period_quantity` is what the running period bills.

Base price, included quantity, and extra-license unit price are configured per interval and currency. For example, DKK 149 including one user plus DKK 79 per extra user costs DKK 307 for three users, before VAT and discounts. Annual billing uses its own annual price line. A mid-period quantity change does not charge the base price again; adjustments use the difference between the old and new total period prices. Changes that do not change the price do not create a separate zero-amount invoice.

In the plan CSV export, **Price** is the unit price for license plans; **Base price** and **Included quantity** show the base amount and included count separately. For other pricing models, **Price** is the interval price or the lowest tier price.

The agreement's base price and included quantity are retained on the subscription and its historical periods. An individual unit-price change changes only the extra-license price. Composite license prices appear on invoices as one subscription item with the total price and an explanation of the license count, not as total quantity multiplied by the extra-license price.

This model supports single-plan checkout, manual creation, and the subscription API. It cannot be used in bundles, offers, or imports into an existing plan carrying these terms. Alunta manages quantities, not master-user roles or individual end-user identities. It does not add a license editor to the customer portal.

A usage plan uses reported values recorded for the customer or through the public API. Usage reported for a specific subscription (Log usage opened from that subscription in the app, or `POST /subscriptions/{uuid}/usage`) is billed on that subscription and is refused with `subscription_not_started` or `subscription_ended` when the date is outside its term (usage dated inside the term can still be reported after the subscription has ended, until its final period is invoiced); usage dated inside a pause or trial is stored but not billed. Usage reported for the customer without naming a subscription (`POST /customers/{uuid}/usage-events`) is billed on the customer's newest live subscription metering that parameter, and is stored but not billed when there is none. Check the parameter, unit, and period before invoicing locks the data. A visible usage value is not itself a completed invoice line, and usage subscriptions should not be read as a fixed MRR price.

## Offers, trials, and introductory price

A trial is a zero-priced period; an introductory offer is a time-limited price for new purchases; an individual discount changes one concrete agreement; and a discount code applies to new self-service purchases. Do not treat these four concepts as interchangeable.

When manually creating a standalone subscription, the team can choose an individual discount with a name, amount or percentage, and either no end date or a duration in months or years. It starts with the first chargeable period after any trial and replaces the plan's introductory price for that subscription; without an individual discount, the plan's introductory price applies as usual. A discount covering only part of a fixed-price period is calculated proportionally. Usage subscriptions support percentage discounts only, applied to the whole usage period. The discount is retained when the team chooses **Do not invoice now**. A discount added after creation can only change unlocked periods; issued or paid periods remain unchanged. Individual discounts cannot be used in bundles or together with offers or discount codes. For card subscriptions with an individual discount, one-off charges must be invoiced separately. Review the first invoice and next scheduled period when several offer elements are used together.

## Notice period

The plan's page has a **Notice period** card. Here the team chooses either no notice period or one of four types: current billing period + N periods, current month + N months, N months' notice to the end of a billing period, or a fixed number of days or months from the cancellation day. Type, length and unit are one term and are saved together with the "Save changes" button. The same setting can be set and changed through the plan's `notice_period` API field (`null` removes the notice period), and plans and subscriptions show it as an object with `type`, `length`, `unit` and `label` (`label` is always English in the API and in webhooks, and is ignored if sent back).

The notice period is part of the agreement with the customer, so it is copied from the plan to the subscription when the subscription is created. A later change to the plan's notice period applies only to new subscriptions; existing subscriptions keep their notice period, and a plan change keeps the subscription's notice period rather than taking the plan's. A notice period can only extend a cancellation, never shorten it: the end date is never earlier than the end of the current period, and protected periods can give a later date than the notice period. It does not apply during a trial or to a subscription that has not started yet, and a pause neither uses it up nor shortens it. Examples of the four types, and of who is bound by the notice period, are in the notice period section of the subscription lifecycle guide. The team is responsible for making sure its terms are lawful towards private customers; Alunta does not check this.

## Custom fields

Custom fields have one owner: plan, subscription, or customer. Use the stable key and declared data type. A plan field does not automatically become a subscription field, and API/webhook responses include only the owners documented by the current public contract.

## Safe access to the plan catalogue

`get_plan_catalog` is disabled by default and requires an administrator to explicitly enable Plan and price details in AI Access. It can then return plan name, pricing model, configured prices, checkout visibility, and payment-provider restrictions. It does not return end-customer data, subscription counts, free-text descriptions, accounting mappings, or internal IDs.

## Collect license upgrades immediately

In the dashboard's quantity-change modal, choose **Charge saved card immediately** for an upgrade effective today with a matching saved card through one of the providers below. **Invoice immediately** only creates the adjustment invoice. The dashboard shows declined or pending payments; the quantity is still changed. Reopen the quantity-change modal and keep the same quantity to retry a collection that has not been invoiced yet. Check payment status before granting additional access.

For an individual license-based subscription billed directly to its saved card through OnPay, Stripe, QuickPay, PensoPay or CostPlus, send `charge_immediately: true` to `PUT /subscriptions/{uuid}/quantity`. Alunta charges the prorated amount including applicable VAT first, then creates a paid adjustment invoice. Use a current increase and omit `invoice_immediately`; that existing flag creates an invoice without charging the card.

Pending and declined payments create no invoice. The reported quantity is still saved, so the integration must check `meta.collection_status` before granting extra capacity: `captured` confirms payment, while `no_eligible_transactions` means no extra amount is due. Retry the same quantity and flag to retrieve or finish the existing collection without double charging; only a confirmed decline permits another attempt. Other term changes and cancellation remain blocked until an unresolved or captured adjustment is invoiced, and regular invoicing excludes it. A confirmed failure releases the claim for ordinary settlement or waiver. Automatic card charging is not required for this explicit request, but must be enabled separately for automatic renewals.
