Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Subscription Checkout Block for Svelte

A meditation app's checkout with a Monthly or Yearly switch and a ledger of the first three charges, tax shown as its own column and every date worked out from a fixed today, beside an email and a card checked as you type.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

Show what a subscription will cost before the first charge, with this subscription checkout for Svelte with Ark UI. A header from Vesper Lane, a meditation app, sits over a hairline frame with a plus mark on each corner. On the start side a Segment Group switches the billing cycle between Monthly and Yearly, and a native table lists the first three charges: Today, then each renewal, with the date, the tax at 20% as its own column and the total, ending in a row that adds the three up. Switch the cycle and every row is worked out again in whole cents from a fixed today, so Monthly renews on the 14th of each month and Yearly a year apart. On the other side an email Input in a Field and a card as one joined control built from Input Group take the payment: number, expiry and CVC with a brand tile, the Luhn sum and an expiry check. Pay $14.40 today is the only Shine Button. A press with problems names each one under its field and moves focus to the first; a clean press waits a moment, then replaces the fields with "Visa ending 4242" and says nothing was charged. For app subscriptions, memberships and any plan where the renewal dates should be clear up front.

FAQ

How is the ledger worked out?

Each plan has a price before tax in cents (1,200 for Monthly, 12,000 for Yearly). Tax is 20% of that, rounded half up to the cent, shown in its own column; the total of a row is the price plus the tax. Dates come from a fixed "today" (14 October 2026) with the day clamped to the month's length, so a start on the 31st renews on the last day of shorter months. Monthly shows the next two months; Yearly shows the next two years. Change PLANS, TAX_PERCENT or the fixed date at the top of the file and every row follows.

What happens when I switch between Monthly and Yearly?

The ledger, the note under the switch, the sum of the three charges and the label of the Pay button change together, and the polite status line says what Today now costs ("Yearly: $144.00 today with tax"). The table keeps three rows either way, so nothing below it moves. The switch is a segment group: arrow keys move between the two and the selected one is named for assistive technology.

Can I use this to take real card payments?

No, and the code says so. It checks a card in the tab's memory (brand by the first digits, the Luhn sum, the expiry against a fixed month) so you can see the pattern. A real page never lets card digits reach its own code: it uses the fields your payment provider hosts, an iframe of theirs, with this layout, labels and error wording around them and the real autocomplete tokens (cc-number, cc-exp, cc-csc, cc-name) that those fields set themselves. Autocomplete is off in the demo so a browser never offers a real saved card to it. Test card 4242 4242 4242 4242 passes with any future expiry (checked against October 2026); a number that fails the Luhn sum, a past expiry or a CVC of the wrong length says so under the field.

What does a successful press keep?

The brand, the last four digits, the plan name and the email you typed. The number, expiry and CVC are cleared from state the moment the demo answers, and the fields are replaced in place by the result with a Start again button, so the panel never changes height. Focus moves to the result and the status line says the plan started in this demo, that nothing was charged and when it would renew.

How does it look on a phone?

The cells stack in reading order: the cycle switch, the ledger, then the account fields. The table keeps its three columns (charge, tax, total) and puts the price and the word Today or Renews under each date. The Pay button and the status line sit in a foot that stays pinned to the bottom of the screen while you scroll.

What stays local, and how do I connect it for real?

Everything: the wait is a 700 ms timer and nothing is created. To connect it, load the plans and tax rate from your billing system, have Pay create the subscription on your server with your provider's payment token (never the digits), and show the provider's error in the same slot the card problems use. Compute the ledger on the server too, so what the page promises is what the invoices say.