Skip to main content
Proration adjusts billing when a customer changes their subscription mid-cycle — whether upgrading to a higher plan, downgrading, or changing the quantity of a non-consumable feature like seats. Autumn calculates the prorated amount and either charges or credits the customer.
Example
A customer on a $20/month plan upgrades to a $50/month plan halfway through the billing cycle. They’re charged $15 (the prorated difference for the remaining half of the month).

Setting up

Add a proration config to a priced plan item:
autumn.config.ts
import { feature, item, plan } from 'atmn';

export const seats = feature({
  id: 'seats',
  name: 'Seats',
  type: 'metered',
  consumable: false,
});

export const pro = plan({
  id: 'pro',
  name: 'Pro',
  price: { amount: 20, interval: 'month' },
  items: [
    item({
      featureId: seats.id,
      included: 5,
      price: {
        amount: 10,
        interval: 'month',
        billingUnits: 1,
        billingMethod: 'usage_based',
      },
      proration: {
        onIncrease: 'prorate',
        onDecrease: 'prorate',
      },
    }),
  ],
});
Push changes with atmn push.

Proration options

On Increase

OptionBehavior
prorateCharge the prorated difference immediately
charge_immediatelyCharge the full unit price immediately (no proration)

On Decrease

OptionBehavior
prorateCredit the prorated difference immediately
no_actionNo credit or refund — change takes effect at next billing cycle
Proration is only relevant for non-consumable features (like seats, workspaces). Consumable features (like API requests) are billed based on usage, not quantity changes.

Plan-level proration

When a customer switches between plans (upgrade or downgrade), Autumn prorates automatically:
  • Upgrades: the customer is charged the prorated difference between the old and new plan prices for the remainder of the billing cycle. This happens immediately.
  • Downgrades: the plan change is scheduled to take effect at the end of the current billing period. The customer continues on their current plan until then.
ExampleA customer is on a $20/month plan and upgrades to a $50/month plan on day 15 of a 30-day cycle.
  • Old plan credit: 20×(15/30)=20 × (15/30) = 10 credit
  • New plan charge: 50×(15/30)=50 × (15/30) = 25 charge
  • Net charge: 2525 - 10 = $15

Controlling proration in attach

By default, plan switches prorate immediately. You can override this behavior using the proration_behavior parameter in billing.attach:
ValueBehavior
prorate_immediately(default) Charges or credits the prorated difference immediately
noneSkips proration — no charges or credits are created for the plan change
await autumn.billing.attach({
  customerId: "user_123",
  planId: "enterprise",
  prorationBehavior: "none",
});
proration_behavior: "none" cannot be used when:
  • Upgrading from a free plan to a paid plan
  • Removing an active free trial
  • Any transition that would result in a new charge
In these cases, Autumn requires immediate billing and will return an error.

Custom line items

If you need full control over what the customer is charged during a plan switch, you can pass custom_line_items to replace the auto-generated proration invoice entirely. This is only valid for immediate plan changes (e.g. upgrades).
await autumn.billing.attach({
  customerId: "user_123",
  planId: "enterprise",
  customLineItems: [
    { amount: 25, description: "Prorated upgrade credit" },
    { amount: -10, description: "Loyalty discount" },
  ],
});
When custom_line_items is provided, Autumn skips its own proration calculation and creates an invoice with exactly the line items you specified. Amounts can be negative to represent credits.

Usage-based proration

For usage-based prices, when a plan change occurs mid-cycle:
  1. Outstanding usage at the old rate is billed immediately
  2. The new rate applies going forward for the rest of the billing period

Stripe integration

Autumn uses Stripe’s proration system under the hood. Prorated amounts appear as line items on the customer’s next invoice (or are charged immediately, depending on configuration).