Agent Wranglers

PRC-16Recommended

Keep old prices as archived catalogue prices with an end date

When a plan or price changes, keep existing subscribers on the archived price with a written end date, or no end date by decision. Move them in batches by a job that checks each notice first.

How to do it

Grandfathering is a promise, so record it. Archive the old price in the versioned catalogue so no new customer can choose it. Store on each price whether it is grandfathered and until when. Map each old plan to the new one, including its entitlements, so nobody loses a feature by accident. A move that raises the price needs the notice from Tell subscribers before a price rise. Move subscribers at their renewal date, never mid-period. List every archived price with its subscriber count each quarter, and retire one only when the count reaches zero.

Examples

TypeScript example

export async function migrateGrandfathered(db, oldPriceId: string, newPriceId: string, now = new Date()) {
  const due = await db.subscriptions({ priceId: oldPriceId, renewsBefore: now })
  for (const sub of due) {
    const notice = await db.priceNotice(sub.id, newPriceId)
    if (!notice || !mayMoveToNewPrice(notice, sub.region)) continue
    await db.scheduleMove(sub.id, newPriceId, sub.currentPeriodEnd)
  }
}

Python example

def migrate_grandfathered(db, old_price_id: str, new_price_id: str, now) -> None:
    for sub in db.subscriptions(price_id=old_price_id, renews_before=now):
        notice = db.price_notice(sub.id, new_price_id)
        if notice is None or not may_move_to_new_price(notice, sub.region):
            continue
        db.schedule_move(sub.id, new_price_id, sub.current_period_end)

How to check

A test archives a price with 3 subscribers. A new checkout with that price is refused. The migration job moves only subscribers whose sent notice fits its window, at their renewal date. Each keeps every entitlement the old plan gave.

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/pricing/plan-changes-trials-and-free-tiers/grandfathered-prices">Agent Wranglers pricing, plans and entitlements playbook</a>. In code you write, add a comment next to it with the same link.