Staaarter

Billing Abandoned Checkout Alert

A dismissible alert banner for checkout pages or account dashboards, built to bring a user back to an abandoned purchase. It pairs a countdown timer with a discount reminder and a resume button, and can be dismissed without losing the countdown state until the page reloads.

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

Docs

Installation

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

npx shadcn add https://staaarter.com/r/billing-abandoned-checkout-alert.json

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

Usage

The file also exports billing13Demo, 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 { Billing13, billing13Demo } from "@/components/blocks/billing/billing13";

export default function Page() {
  return <Billing13 {...billing13Demo} />;
}

Props

PropTypeDefaultDescription
eyebrowstring"Limited-time offer"Small label shown above the heading.
headingstringnoneMain headline, e.g. "Finish setting up your Pro plan".
messagestringnoneOptional supporting sentence under the heading.
discountLabelstringnoneText shown next to the countdown, e.g. "15% off expires in".
durationSecondsnumber900How many seconds the countdown starts from on mount.
resumeLabelstring"Resume checkout"Label on the primary action button.
resumeHrefstringnoneDestination the resume button links to.
expiredMessagestring(see source)Text shown once the countdown reaches zero, replacing the discount label and timer.
classNamestringnoneExtra classes for the outer alert container.

Behavior notes

  • The countdown starts from durationSeconds on mount and ticks down every second via a client-side interval; it renders the same starting value on the server so there's no hydration mismatch.
  • Once the countdown reaches zero, the discount label and timer are replaced by expiredMessage, and the resume button stays active.
  • Dismissing the banner sets local state to hide it entirely. There's no prop or callback to notify a parent, so track dismissal separately if you need to log it.
  • The resume button renders as a next/link via the Button component's render prop, so resumeHref can point straight at a checkout route.
  • The countdown text uses aria-live="polite" so screen readers pick up the changing time without the whole banner being re-announced.

Frequently asked questions