Staaarter

Billing Lifetime Deal

A lifetime deal (LTD) pricing block for one-time-payment promotions instead of a recurring subscription. Each tier shows a one-time price, an optional crossed-out original price, a remaining-codes count, and its own feature list and CTA. One tier can be marked highlighted to stand out as the best-value pick. Built for AppSumo-style launches, beta promotions, and early adopter offers.

By Staaarter Team
Billing
Updated May 9, 2026
Docs
Live preview

Docs

Installation

A real shadcn registry command, not a copy-paste stand-in: it fetches this block plus its badge, button dependencies and any missing npm packages, and installs them straight into your project.

npx shadcn add https://staaarter.com/r/billing-lifetime-deal.json

Prefer not to use the CLI? Copy the source from the Code toggle above into src/components/blocks/billing/billing69.tsx instead.

Usage

The file also exports billing69Demo, the exact props behind the preview above. Spread it to get a working section in one line, then replace it with your own data.

import { Billing69, billing69Demo } from "@/components/blocks/billing/billing69";

export default function Page() {
  return <Billing69 {...billing69Demo} />;
}

Props

PropTypeDefaultDescription
eyebrowstring"Lifetime deal"Small label pill above the heading.
headingstring"Pay once, own it forever"Main heading for the block.
descriptionstringnoneOptional supporting text under the heading.
tiersLifetimeTier[]noneLicense tiers rendered as cards. Renders in a 3-column grid at three tiers, 2-column otherwise.
footnotestringnoneOptional fine print shown centered below the tier grid, for terms like refund windows.
classNamestringnoneExtra classes for the outer wrapper.

Types

interface LifetimeTier {
  id: string;
  name: string;
  price: string;
  originalPrice?: string;
  codesRemaining?: number;
  features: string[];
  badge?: string;
  highlighted?: boolean;
  ctaHref: string;
  ctaLabel?: string;
}

Behavior notes

  • This is a static display block, there's no client-side state, every tier renders as-is from the tiers array.
  • codesRemaining is a plain number you supply. It doesn't decrement on its own or sync with a real inventory count, update it from your backend whenever you re-render the page.
  • highlighted controls both the card's border/ring styling and the badge/button variant, useful for marking the tier you want to nudge people toward.
  • Each tier's CTA is a next/link, so it navigates directly rather than opening a modal or triggering a purchase handler.
  • price and originalPrice are plain strings, so currency formatting and the crossed-out comparison price are entirely up to the caller.

Frequently asked questions