Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Add Card Billing Block for Ark UI

A card form for Podmoor with the number grouped as you type and four checks that tick beside it (length, check digit, expiry, CVC), the network named in text, and only the network, last four digits and expiry kept.

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

Let a customer add a payment card with checks they can see, with this add card form for React with Ark UI. It is the payment settings of Podmoor, a podcast host. A hairline frame with a plus mark on each corner holds the form beside a side cell of four checks. The number groups itself as 4-4-4-4 (4-6-5 for Amex) in an Input, the network is read from the first digits and named in text beside a two-letter tile, and the expiry and CVC are checked against a fixed date and the digits that network uses. In the side cell each check ticks with a glyph and words: the number has its full length, it passes the check digit, it is not expired, the CVC has the right digits. A Switch marks the card for renewals. The Shine Button is the only colored control: it stays quiet until all four checks pass, and pressed early it names what is wrong in the status line and moves focus to that field. Adding the card says "Visa ending 4242 added, in this demo" and wipes the number and the CVC. It's built from Field, Input, Switch, Shine Button and Guides, with a CSS entrance only. For payment settings, onboarding and any subscription app.

FAQ

Can I use these card fields in production?

No. They show the pattern: the number is formatted and checked in the tab's memory, autocomplete is off so a browser never offers a real saved card to a demo, and only the network, the last four digits and the expiry are kept. A real page never lets card digits reach its own code: use the fields your payment provider hosts, in an iframe of theirs inside this layout, and keep the token and the summary it returns. The test number 4242 4242 4242 4242 passes with any future expiry.

What do the four checks do?

They are pure functions in the file. The first asks whether the number has the length of its network (16 digits, or 15 for Amex). The second runs the Luhn sum, the check digit every card number carries, so a mistyped digit fails it. The third compares the expiry month and year with a fixed AS_OF date. The fourth asks for 3 digits, or 4 for Amex. They tick as you type; a field shows its own problem only after a press that failed.

What stays local, and how do I wire it up?

Everything. Add card appends nothing to a server: it sets "Last added" in the side cell to the network, the last four digits and the expiry, then clears the number, the expiry and the CVC. In your app create the payment method with your provider's hosted fields, send your server the token, and show the summary the provider returns.

Why is the button quiet instead of disabled?

A disabled button cannot say why. This one keeps aria-disabled and still answers a press: it reads out the first problem in the status line and puts focus on that field. Once all four checks pass it takes the primary look and adds the card.

Is it accessible?

Every field has a visible label, its hint and its problem share one reserved slot that is read with the field, and the checks are a list whose items start with a hidden "Done" or "Not yet", so state is never only a glyph. The status line is a polite live region. Card numbers, expiry and CVC are set left to right inside right-to-left pages.

How does it look on a phone?

The checks move under the fields, the Add card button is pinned at the bottom of the screen with the status line beside it, and the status line keeps room for two lines so nothing jumps when a message appears.